mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-22 05:06:45 +01:00
WIP 1.20.6 support
This commit is contained in:
parent
5628df988f
commit
78558107b3
@ -1,6 +1,13 @@
|
||||
Version 2.2.007
|
||||
Compatibility with the 1.20.5 MC Update
|
||||
Alchemy now has more warning/errors that will print out to help debug
|
||||
Fixed bug where Green Thumb did not replant if seed was in the off hand
|
||||
|
||||
NOTES:
|
||||
I did my best to keep mcMMO compatible with older versions of Minecraft for this update.
|
||||
This update to MC was quite large, with breaking changes to a lot of code relating to Alchemy, and some other things.
|
||||
I expect there to be bugs, please report them on GitHub or Discord, but preferably GitHub.
|
||||
I will be working on fixing these bugs as they come in, so please be patient.
|
||||
Version 2.2.006
|
||||
Added new config custom_item_support.yml
|
||||
Added support for hex color codes in the locale file, uses the format &#RRGGBB (see notes)
|
||||
|
33
pom.xml
33
pom.xml
@ -254,8 +254,11 @@
|
||||
<id>devmart-other</id>
|
||||
<url>https://nexuslite.gcnt.net/repos/other/</url>
|
||||
</repository>
|
||||
<!-- ... -->
|
||||
<!-- ... -->
|
||||
<!-- MockBukkit -->
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
|
||||
@ -361,7 +364,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<version>1.20.5-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -435,5 +438,29 @@
|
||||
<version>0.3.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.logging.log4j</groupId>-->
|
||||
<!-- <artifactId>log4j-core</artifactId>-->
|
||||
<!-- <version>2.22.1</version> <!– Make sure this version matches the other log4j dependencies –>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.logging.log4j</groupId>-->
|
||||
<!-- <artifactId>log4j-api</artifactId>-->
|
||||
<!-- <version>2.22.1</version>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.logging.log4j</groupId>-->
|
||||
<!-- <artifactId>log4j-slf4j-impl</artifactId>-->
|
||||
<!-- <version>2.22.1</version>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.github.seeseemelk</groupId>-->
|
||||
<!-- <artifactId>MockBukkit-v1.19</artifactId>-->
|
||||
<!-- <version>LATEST</version>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -0,0 +1,56 @@
|
||||
//package com.gmail.nossr50.commands.skills;
|
||||
//
|
||||
//import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
//import com.gmail.nossr50.util.player.UserManager;
|
||||
//import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
//import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
//import com.gmail.nossr50.util.text.TextComponentFactory;
|
||||
//import net.kyori.adventure.text.Component;
|
||||
//import org.bukkit.ChatColor;
|
||||
//import org.bukkit.entity.Player;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//
|
||||
//import static com.gmail.nossr50.datatypes.skills.SubSkillType.MACES_MACES_LIMIT_BREAK;
|
||||
//
|
||||
//public class MacesCommand extends SkillCommand {
|
||||
//
|
||||
// public MacesCommand() {
|
||||
// super(PrimarySkillType.MACES);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void dataCalculations(Player player, float skillValue) {}
|
||||
//
|
||||
// @Override
|
||||
// protected void permissionsCheck(Player player) {}
|
||||
//
|
||||
// @Override
|
||||
// protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
|
||||
// List<String> messages = new ArrayList<>();
|
||||
// McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
|
||||
// if (mmoPlayer == null) {
|
||||
// return messages;
|
||||
// }
|
||||
//
|
||||
// if(SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) {
|
||||
// messages.add(getStatMessage(MACES_MACES_LIMIT_BREAK,
|
||||
// String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, MACES_MACES_LIMIT_BREAK, 1000))));
|
||||
// }
|
||||
//
|
||||
// messages.add(ChatColor.GRAY + "The Maces skill is a work in progress and is still being developed," +
|
||||
// " feedback would be appreciated in the mcMMO discord server.");
|
||||
// return messages;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected List<Component> getTextComponents(Player player) {
|
||||
// List<Component> textComponents = new ArrayList<>();
|
||||
//
|
||||
// TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.MACES);
|
||||
//
|
||||
// return textComponents;
|
||||
// }
|
||||
//}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -253,68 +253,26 @@ public class FlatFileDataProcessor {
|
||||
}
|
||||
|
||||
public static @NotNull ExpectedType getExpectedValueType(int dataIndex) throws IndexOutOfBoundsException {
|
||||
switch(dataIndex) {
|
||||
case USERNAME_INDEX:
|
||||
return ExpectedType.STRING;
|
||||
case 2: //Assumption: Used to be for something, no longer used
|
||||
case 3: //Assumption: Used to be for something, no longer used
|
||||
case 23: //Assumption: Used to be used for something, no longer used
|
||||
case 33: //Assumption: Used to be used for something, no longer used
|
||||
case HEALTHBAR:
|
||||
case LEGACY_LAST_LOGIN:
|
||||
return ExpectedType.IGNORED;
|
||||
case SKILLS_MINING:
|
||||
case SKILLS_REPAIR:
|
||||
case SKILLS_UNARMED:
|
||||
case SKILLS_HERBALISM:
|
||||
case SKILLS_EXCAVATION:
|
||||
case SKILLS_ARCHERY:
|
||||
case SKILLS_SWORDS:
|
||||
case SKILLS_AXES:
|
||||
case SKILLS_WOODCUTTING:
|
||||
case SKILLS_ACROBATICS:
|
||||
case SKILLS_TAMING:
|
||||
case SKILLS_FISHING:
|
||||
case SKILLS_ALCHEMY:
|
||||
case SKILLS_CROSSBOWS:
|
||||
case SKILLS_TRIDENTS:
|
||||
case COOLDOWN_BERSERK:
|
||||
case COOLDOWN_GIGA_DRILL_BREAKER:
|
||||
case COOLDOWN_TREE_FELLER:
|
||||
case COOLDOWN_GREEN_TERRA:
|
||||
case COOLDOWN_SERRATED_STRIKES:
|
||||
case COOLDOWN_SKULL_SPLITTER:
|
||||
case COOLDOWN_SUPER_BREAKER:
|
||||
case COOLDOWN_BLAST_MINING:
|
||||
case SCOREBOARD_TIPS:
|
||||
case COOLDOWN_CHIMAERA_WING:
|
||||
case COOLDOWN_SUPER_SHOTGUN:
|
||||
case COOLDOWN_TRIDENTS:
|
||||
case COOLDOWN_ARCHERY:
|
||||
return ExpectedType.INTEGER;
|
||||
case EXP_MINING:
|
||||
case EXP_WOODCUTTING:
|
||||
case EXP_REPAIR:
|
||||
case EXP_UNARMED:
|
||||
case EXP_HERBALISM:
|
||||
case EXP_EXCAVATION:
|
||||
case EXP_ARCHERY:
|
||||
case EXP_SWORDS:
|
||||
case EXP_AXES:
|
||||
case EXP_ACROBATICS:
|
||||
case EXP_TAMING:
|
||||
case EXP_FISHING:
|
||||
case EXP_ALCHEMY:
|
||||
case EXP_CROSSBOWS:
|
||||
case EXP_TRIDENTS:
|
||||
return ExpectedType.FLOAT;
|
||||
case UUID_INDEX:
|
||||
return ExpectedType.UUID;
|
||||
case OVERHAUL_LAST_LOGIN:
|
||||
return ExpectedType.LONG;
|
||||
}
|
||||
|
||||
throw new IndexOutOfBoundsException();
|
||||
return switch (dataIndex) {
|
||||
case USERNAME_INDEX -> ExpectedType.STRING; //Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
case 2, 3, 23, 33, HEALTHBAR, LEGACY_LAST_LOGIN -> ExpectedType.IGNORED;
|
||||
case SKILLS_MINING, SKILLS_REPAIR, SKILLS_UNARMED, SKILLS_HERBALISM, SKILLS_EXCAVATION, SKILLS_ARCHERY,
|
||||
SKILLS_SWORDS, SKILLS_AXES, SKILLS_WOODCUTTING, SKILLS_ACROBATICS, SKILLS_TAMING, SKILLS_FISHING,
|
||||
SKILLS_ALCHEMY, SKILLS_CROSSBOWS, SKILLS_TRIDENTS, SKILLS_MACES, COOLDOWN_BERSERK,
|
||||
COOLDOWN_GIGA_DRILL_BREAKER, COOLDOWN_TREE_FELLER, COOLDOWN_GREEN_TERRA, COOLDOWN_SERRATED_STRIKES,
|
||||
COOLDOWN_SKULL_SPLITTER, COOLDOWN_SUPER_BREAKER, COOLDOWN_BLAST_MINING, SCOREBOARD_TIPS,
|
||||
COOLDOWN_CHIMAERA_WING, COOLDOWN_SUPER_SHOTGUN, COOLDOWN_TRIDENTS, COOLDOWN_ARCHERY, COOLDOWN_MACES ->
|
||||
ExpectedType.INTEGER;
|
||||
case EXP_MINING, EXP_WOODCUTTING, EXP_REPAIR, EXP_UNARMED, EXP_HERBALISM, EXP_EXCAVATION, EXP_ARCHERY,
|
||||
EXP_SWORDS, EXP_AXES, EXP_ACROBATICS, EXP_TAMING, EXP_FISHING, EXP_ALCHEMY, EXP_CROSSBOWS,
|
||||
EXP_TRIDENTS, EXP_MACES -> ExpectedType.FLOAT;
|
||||
case UUID_INDEX -> ExpectedType.UUID;
|
||||
case OVERHAUL_LAST_LOGIN -> ExpectedType.LONG;
|
||||
default -> throw new IndexOutOfBoundsException();
|
||||
};
|
||||
}
|
||||
|
||||
public @NotNull List<FlatFileDataContainer> getFlatFileDataContainers() {
|
||||
|
@ -87,8 +87,11 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
public static final int COOLDOWN_SUPER_SHOTGUN = 49;
|
||||
public static final int COOLDOWN_TRIDENTS = 50;
|
||||
public static final int COOLDOWN_ARCHERY = 51;
|
||||
public static final int EXP_MACES = 52;
|
||||
public static final int SKILLS_MACES = 53;
|
||||
public static final int COOLDOWN_MACES = 54;
|
||||
//Update this everytime new data is added
|
||||
public static final int DATA_ENTRY_COUNT = COOLDOWN_ARCHERY + 1;
|
||||
public static final int DATA_ENTRY_COUNT = COOLDOWN_MACES + 1;
|
||||
|
||||
FlatFileDatabaseManager(@NotNull File usersFile, @NotNull Logger logger, long purgeTime, int startingLevel, boolean testing) {
|
||||
this.usersFile = usersFile;
|
||||
@ -478,6 +481,18 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.CROSSBOWS))).append(":");
|
||||
appendable.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.TRIDENTS))).append(":");
|
||||
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.TRIDENTS))).append(":");
|
||||
// public static final int COOLDOWN_SUPER_SHOTGUN = 49;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.SUPER_SHOTGUN))).append(":");
|
||||
// public static final int COOLDOWN_TRIDENTS = 50;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.TRIDENTS_SUPER_ABILITY))).append(":");
|
||||
// public static final int COOLDOWN_ARCHERY = 51;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.EXPLOSIVE_SHOT))).append(":");
|
||||
// public static final int EXP_MACES = 52;
|
||||
appendable.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.MACES))).append(":");
|
||||
// public static final int SKILLS_MACES = 53;
|
||||
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.MACES))).append(":");
|
||||
// public static final int COOLDOWN_MACES = 54;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.MACES_SUPER_ABILITY))).append(":");
|
||||
appendable.append("\r\n");
|
||||
}
|
||||
|
||||
@ -987,6 +1002,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
List<PlayerStat> alchemy = new ArrayList<>();
|
||||
List<PlayerStat> crossbows = new ArrayList<>();
|
||||
List<PlayerStat> tridents = new ArrayList<>();
|
||||
List<PlayerStat> maces = new ArrayList<>();
|
||||
|
||||
BufferedReader in = null;
|
||||
String playerName = null;
|
||||
@ -1022,6 +1038,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
powerLevel += putStat(woodcutting, playerName, skills.get(PrimarySkillType.WOODCUTTING));
|
||||
powerLevel += putStat(crossbows, playerName, skills.get(PrimarySkillType.CROSSBOWS));
|
||||
powerLevel += putStat(tridents, playerName, skills.get(PrimarySkillType.TRIDENTS));
|
||||
powerLevel += putStat(maces, playerName, skills.get(PrimarySkillType.MACES));
|
||||
|
||||
putStat(powerLevels, playerName, powerLevel);
|
||||
}
|
||||
@ -1059,6 +1076,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
alchemy.sort(c);
|
||||
crossbows.sort(c);
|
||||
tridents.sort(c);
|
||||
maces.sort(c);
|
||||
powerLevels.sort(c);
|
||||
|
||||
playerStatHash.put(PrimarySkillType.MINING, mining);
|
||||
@ -1076,6 +1094,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
playerStatHash.put(PrimarySkillType.ALCHEMY, alchemy);
|
||||
playerStatHash.put(PrimarySkillType.CROSSBOWS, crossbows);
|
||||
playerStatHash.put(PrimarySkillType.TRIDENTS, tridents);
|
||||
playerStatHash.put(PrimarySkillType.MACES, maces);
|
||||
|
||||
return LeaderboardStatus.UPDATED;
|
||||
}
|
||||
@ -1239,6 +1258,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ALCHEMY, EXP_ALCHEMY, username);
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.CROSSBOWS, EXP_CROSSBOWS, username);
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.TRIDENTS, EXP_TRIDENTS, username);
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.MACES, EXP_MACES, username);
|
||||
|
||||
// Taming - Unused
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_BREAKER, COOLDOWN_SUPER_BREAKER, username);
|
||||
@ -1254,6 +1274,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BLAST_MINING, COOLDOWN_BLAST_MINING, username);
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_SHOTGUN, COOLDOWN_SUPER_SHOTGUN, username);
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.TRIDENTS_SUPER_ABILITY, COOLDOWN_TRIDENTS, username);
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.MACES_SUPER_ABILITY, COOLDOWN_MACES, username);
|
||||
|
||||
UUID uuid;
|
||||
try {
|
||||
@ -1343,6 +1364,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.ALCHEMY, SKILLS_ALCHEMY, username);
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.CROSSBOWS, SKILLS_CROSSBOWS, username);
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.TRIDENTS, SKILLS_TRIDENTS, username);
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.MACES, SKILLS_MACES, username);
|
||||
|
||||
return skills;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ "taming = 0 AND mining = 0 AND woodcutting = 0 AND repair = 0 "
|
||||
+ "AND unarmed = 0 AND herbalism = 0 AND excavation = 0 AND "
|
||||
+ "archery = 0 AND swords = 0 AND axes = 0 AND acrobatics = 0 "
|
||||
+ "AND fishing = 0 AND alchemy = 0 AND crossbows = 0 AND tridents = 0;");
|
||||
+ "AND fishing = 0 AND alchemy = 0 AND crossbows = 0 AND tridents = 0 AND maces = 0;");
|
||||
|
||||
statement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "experience`.`user_id` = `s`.`user_id`)");
|
||||
statement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "huds`.`user_id` = `s`.`user_id`)");
|
||||
@ -291,7 +291,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ " taming = ?, mining = ?, repair = ?, woodcutting = ?"
|
||||
+ ", unarmed = ?, herbalism = ?, excavation = ?"
|
||||
+ ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, total = ? WHERE user_id = ?");
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, maces = ?, total = ? WHERE user_id = ?");
|
||||
statement.setInt(1, profile.getSkillLevel(PrimarySkillType.TAMING));
|
||||
statement.setInt(2, profile.getSkillLevel(PrimarySkillType.MINING));
|
||||
statement.setInt(3, profile.getSkillLevel(PrimarySkillType.REPAIR));
|
||||
@ -307,11 +307,12 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement.setInt(13, profile.getSkillLevel(PrimarySkillType.ALCHEMY));
|
||||
statement.setInt(14, profile.getSkillLevel(PrimarySkillType.CROSSBOWS));
|
||||
statement.setInt(15, profile.getSkillLevel(PrimarySkillType.TRIDENTS));
|
||||
statement.setInt(16, profile.getSkillLevel(PrimarySkillType.MACES));
|
||||
int total = 0;
|
||||
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS)
|
||||
total += profile.getSkillLevel(primarySkillType);
|
||||
statement.setInt(16, total);
|
||||
statement.setInt(17, id);
|
||||
statement.setInt(17, total);
|
||||
statement.setInt(18, id);
|
||||
success &= (statement.executeUpdate() != 0);
|
||||
statement.close();
|
||||
if (!success) {
|
||||
@ -323,7 +324,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ " taming = ?, mining = ?, repair = ?, woodcutting = ?"
|
||||
+ ", unarmed = ?, herbalism = ?, excavation = ?"
|
||||
+ ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ? WHERE user_id = ?");
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, maces = ? WHERE user_id = ?");
|
||||
statement.setInt(1, profile.getSkillXpLevel(PrimarySkillType.TAMING));
|
||||
statement.setInt(2, profile.getSkillXpLevel(PrimarySkillType.MINING));
|
||||
statement.setInt(3, profile.getSkillXpLevel(PrimarySkillType.REPAIR));
|
||||
@ -339,7 +340,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement.setInt(13, profile.getSkillXpLevel(PrimarySkillType.ALCHEMY));
|
||||
statement.setInt(14, profile.getSkillXpLevel(PrimarySkillType.CROSSBOWS));
|
||||
statement.setInt(15, profile.getSkillXpLevel(PrimarySkillType.TRIDENTS));
|
||||
statement.setInt(16, id);
|
||||
statement.setInt(16, profile.getSkillXpLevel(PrimarySkillType.MACES));
|
||||
statement.setInt(17, id);
|
||||
success &= (statement.executeUpdate() != 0);
|
||||
statement.close();
|
||||
if (!success) {
|
||||
@ -350,7 +352,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement = connection.prepareStatement("UPDATE " + tablePrefix + "cooldowns SET "
|
||||
+ " mining = ?, woodcutting = ?, unarmed = ?"
|
||||
+ ", herbalism = ?, excavation = ?, swords = ?"
|
||||
+ ", axes = ?, blast_mining = ?, chimaera_wing = ?, crossbows = ?, tridents = ? WHERE user_id = ?");
|
||||
+ ", axes = ?, blast_mining = ?, chimaera_wing = ?, crossbows = ?"
|
||||
+ ", tridents = ?, maces = ? WHERE user_id = ?");
|
||||
statement.setLong(1, profile.getAbilityDATS(SuperAbilityType.SUPER_BREAKER));
|
||||
statement.setLong(2, profile.getAbilityDATS(SuperAbilityType.TREE_FELLER));
|
||||
statement.setLong(3, profile.getAbilityDATS(SuperAbilityType.BERSERK));
|
||||
@ -362,7 +365,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement.setLong(9, profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS));
|
||||
statement.setLong(10, profile.getAbilityDATS(SuperAbilityType.SUPER_SHOTGUN));
|
||||
statement.setLong(11, profile.getAbilityDATS(SuperAbilityType.TRIDENTS_SUPER_ABILITY));
|
||||
statement.setInt(12, id);
|
||||
statement.setLong(12, profile.getAbilityDATS(SuperAbilityType.MACES_SUPER_ABILITY));
|
||||
statement.setInt(13, id);
|
||||
success = (statement.executeUpdate() != 0);
|
||||
statement.close();
|
||||
if (!success) {
|
||||
@ -648,9 +652,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
|
||||
statement = connection.prepareStatement(
|
||||
"SELECT " +
|
||||
"s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, s.crossbows, s.tridents, " +
|
||||
"e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, e.crossbows, e.tridents, " +
|
||||
"c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, c.chimaera_wing, c.crossbows, c.tridents, " +
|
||||
"s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, s.crossbows, s.tridents, s.maces, " +
|
||||
"e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, e.crossbows, e.tridents, e.maces, " +
|
||||
"c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, c.chimaera_wing, c.crossbows, c.tridents, c.maces, " +
|
||||
"h.mobhealthbar, h.scoreboardtips, u.uuid, u.`user` "
|
||||
+ "FROM " + tablePrefix + "users u "
|
||||
+ "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
|
||||
@ -922,6 +926,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ "`chimaera_wing` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "`crossbows` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "`tridents` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "`maces` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "PRIMARY KEY (`user_id`)) "
|
||||
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
|
||||
tryClose(createStatement);
|
||||
@ -950,6 +955,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ "`alchemy` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`crossbows` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`tridents` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`maces` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`total` int(10) unsigned NOT NULL DEFAULT "+totalLevel+","
|
||||
+ "PRIMARY KEY (`user_id`)) "
|
||||
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
|
||||
@ -1017,20 +1023,24 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
tryClose(connection);
|
||||
}
|
||||
|
||||
String skills = "skills";
|
||||
String crossbows = "crossbows";
|
||||
String tridents = "tridents";
|
||||
String experience = "experience";
|
||||
String cooldowns = "cooldowns";
|
||||
final String skills = "skills";
|
||||
final String crossbows = "crossbows";
|
||||
final String tridents = "tridents";
|
||||
final String maces = "maces";
|
||||
final String experience = "experience";
|
||||
final String cooldowns = "cooldowns";
|
||||
|
||||
updateStructure(skills, crossbows, String.valueOf(32));
|
||||
updateStructure(skills, tridents, String.valueOf(32));
|
||||
updateStructure(skills, maces, String.valueOf(32));
|
||||
|
||||
updateStructure(experience, crossbows, String.valueOf(10));
|
||||
updateStructure(experience, tridents, String.valueOf(10));
|
||||
updateStructure(experience, maces, String.valueOf(10));
|
||||
|
||||
updateStructure(cooldowns, crossbows, String.valueOf(10));
|
||||
updateStructure(cooldowns, tridents, String.valueOf(10));
|
||||
updateStructure(cooldowns, maces, String.valueOf(10));
|
||||
}
|
||||
|
||||
private void updateStructure(String tableName, String columnName, String columnSize) {
|
||||
@ -1213,15 +1223,14 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
Map<PrimarySkillType, Float> skillsXp = new EnumMap<>(PrimarySkillType.class); // Skill & XP
|
||||
Map<SuperAbilityType, Integer> skillsDATS = new EnumMap<>(SuperAbilityType.class); // Ability & Cooldown
|
||||
Map<UniqueDataType, Integer> uniqueData = new EnumMap<>(UniqueDataType.class); //Chimaera wing cooldown and other misc info
|
||||
MobHealthbarType mobHealthbarType;
|
||||
UUID uuid;
|
||||
int scoreboardTipsShown;
|
||||
|
||||
final int OFFSET_SKILLS = 0; // TODO update these numbers when the query
|
||||
// changes (a new skill is added)
|
||||
final int OFFSET_XP = 15;
|
||||
final int OFFSET_DATS = 28;
|
||||
final int OFFSET_OTHER = 41;
|
||||
final int OFFSET_XP = 16;
|
||||
final int OFFSET_DATS = 29;
|
||||
final int OFFSET_OTHER = 42;
|
||||
|
||||
skills.put(PrimarySkillType.TAMING, result.getInt(OFFSET_SKILLS + 1));
|
||||
skills.put(PrimarySkillType.MINING, result.getInt(OFFSET_SKILLS + 2));
|
||||
@ -1238,6 +1247,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
skills.put(PrimarySkillType.ALCHEMY, result.getInt(OFFSET_SKILLS + 13));
|
||||
skills.put(PrimarySkillType.CROSSBOWS, result.getInt(OFFSET_SKILLS + 14));
|
||||
skills.put(PrimarySkillType.TRIDENTS, result.getInt(OFFSET_SKILLS + 15));
|
||||
skills.put(PrimarySkillType.MACES, result.getInt(OFFSET_SKILLS + 16));
|
||||
|
||||
skillsXp.put(PrimarySkillType.TAMING, result.getFloat(OFFSET_XP + 1));
|
||||
skillsXp.put(PrimarySkillType.MINING, result.getFloat(OFFSET_XP + 2));
|
||||
@ -1254,6 +1264,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
skillsXp.put(PrimarySkillType.ALCHEMY, result.getFloat(OFFSET_XP + 13));
|
||||
skillsXp.put(PrimarySkillType.CROSSBOWS, result.getFloat(OFFSET_XP + 14));
|
||||
skillsXp.put(PrimarySkillType.TRIDENTS, result.getFloat(OFFSET_XP + 15));
|
||||
skillsXp.put(PrimarySkillType.MACES, result.getFloat(OFFSET_XP + 16));
|
||||
|
||||
// Taming - Unused - result.getInt(OFFSET_DATS + 1)
|
||||
skillsDATS.put(SuperAbilityType.SUPER_BREAKER, result.getInt(OFFSET_DATS + 2));
|
||||
@ -1270,6 +1281,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
uniqueData.put(UniqueDataType.CHIMAERA_WING_DATS, result.getInt(OFFSET_DATS + 13));
|
||||
skillsDATS.put(SuperAbilityType.SUPER_SHOTGUN, result.getInt(OFFSET_DATS + 14));
|
||||
skillsDATS.put(SuperAbilityType.TRIDENTS_SUPER_ABILITY, result.getInt(OFFSET_DATS + 15));
|
||||
skillsDATS.put(SuperAbilityType.MACES_SUPER_ABILITY, result.getInt(OFFSET_DATS + 16));
|
||||
|
||||
try {
|
||||
scoreboardTipsShown = result.getInt(OFFSET_OTHER + 2);
|
||||
|
@ -56,67 +56,29 @@ public class FlatFileDataUtil {
|
||||
* @return the "zero" initialized data corresponding to the index
|
||||
*/
|
||||
public static @NotNull String getZeroInitialisedData(int index, int startingLevel) throws IndexOutOfBoundsException {
|
||||
switch(index) {
|
||||
case USERNAME_INDEX:
|
||||
return LEGACY_INVALID_OLD_USERNAME; //We'll keep using this value for legacy compatibility reasons (not sure if needed but don't care)
|
||||
case 2: //Assumption: Used to be for something, no longer used
|
||||
case 3: //Assumption: Used to be for something, no longer used
|
||||
case 23: //Assumption: Used to be used for something, no longer used
|
||||
case 33: //Assumption: Used to be used for something, no longer used
|
||||
case LEGACY_LAST_LOGIN:
|
||||
case HEALTHBAR:
|
||||
return "IGNORED";
|
||||
case SKILLS_MINING:
|
||||
case SKILLS_REPAIR:
|
||||
case SKILLS_UNARMED:
|
||||
case SKILLS_HERBALISM:
|
||||
case SKILLS_EXCAVATION:
|
||||
case SKILLS_ARCHERY:
|
||||
case SKILLS_SWORDS:
|
||||
case SKILLS_AXES:
|
||||
case SKILLS_WOODCUTTING:
|
||||
case SKILLS_ACROBATICS:
|
||||
case SKILLS_TAMING:
|
||||
case SKILLS_FISHING:
|
||||
case SKILLS_ALCHEMY:
|
||||
case SKILLS_CROSSBOWS:
|
||||
case SKILLS_TRIDENTS:
|
||||
return String.valueOf(startingLevel);
|
||||
case OVERHAUL_LAST_LOGIN:
|
||||
return String.valueOf(-1L);
|
||||
case COOLDOWN_BERSERK:
|
||||
case COOLDOWN_GIGA_DRILL_BREAKER:
|
||||
case COOLDOWN_TREE_FELLER:
|
||||
case COOLDOWN_GREEN_TERRA:
|
||||
case COOLDOWN_SERRATED_STRIKES:
|
||||
case COOLDOWN_SKULL_SPLITTER:
|
||||
case COOLDOWN_SUPER_BREAKER:
|
||||
case COOLDOWN_BLAST_MINING:
|
||||
case COOLDOWN_SUPER_SHOTGUN:
|
||||
case COOLDOWN_TRIDENTS:
|
||||
case COOLDOWN_ARCHERY:
|
||||
case SCOREBOARD_TIPS:
|
||||
case COOLDOWN_CHIMAERA_WING:
|
||||
case EXP_MINING:
|
||||
case EXP_WOODCUTTING:
|
||||
case EXP_REPAIR:
|
||||
case EXP_UNARMED:
|
||||
case EXP_HERBALISM:
|
||||
case EXP_EXCAVATION:
|
||||
case EXP_ARCHERY:
|
||||
case EXP_SWORDS:
|
||||
case EXP_AXES:
|
||||
case EXP_ACROBATICS:
|
||||
case EXP_TAMING:
|
||||
case EXP_FISHING:
|
||||
case EXP_ALCHEMY:
|
||||
case EXP_CROSSBOWS:
|
||||
case EXP_TRIDENTS:
|
||||
return "0";
|
||||
case UUID_INDEX:
|
||||
//TODO: Add UUID recovery? Might not even be worth it.
|
||||
return switch (index) {
|
||||
case USERNAME_INDEX ->
|
||||
LEGACY_INVALID_OLD_USERNAME; //We'll keep using this value for legacy compatibility reasons (not sure if needed but don't care)
|
||||
//Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
case 2, 3, 23, 33, LEGACY_LAST_LOGIN, HEALTHBAR -> "IGNORED";
|
||||
case SKILLS_MINING, SKILLS_REPAIR, SKILLS_UNARMED, SKILLS_HERBALISM, SKILLS_EXCAVATION, SKILLS_ARCHERY,
|
||||
SKILLS_SWORDS, SKILLS_AXES, SKILLS_WOODCUTTING, SKILLS_ACROBATICS, SKILLS_TAMING, SKILLS_FISHING,
|
||||
SKILLS_ALCHEMY, SKILLS_CROSSBOWS, SKILLS_TRIDENTS, SKILLS_MACES -> String.valueOf(startingLevel);
|
||||
case OVERHAUL_LAST_LOGIN -> String.valueOf(-1L);
|
||||
case COOLDOWN_BERSERK, COOLDOWN_GIGA_DRILL_BREAKER, COOLDOWN_TREE_FELLER, COOLDOWN_GREEN_TERRA,
|
||||
COOLDOWN_SERRATED_STRIKES, COOLDOWN_SKULL_SPLITTER, COOLDOWN_SUPER_BREAKER, COOLDOWN_BLAST_MINING,
|
||||
COOLDOWN_SUPER_SHOTGUN, COOLDOWN_TRIDENTS, COOLDOWN_ARCHERY, COOLDOWN_MACES, SCOREBOARD_TIPS, COOLDOWN_CHIMAERA_WING,
|
||||
EXP_MINING, EXP_WOODCUTTING, EXP_REPAIR, EXP_UNARMED, EXP_HERBALISM, EXP_EXCAVATION, EXP_ARCHERY,
|
||||
EXP_SWORDS, EXP_AXES, EXP_ACROBATICS, EXP_TAMING, EXP_FISHING, EXP_ALCHEMY, EXP_CROSSBOWS,
|
||||
EXP_TRIDENTS, EXP_MACES -> "0";
|
||||
case UUID_INDEX ->
|
||||
throw new IndexOutOfBoundsException(); //TODO: Add UUID recovery? Might not even be worth it.
|
||||
}
|
||||
default -> throw new IndexOutOfBoundsException();
|
||||
};
|
||||
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import com.gmail.nossr50.skills.crossbows.CrossbowsManager;
|
||||
import com.gmail.nossr50.skills.excavation.ExcavationManager;
|
||||
import com.gmail.nossr50.skills.fishing.FishingManager;
|
||||
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
|
||||
import com.gmail.nossr50.skills.maces.MacesManager;
|
||||
import com.gmail.nossr50.skills.mining.MiningManager;
|
||||
import com.gmail.nossr50.skills.repair.RepairManager;
|
||||
import com.gmail.nossr50.skills.salvage.SalvageManager;
|
||||
@ -220,6 +221,9 @@ public class McMMOPlayer implements Identified {
|
||||
case WOODCUTTING:
|
||||
skillManagers.put(primarySkillType, new WoodcuttingManager(this));
|
||||
break;
|
||||
case MACES:
|
||||
skillManagers.put(primarySkillType, new MacesManager(this));
|
||||
break;
|
||||
default:
|
||||
throw new InvalidSkillException("The skill named has no manager! Contact the devs!");
|
||||
}
|
||||
@ -313,6 +317,10 @@ public class McMMOPlayer implements Identified {
|
||||
return (TridentsManager) skillManagers.get(PrimarySkillType.TRIDENTS);
|
||||
}
|
||||
|
||||
public MacesManager getMacesManager() {
|
||||
return (MacesManager) skillManagers.get(PrimarySkillType.MACES);
|
||||
}
|
||||
|
||||
public ExcavationManager getExcavationManager() {
|
||||
return (ExcavationManager) skillManagers.get(PrimarySkillType.EXCAVATION);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ public enum PrimarySkillType {
|
||||
EXCAVATION,
|
||||
FISHING,
|
||||
HERBALISM,
|
||||
MACES,
|
||||
MINING,
|
||||
REPAIR,
|
||||
SALVAGE,
|
||||
|
@ -57,6 +57,9 @@ public enum SubSkillType {
|
||||
HERBALISM_HYLIAN_LUCK,
|
||||
HERBALISM_SHROOM_THUMB,
|
||||
|
||||
/* Maces */
|
||||
MACES_MACES_LIMIT_BREAK(10),
|
||||
|
||||
/* Mining */
|
||||
MINING_BIGGER_BOMBS(1),
|
||||
MINING_BLAST_MINING(8),
|
||||
|
@ -72,19 +72,26 @@ public enum SuperAbilityType {
|
||||
"Swords.Skills.SS.Other.Off",
|
||||
"Swords.SubSkill.SerratedStrikes.Name"),
|
||||
SUPER_SHOTGUN(
|
||||
null,
|
||||
null,
|
||||
"Crossbows.Skills.SSG.Other.On",
|
||||
"Crossbows.Skills.SSG.Refresh",
|
||||
null,
|
||||
"Crossbows.SubSkill.SuperShotgun.Name"),
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder"),
|
||||
TRIDENTS_SUPER_ABILITY(
|
||||
"Tridents.Skills.TA.On",
|
||||
"Tridents.Skills.TA.Off",
|
||||
"Tridents.Skills.TA.Other.On",
|
||||
"Tridents.Skills.TA.Refresh",
|
||||
"Tridents.Skills.TA.Other.Off",
|
||||
"Tridents.SubSkill.TridentAbility.Name"),
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder"),
|
||||
MACES_SUPER_ABILITY(
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder"),
|
||||
|
||||
/**
|
||||
* Has cooldown - but has to share a skill with Super Breaker, so needs special treatment
|
||||
@ -209,6 +216,7 @@ public enum SuperAbilityType {
|
||||
case SUPER_SHOTGUN -> Permissions.superShotgun(player);
|
||||
case TREE_FELLER -> Permissions.treeFeller(player);
|
||||
case TRIDENTS_SUPER_ABILITY -> Permissions.tridentsSuper(player);
|
||||
case MACES_SUPER_ABILITY -> Permissions.macesSuper(player);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,8 @@ public enum ToolType {
|
||||
SWORD("Swords.Ability.Lower", "Swords.Ability.Ready"),
|
||||
CROSSBOW("Crossbows.Ability.Lower", "Crossbows.Ability.Ready"),
|
||||
BOW("Archery.Ability.Lower", "Archery.Ability.Ready"),
|
||||
TRIDENTS("Tridents.Ability.Lower", "Tridents.Ability.Ready");
|
||||
TRIDENTS("Tridents.Ability.Lower", "Tridents.Ability.Ready"),
|
||||
MACES("Maces.Ability.Lower", "Maces.Ability.Ready");
|
||||
|
||||
private final String lowerTool;
|
||||
private final String raiseTool;
|
||||
@ -45,6 +46,8 @@ public enum ToolType {
|
||||
return ItemUtils.isCrossbow(itemStack);
|
||||
case TRIDENTS:
|
||||
return ItemUtils.isTrident(itemStack);
|
||||
case MACES:
|
||||
return ItemUtils.isMace(itemStack);
|
||||
|
||||
case FISTS:
|
||||
return itemStack.getType() == Material.AIR;
|
||||
|
@ -1,167 +1,120 @@
|
||||
package com.gmail.nossr50.datatypes.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
|
||||
import org.bukkit.Color;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionUtil.samePotionType;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class AlchemyPotion {
|
||||
private final Material material;
|
||||
private PotionData data;
|
||||
private String name;
|
||||
private List<String> lore;
|
||||
private List<PotionEffect> effects;
|
||||
private Color color;
|
||||
private Map<ItemStack, String> children;
|
||||
private final ItemStack potion;
|
||||
private final Map<ItemStack, String> alchemyPotionChildren;
|
||||
|
||||
public AlchemyPotion(Material material, PotionData data, String name, List<String> lore, List<PotionEffect> effects, Color color, Map<ItemStack, String> children) {
|
||||
this.material = material;
|
||||
this.data = data;
|
||||
this.lore = lore;
|
||||
this.name = name;
|
||||
this.effects = effects;
|
||||
this.children = children;
|
||||
this.color = color;
|
||||
public AlchemyPotion(ItemStack potion, Map<ItemStack, String> alchemyPotionChildren) {
|
||||
this.potion = requireNonNull(potion, "potion cannot be null");
|
||||
this.alchemyPotionChildren = requireNonNull(alchemyPotionChildren, "alchemyPotionChildren cannot be null");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AlchemyPotion{" + data + ", " + name + ", Effects[" + effects.size() + "], Children[" + children.size() + "]}";
|
||||
}
|
||||
|
||||
public ItemStack toItemStack(int amount) {
|
||||
ItemStack potion = new ItemStack(material, amount);
|
||||
PotionMeta meta = (PotionMeta) potion.getItemMeta();
|
||||
|
||||
meta.setBasePotionData(data);
|
||||
if (this.getName() != null) {
|
||||
meta.setDisplayName(this.getName());
|
||||
}
|
||||
|
||||
if (this.getLore() != null && !this.getLore().isEmpty()) {
|
||||
meta.setLore(this.getLore());
|
||||
}
|
||||
|
||||
if (!this.getEffects().isEmpty()) {
|
||||
for (PotionEffect effect : this.getEffects()) {
|
||||
meta.addCustomEffect(effect, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getColor() != null) {
|
||||
meta.setColor(this.getColor());
|
||||
}
|
||||
|
||||
potion.setItemMeta(meta);
|
||||
public @NotNull ItemStack toItemStack(int amount) {
|
||||
final ItemStack potion = new ItemStack(this.potion);
|
||||
potion.setAmount(Math.max(1, amount));
|
||||
return potion;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
public Map<ItemStack, String> getAlchemyPotionChildren() {
|
||||
return alchemyPotionChildren;
|
||||
}
|
||||
|
||||
public Potion toPotion(int amount) {
|
||||
return Potion.fromItemStack(this.toItemStack(amount));
|
||||
}
|
||||
|
||||
public PotionData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(PotionData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<String> getLore() {
|
||||
return lore;
|
||||
}
|
||||
|
||||
public void setLore(List<String> lore) {
|
||||
this.lore = lore;
|
||||
}
|
||||
|
||||
public List<PotionEffect> getEffects() {
|
||||
return effects;
|
||||
}
|
||||
|
||||
public void setEffects(List<PotionEffect> effects) {
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Map<ItemStack, String> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(Map<ItemStack, String> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public AlchemyPotion getChild(ItemStack ingredient) {
|
||||
if (!children.isEmpty()) {
|
||||
for (Entry<ItemStack, String> child : children.entrySet()) {
|
||||
public @Nullable AlchemyPotion getChild(@NotNull ItemStack ingredient) {
|
||||
if (!alchemyPotionChildren.isEmpty()) {
|
||||
for (Entry<ItemStack, String> child : alchemyPotionChildren.entrySet()) {
|
||||
if (ingredient.isSimilar(child.getKey())) {
|
||||
return PotionConfig.getInstance().getPotion(child.getValue());
|
||||
return mcMMO.p.getPotionConfig().getPotion(child.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSimilar(ItemStack item) {
|
||||
if (item.getType() != material) {
|
||||
public boolean isSimilarPotion(@NotNull ItemStack otherPotion) {
|
||||
requireNonNull(otherPotion, "otherPotion cannot be null");
|
||||
// TODO: Investigate?
|
||||
// We currently don't compare base potion effects, likely because they are derived from the potion type
|
||||
if (otherPotion.getType() != potion.getType() || !otherPotion.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
if (!item.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
PotionMeta meta = (PotionMeta) item.getItemMeta();
|
||||
PotionData that = meta.getBasePotionData();
|
||||
if (data.getType() != that.getType()) {
|
||||
return false;
|
||||
}
|
||||
if (data.isExtended() != that.isExtended()) {
|
||||
return false;
|
||||
}
|
||||
if (data.isUpgraded() != that.isUpgraded()) {
|
||||
return false;
|
||||
}
|
||||
for (PotionEffect effect : effects) {
|
||||
if (!meta.hasCustomEffect(effect.getType())) {
|
||||
|
||||
final PotionMeta otherPotionMeta = (PotionMeta) otherPotion.getItemMeta();
|
||||
|
||||
// all custom effects must be present
|
||||
for (var effect : getAlchemyPotionMeta().getCustomEffects()) {
|
||||
if (!otherPotionMeta.hasCustomEffect(effect.getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!meta.hasLore() && !lore.isEmpty()) {
|
||||
|
||||
if (!samePotionType(getAlchemyPotionMeta(), otherPotionMeta)) {
|
||||
return false;
|
||||
}
|
||||
if (!(lore.isEmpty() && !meta.hasLore()) && !meta.getLore().equals(lore)) {
|
||||
|
||||
if (!otherPotionMeta.hasLore() && getAlchemyPotionMeta().hasLore()
|
||||
|| !getAlchemyPotionMeta().hasLore() && otherPotionMeta.hasLore()) {
|
||||
return false;
|
||||
}
|
||||
if (!meta.hasDisplayName() && name != null) {
|
||||
|
||||
if (otherPotionMeta.hasLore() && getAlchemyPotionMeta().hasLore()
|
||||
&& !otherPotionMeta.getLore().equals(getAlchemyPotionMeta().getLore())) {
|
||||
return false;
|
||||
}
|
||||
return (name == null && !meta.hasDisplayName()) || meta.getDisplayName().equals(name);
|
||||
|
||||
if (!otherPotionMeta.hasDisplayName() && getAlchemyPotionMeta().hasDisplayName()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var alchemyPotionName = getAlchemyPotionMeta().hasDisplayName() ? getAlchemyPotionMeta().getDisplayName() : null;
|
||||
|
||||
return (alchemyPotionName == null && !otherPotionMeta.hasDisplayName()) || otherPotionMeta.getDisplayName().equals(alchemyPotionName);
|
||||
}
|
||||
|
||||
public PotionMeta getAlchemyPotionMeta() {
|
||||
return (PotionMeta) potion.getItemMeta();
|
||||
}
|
||||
|
||||
public boolean isSplash() {
|
||||
return potion.getType() == Material.SPLASH_POTION;
|
||||
}
|
||||
|
||||
public boolean isLingering() {
|
||||
return potion.getType() == Material.LINGERING_POTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AlchemyPotion that = (AlchemyPotion) o;
|
||||
return Objects.equals(potion, that.potion) && Objects.equals(alchemyPotionChildren, that.alchemyPotionChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(potion, alchemyPotionChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlchemyPotion{" +
|
||||
"potion=" + potion +
|
||||
", alchemyPotionChildren=" + alchemyPotionChildren +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package com.gmail.nossr50.datatypes.skills.alchemy;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import com.gmail.nossr50.util.PotionUtil;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.util.List;
|
||||
import static com.gmail.nossr50.util.PotionUtil.*;
|
||||
|
||||
public enum PotionStage {
|
||||
FIVE(5),
|
||||
@ -43,27 +42,27 @@ public enum PotionStage {
|
||||
return potionStage;
|
||||
}
|
||||
|
||||
private static boolean isWaterBottle(AlchemyPotion input) {
|
||||
return input.getData().getType() == PotionType.WATER;
|
||||
private static boolean isWaterBottle(AlchemyPotion alchemyPotion) {
|
||||
return isPotionTypeWater(alchemyPotion.getAlchemyPotionMeta());
|
||||
}
|
||||
|
||||
public static PotionStage getPotionStage(AlchemyPotion alchemyPotion) {
|
||||
PotionData data = alchemyPotion.getData();
|
||||
List<PotionEffect> effects = alchemyPotion.getEffects();
|
||||
final PotionMeta potionMeta = alchemyPotion.getAlchemyPotionMeta();
|
||||
|
||||
int stage = 1;
|
||||
|
||||
// Check if potion has an effect of any sort
|
||||
if (data.getType().getEffectType() != null || !effects.isEmpty()) {
|
||||
if (!potionMeta.getCustomEffects().isEmpty()
|
||||
|| PotionUtil.hasBasePotionEffects(potionMeta)) {
|
||||
stage++;
|
||||
}
|
||||
|
||||
// Check if potion has a glowstone dust amplifier
|
||||
// Else check if the potion has a custom effect with an amplifier added by mcMMO
|
||||
if (data.isUpgraded()) {
|
||||
if (isStrong(potionMeta)) {
|
||||
stage++;
|
||||
} else if(!effects.isEmpty()) {
|
||||
for (PotionEffect effect : effects){
|
||||
} else if (!potionMeta.getCustomEffects().isEmpty()) {
|
||||
for (PotionEffect effect : potionMeta.getCustomEffects()){
|
||||
if(effect.getAmplifier() > 0){
|
||||
stage++;
|
||||
break;
|
||||
@ -72,12 +71,12 @@ public enum PotionStage {
|
||||
}
|
||||
|
||||
// Check if potion has a redstone dust amplifier
|
||||
if (data.isExtended()) {
|
||||
if (isLong(potionMeta)) {
|
||||
stage++;
|
||||
}
|
||||
|
||||
// Check if potion has a gunpowder amplifier
|
||||
if (alchemyPotion.getMaterial() == Material.SPLASH_POTION || alchemyPotion.getMaterial() == Material.LINGERING_POTION) {
|
||||
if (alchemyPotion.isSplash() || alchemyPotion.isLingering()) {
|
||||
stage++;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ import net.kyori.adventure.text.TextComponent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -317,7 +316,7 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
ItemStack boots = player.getInventory().getBoots();
|
||||
float xp = (float) (damage * (isRoll ? ExperienceConfig.getInstance().getRollXPModifier() : ExperienceConfig.getInstance().getFallXPModifier()));
|
||||
|
||||
if (boots != null && boots.containsEnchantment(Enchantment.PROTECTION_FALL)) {
|
||||
if (boots != null && boots.containsEnchantment(mcMMO.p.getEnchantmentMapper().getFeatherFalling())) {
|
||||
xp *= ExperienceConfig.getInstance().getFeatherFallXPModifier();
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ public class EntityListener implements Listener {
|
||||
if (bow == null)
|
||||
return;
|
||||
|
||||
if (bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
|
||||
if (bow.containsEnchantment(mcMMO.p.getEnchantmentMapper().getInfinity())) {
|
||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_INF_ARROW, MetadataConstants.MCMMO_METADATA_VALUE);
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class mcMMO extends JavaPlugin {
|
||||
|
||||
|
||||
/* Managers & Services */
|
||||
private static PlatformManager platformManager;
|
||||
private static MetadataService metadataService;
|
||||
@ -140,21 +138,14 @@ public class mcMMO extends JavaPlugin {
|
||||
private GeneralConfig generalConfig;
|
||||
private AdvancedConfig advancedConfig;
|
||||
private PartyConfig partyConfig;
|
||||
private PotionConfig potionConfig;
|
||||
private CustomItemSupportConfig customItemSupportConfig;
|
||||
private EnchantmentMapper enchantmentMapper;
|
||||
private AttributeMapper attributeMapper;
|
||||
|
||||
private FoliaLib foliaLib;
|
||||
private PartyManager partyManager;
|
||||
|
||||
// private RepairConfig repairConfig;
|
||||
// private SalvageConfig salvageConfig;
|
||||
// private PersistentDataConfig persistentDataConfig;
|
||||
// private ChatConfig chatConfig;
|
||||
// private CoreSkillsConfig coreSkillsConfig;
|
||||
// private RankConfig rankConfig;
|
||||
// private TreasureConfig treasureConfig;
|
||||
// private FishingTreasureConfig fishingTreasureConfig;
|
||||
// private SoundConfig soundConfig;
|
||||
|
||||
public mcMMO() {
|
||||
p = this;
|
||||
}
|
||||
@ -209,6 +200,9 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
// Init Material Maps
|
||||
materialMapStore = new MaterialMapStore();
|
||||
// Init compatibility mappers
|
||||
enchantmentMapper = new EnchantmentMapper(this);
|
||||
attributeMapper = new AttributeMapper(this);
|
||||
|
||||
loadConfigFiles();
|
||||
|
||||
@ -567,7 +561,11 @@ public class mcMMO extends JavaPlugin {
|
||||
FishingTreasureConfig.getInstance();
|
||||
HiddenConfig.getInstance();
|
||||
mcMMO.p.getAdvancedConfig();
|
||||
PotionConfig.getInstance();
|
||||
|
||||
// init potion config
|
||||
potionConfig = new PotionConfig();
|
||||
potionConfig.loadPotions();
|
||||
|
||||
CoreSkillsConfig.getInstance();
|
||||
SoundConfig.getInstance();
|
||||
RankConfig.getInstance();
|
||||
@ -812,6 +810,18 @@ public class mcMMO extends JavaPlugin {
|
||||
return customItemSupportConfig;
|
||||
}
|
||||
|
||||
public PotionConfig getPotionConfig() {
|
||||
return potionConfig;
|
||||
}
|
||||
|
||||
public EnchantmentMapper getEnchantmentMapper() {
|
||||
return enchantmentMapper;
|
||||
}
|
||||
|
||||
public AttributeMapper getAttributeMapper() {
|
||||
return attributeMapper;
|
||||
}
|
||||
|
||||
public @NotNull FoliaLib getFoliaLib() {
|
||||
return foliaLib;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.gmail.nossr50.metadata;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
@ -74,12 +73,12 @@ public class ItemMetadataService {
|
||||
|
||||
if(itemMeta != null) {
|
||||
//TODO: can be optimized
|
||||
if (itemMeta.hasEnchant(Enchantment.DIG_SPEED)) {
|
||||
itemMeta.removeEnchant(Enchantment.DIG_SPEED);
|
||||
if (itemMeta.hasEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency())) {
|
||||
itemMeta.removeEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency());
|
||||
}
|
||||
|
||||
if (originalSpeed > 0) {
|
||||
itemMeta.addEnchant(Enchantment.DIG_SPEED, originalSpeed, true);
|
||||
itemMeta.addEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency(), originalSpeed, true);
|
||||
}
|
||||
|
||||
PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer();
|
||||
|
@ -1,13 +1,13 @@
|
||||
package com.gmail.nossr50.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.text.StringUtils;
|
||||
@ -27,7 +27,7 @@ public class AlchemyManager extends SkillManager {
|
||||
}
|
||||
|
||||
public List<ItemStack> getIngredients() {
|
||||
return PotionConfig.getInstance().getIngredients(getTier());
|
||||
return mcMMO.p.getPotionConfig().getIngredients(getTier());
|
||||
}
|
||||
|
||||
public String getIngredientList() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.gmail.nossr50.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
|
||||
@ -36,7 +35,7 @@ public final class AlchemyPotionBrewer {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getChildPotion(PotionConfig.getInstance().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
|
||||
if (getChildPotion(mcMMO.p.getPotionConfig().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -94,12 +93,11 @@ public final class AlchemyPotionBrewer {
|
||||
}
|
||||
|
||||
private static List<ItemStack> getValidIngredients(Player player) {
|
||||
if(player == null || UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return PotionConfig.getInstance().getIngredients(1);
|
||||
if(player == null || UserManager.getPlayer(player) == null) {
|
||||
return mcMMO.p.getPotionConfig().getIngredients(1);
|
||||
}
|
||||
|
||||
return PotionConfig.getInstance().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
|
||||
return mcMMO.p.getPotionConfig().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
|
||||
}
|
||||
|
||||
public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
|
||||
@ -120,11 +118,11 @@ public final class AlchemyPotionBrewer {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ItemStack item = inventory.getItem(i);
|
||||
|
||||
if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !PotionConfig.getInstance().isValidPotion(item)) {
|
||||
if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !mcMMO.p.getPotionConfig().isValidPotion(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AlchemyPotion input = PotionConfig.getInstance().getPotion(item);
|
||||
AlchemyPotion input = mcMMO.p.getPotionConfig().getPotion(item);
|
||||
AlchemyPotion output = input.getChild(ingredient);
|
||||
|
||||
inputList.set(i, input);
|
||||
|
@ -18,7 +18,8 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionEffectMapper.getNausea;
|
||||
|
||||
public class ArcheryManager extends SkillManager {
|
||||
public ArcheryManager(McMMOPlayer mcMMOPlayer) {
|
||||
@ -95,10 +96,8 @@ public class ArcheryManager extends SkillManager {
|
||||
Location dazedLocation = defender.getLocation();
|
||||
dazedLocation.setPitch(90 - Misc.getRandom().nextInt(181));
|
||||
|
||||
// defender.teleport(dazedLocation);
|
||||
mcMMO.p.getFoliaLib().getImpl().teleportAsync(defender, dazedLocation);
|
||||
defender.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 20 * 10, 10));
|
||||
|
||||
defender.addPotionEffect(new PotionEffect(getNausea(), 20 * 10, 10));
|
||||
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Combat.TouchedFuzzy");
|
||||
|
@ -573,11 +573,13 @@ public class FishingManager extends SkillManager {
|
||||
int luck;
|
||||
|
||||
if (getPlayer().getInventory().getItemInMainHand().getType() == Material.FISHING_ROD) {
|
||||
luck = getPlayer().getInventory().getItemInMainHand().getEnchantmentLevel(Enchantment.LUCK);
|
||||
luck = getPlayer().getInventory().getItemInMainHand().getEnchantmentLevel(
|
||||
mcMMO.p.getEnchantmentMapper().getLuckOfTheSea());
|
||||
}
|
||||
else {
|
||||
// We know something was caught, so if the rod wasn't in the main hand it must be in the offhand
|
||||
luck = getPlayer().getInventory().getItemInOffHand().getEnchantmentLevel(Enchantment.LUCK);
|
||||
luck = getPlayer().getInventory().getItemInOffHand().getEnchantmentLevel(
|
||||
mcMMO.p.getEnchantmentMapper().getLuckOfTheSea());
|
||||
}
|
||||
|
||||
// Rather than subtracting luck (and causing a minimum 3% chance for every drop), scale by luck.
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.gmail.nossr50.skills.maces;
|
||||
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.ToolType;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
|
||||
public class MacesManager extends SkillManager {
|
||||
public MacesManager(McMMOPlayer mmoPlayer) {
|
||||
super(mmoPlayer, PrimarySkillType.MACES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can activate the Super Ability for Maces
|
||||
* @return true if the player can activate the Super Ability, false otherwise
|
||||
*/
|
||||
public boolean canActivateAbility() {
|
||||
return mmoPlayer.getToolPreparationMode(ToolType.MACES) && Permissions.macesSuper(getPlayer());
|
||||
}
|
||||
}
|
@ -233,7 +233,7 @@ public class TamingManager extends SkillManager {
|
||||
|
||||
// Bred mules & donkeys can actually have horse-like stats, but llamas cannot.
|
||||
if (beast instanceof AbstractHorse horseLikeCreature && !(beast instanceof Llama)) {
|
||||
AttributeInstance jumpAttribute = horseLikeCreature.getAttribute(Attribute.HORSE_JUMP_STRENGTH);
|
||||
AttributeInstance jumpAttribute = horseLikeCreature.getAttribute(mcMMO.p.getAttributeMapper().getHorseJumpStrength());
|
||||
|
||||
if(jumpAttribute != null) {
|
||||
double jumpStrength = jumpAttribute.getValue();
|
||||
|
45
src/main/java/com/gmail/nossr50/util/AttributeMapper.java
Normal file
45
src/main/java/com/gmail/nossr50/util/AttributeMapper.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
|
||||
public class AttributeMapper {
|
||||
private final mcMMO pluginRef;
|
||||
private static final String GENERIC_JUMP_STRENGTH = "generic.jump_strength";
|
||||
private static final String HORSE_JUMP_STRENGTH = "horse.jump_strength";
|
||||
private final Attribute horseJumpStrength;
|
||||
|
||||
public AttributeMapper(mcMMO pluginRef) {
|
||||
this.pluginRef = pluginRef;
|
||||
this.horseJumpStrength = initHorseJumpStrength();
|
||||
}
|
||||
|
||||
private Attribute initHorseJumpStrength() {
|
||||
// TODO: Use modern matching?
|
||||
// if (Registry.ATTRIBUTE.match(GENERIC_JUMP_STRENGTH) != null) {
|
||||
// return Registry.ATTRIBUTE.match(GENERIC_JUMP_STRENGTH);
|
||||
// }
|
||||
//
|
||||
// if (Registry.ATTRIBUTE.match(HORSE_JUMP_STRENGTH) != null) {
|
||||
// return Registry.ATTRIBUTE.match(HORSE_JUMP_STRENGTH);
|
||||
// }
|
||||
|
||||
for (Attribute attr : Registry.ATTRIBUTE) {
|
||||
if (attr.getKey().getKey().equalsIgnoreCase(HORSE_JUMP_STRENGTH)
|
||||
|| attr.getKey().getKey().equalsIgnoreCase(GENERIC_JUMP_STRENGTH)
|
||||
|| attr.name().equalsIgnoreCase(HORSE_JUMP_STRENGTH)
|
||||
|| attr.name().equalsIgnoreCase(GENERIC_JUMP_STRENGTH)) {
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Generic Jump Strength or Horse Jump Strength attribute, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Generic Jump Strength or Horse Jump Strength attribute");
|
||||
}
|
||||
|
||||
public Attribute getHorseJumpStrength() {
|
||||
return horseJumpStrength;
|
||||
}
|
||||
}
|
149
src/main/java/com/gmail/nossr50/util/EnchantmentMapper.java
Normal file
149
src/main/java/com/gmail/nossr50/util/EnchantmentMapper.java
Normal file
@ -0,0 +1,149 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
||||
public class EnchantmentMapper {
|
||||
private final mcMMO pluginRef;
|
||||
private final Enchantment efficiency;
|
||||
private final Enchantment unbreaking;
|
||||
private final Enchantment infinity;
|
||||
private final Enchantment featherFalling;
|
||||
private final Enchantment luckOfTheSea;
|
||||
|
||||
public EnchantmentMapper(mcMMO pluginRef) {
|
||||
this.pluginRef = pluginRef;
|
||||
this.efficiency = initEfficiency();
|
||||
this.unbreaking = initUnbreaking();
|
||||
this.infinity = initInfinity();
|
||||
this.featherFalling = initFeatherFalling();
|
||||
this.luckOfTheSea = initLuckOfTheSea();
|
||||
}
|
||||
|
||||
private Enchantment initLuckOfTheSea() {
|
||||
// TODO: Make use of match if present
|
||||
// if (Registry.ENCHANTMENT.match("luck_of_the_sea") != null) {
|
||||
// return Registry.ENCHANTMENT.match("luck_of_the_sea");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("LUCK_OF_THE_SEA")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("LUCK")
|
||||
|| enchantment.getName().equalsIgnoreCase("LUCK_OF_THE_SEA")
|
||||
|| enchantment.getName().equalsIgnoreCase("LUCK")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Luck of the Sea enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Luck of the Sea enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initFeatherFalling() {
|
||||
// if (Registry.ENCHANTMENT.match("feather_falling") != null) {
|
||||
// return Registry.ENCHANTMENT.match("feather_falling");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("FEATHER_FALLING")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("PROTECTION_FALL")
|
||||
|| enchantment.getName().equalsIgnoreCase("FEATHER_FALLING")
|
||||
|| enchantment.getName().equalsIgnoreCase("PROTECTION_FALL")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Feather Falling enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Feather Falling enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initInfinity() {
|
||||
// if(Registry.ENCHANTMENT.match("infinity") != null) {
|
||||
// return Registry.ENCHANTMENT.match("infinity");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("INFINITY")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("ARROW_INFINITE")
|
||||
|| enchantment.getName().equalsIgnoreCase("INFINITY")
|
||||
|| enchantment.getName().equalsIgnoreCase("ARROW_INFINITE")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Infinity enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Infinity enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initEfficiency() {
|
||||
// if (Registry.ENCHANTMENT.match("efficiency") != null) {
|
||||
// return Registry.ENCHANTMENT.match("efficiency");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("EFFICIENCY")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("DIG_SPEED")
|
||||
|| enchantment.getName().equalsIgnoreCase("EFFICIENCY")
|
||||
|| enchantment.getName().equalsIgnoreCase("DIG_SPEED")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Efficiency enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Efficiency enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initUnbreaking() {
|
||||
// if (Registry.ENCHANTMENT.match("unbreaking") != null) {
|
||||
// return Registry.ENCHANTMENT.match("unbreaking");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("UNBREAKING")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("DURABILITY")
|
||||
|| enchantment.getName().equalsIgnoreCase("UNBREAKING")
|
||||
|| enchantment.getName().equalsIgnoreCase("DURABILITY")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Unbreaking enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Unbreaking enchantment");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the efficiency enchantment
|
||||
*
|
||||
* @return The efficiency enchantment
|
||||
*/
|
||||
public Enchantment getEfficiency() {
|
||||
return efficiency;
|
||||
}
|
||||
|
||||
public Enchantment getUnbreaking() {
|
||||
return unbreaking;
|
||||
}
|
||||
|
||||
public Enchantment getInfinity() {
|
||||
return infinity;
|
||||
}
|
||||
|
||||
public Enchantment getFeatherFalling() {
|
||||
return featherFalling;
|
||||
}
|
||||
|
||||
public Enchantment getLuckOfTheSea() {
|
||||
return luckOfTheSea;
|
||||
}
|
||||
}
|
@ -1,39 +1,34 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class EnchantmentUtils {
|
||||
|
||||
private static final HashMap<String, Enchantment> enchants = new HashMap<>();
|
||||
private static final HashMap<String, Enchantment> legacyEnchantments = new HashMap<>();
|
||||
|
||||
static {
|
||||
enchants.put("SHARPNESS", Enchantment.DAMAGE_ALL);
|
||||
enchants.put("POWER", Enchantment.ARROW_DAMAGE);
|
||||
enchants.put("FIRE_PROTECTION", Enchantment.PROTECTION_FIRE);
|
||||
enchants.put("FEATHER_FALLING", Enchantment.PROTECTION_FALL);
|
||||
enchants.put("PROTECTION", Enchantment.PROTECTION_ENVIRONMENTAL);
|
||||
enchants.put("BLAST_PROTECTION", Enchantment.PROTECTION_EXPLOSIONS);
|
||||
enchants.put("PROJECTILE_PROTECTION", Enchantment.PROTECTION_PROJECTILE);
|
||||
enchants.put("RESPIRATION", Enchantment.OXYGEN);
|
||||
enchants.put("INFINITY", Enchantment.ARROW_INFINITE);
|
||||
enchants.put("AQUA_AFFINITY", Enchantment.WATER_WORKER);
|
||||
enchants.put("UNBREAKING", Enchantment.DURABILITY);
|
||||
enchants.put("SMITE", Enchantment.DAMAGE_UNDEAD);
|
||||
enchants.put("BANE_OF_ARTHROPODS", Enchantment.DAMAGE_ARTHROPODS);
|
||||
enchants.put("EFFICIENCY", Enchantment.DIG_SPEED);
|
||||
enchants.put("FIRE_ASPECT", Enchantment.FIRE_ASPECT);
|
||||
enchants.put("SILK_TOUCH", Enchantment.SILK_TOUCH);
|
||||
enchants.put("FORTUNE", Enchantment.LOOT_BONUS_BLOCKS);
|
||||
enchants.put("LOOTING", Enchantment.LOOT_BONUS_MOBS);
|
||||
enchants.put("PUNCH", Enchantment.ARROW_KNOCKBACK);
|
||||
enchants.put("FLAME", Enchantment.ARROW_FIRE);
|
||||
enchants.put("KNOCKBACK", Enchantment.KNOCKBACK);
|
||||
enchants.put("THORNS", Enchantment.THORNS);
|
||||
enchants.put("MENDING", Enchantment.MENDING);
|
||||
enchants.put("DEPTH_STRIDER", Enchantment.DEPTH_STRIDER);
|
||||
enchants.put("FROST_WALKER", Enchantment.FROST_WALKER);
|
||||
// backwards compatibility for looking up legacy bukkit enums
|
||||
addLegacyEnchantmentLookup("SHARPNESS", "DAMAGE_ALL");
|
||||
addLegacyEnchantmentLookup("POWER", "ARROW_DAMAGE");
|
||||
addLegacyEnchantmentLookup("FIRE_PROTECTION", "PROTECTION_FIRE");
|
||||
addLegacyEnchantmentLookup("FEATHER_FALLING", "PROTECTION_FALL");
|
||||
addLegacyEnchantmentLookup("PROTECTION", "PROTECTION_ENVIRONMENTAL");
|
||||
addLegacyEnchantmentLookup("BLAST_PROTECTION", "PROTECTION_EXPLOSIONS");
|
||||
addLegacyEnchantmentLookup("PROJECTILE_PROTECTION", "PROTECTION_PROJECTILE");
|
||||
addLegacyEnchantmentLookup("RESPIRATION", "OXYGEN");
|
||||
addLegacyEnchantmentLookup("INFINITY", "ARROW_INFINITE");
|
||||
addLegacyEnchantmentLookup("AQUA_AFFINITY", "WATER_WORKER");
|
||||
addLegacyEnchantmentLookup("UNBREAKING", "DURABILITY");
|
||||
addLegacyEnchantmentLookup("SMITE", "DAMAGE_UNDEAD");
|
||||
addLegacyEnchantmentLookup("BANE_OF_ARTHROPODS", "DAMAGE_ARTHROPODS");
|
||||
addLegacyEnchantmentLookup("EFFICIENCY", "DIG_SPEED");
|
||||
addLegacyEnchantmentLookup("FORTUNE", "LOOT_BONUS_BLOCKS");
|
||||
addLegacyEnchantmentLookup("LOOTING", "LOOT_BONUS_MOBS");
|
||||
addLegacyEnchantmentLookup("PUNCH", "ARROW_KNOCKBACK");
|
||||
addLegacyEnchantmentLookup("FLAME", "ARROW_FIRE");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,11 +38,19 @@ public class EnchantmentUtils {
|
||||
*
|
||||
* @return Enchantment or null if no enchantment was found
|
||||
*/
|
||||
public static Enchantment getByName(String enchantmentName) {
|
||||
if (enchants.containsKey(enchantmentName)) {
|
||||
return enchants.get(enchantmentName);
|
||||
@SuppressWarnings("deprecation")
|
||||
public static @Nullable Enchantment getByName(String enchantmentName) {
|
||||
if (legacyEnchantments.containsKey(enchantmentName)) {
|
||||
return legacyEnchantments.get(enchantmentName);
|
||||
}
|
||||
|
||||
return Enchantment.getByName(enchantmentName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void addLegacyEnchantmentLookup(String enchantmentName, String legacyBukkitName) {
|
||||
if (Enchantment.getByName(legacyBukkitName) != null) {
|
||||
legacyEnchantments.put(enchantmentName, Enchantment.getByName(legacyBukkitName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class ItemUtils {
|
||||
/**
|
||||
* This is a static utility class, therefore we don't want any instances of
|
||||
@ -41,6 +43,37 @@ public final class ItemUtils {
|
||||
return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exhaustive lookup for a Material by name.
|
||||
* <p>
|
||||
* This method will first try a normal lookup, then a legacy lookup, then a lookup by ENUM name,
|
||||
* and finally a lookup by ENUM name with legacy name.
|
||||
* @param materialName The name of the material to lookup
|
||||
* @return The Material if found, or null if not found
|
||||
*/
|
||||
public static @Nullable Material exhaustiveMaterialLookup(@NotNull String materialName) {
|
||||
requireNonNull(materialName, "materialName cannot be null");
|
||||
|
||||
// First try a normal lookup
|
||||
Material material = Material.matchMaterial(materialName);
|
||||
|
||||
// If that fails, try a legacy lookup
|
||||
if (material == null) {
|
||||
material = Material.matchMaterial(materialName, true);
|
||||
}
|
||||
|
||||
// try to match to Material ENUM
|
||||
if (material == null) {
|
||||
material = Material.getMaterial(materialName.toUpperCase());
|
||||
}
|
||||
|
||||
// try to match to Material ENUM with legacy name
|
||||
if (material == null) {
|
||||
material = Material.getMaterial(materialName.toUpperCase(), true);
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has an item in their inventory or offhand.
|
||||
*
|
||||
@ -100,6 +133,10 @@ public final class ItemUtils {
|
||||
return mcMMO.getMaterialMapStore().isTrident(item.getType().getKey().getKey());
|
||||
}
|
||||
|
||||
public static boolean isMace(@NotNull ItemStack item) {
|
||||
return mcMMO.getMaterialMapStore().isMace(item.getType().getKey().getKey());
|
||||
}
|
||||
|
||||
public static boolean hasItemInEitherHand(@NotNull Player player, Material material) {
|
||||
return player.getInventory().getItemInMainHand().getType() == material || player.getInventory().getItemInOffHand().getType() == material;
|
||||
}
|
||||
@ -681,7 +718,8 @@ public final class ItemUtils {
|
||||
if(itemMeta == null)
|
||||
return;
|
||||
|
||||
itemMeta.addEnchant(Enchantment.DIG_SPEED, existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
|
||||
itemMeta.addEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency(),
|
||||
existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class MaterialMapStore {
|
||||
private final @NotNull HashSet<String> crossbows;
|
||||
private final @NotNull HashSet<String> tools;
|
||||
private final @NotNull HashSet<String> enchantables;
|
||||
private final @NotNull HashSet<String> maces;
|
||||
|
||||
private final @NotNull HashSet<String> ores;
|
||||
private final @NotNull HashSet<String> intendedToolPickAxe;
|
||||
@ -97,6 +98,7 @@ public class MaterialMapStore {
|
||||
shovels = new HashSet<>();
|
||||
hoes = new HashSet<>();
|
||||
tridents = new HashSet<>();
|
||||
maces = new HashSet<>();
|
||||
|
||||
enchantables = new HashSet<>();
|
||||
|
||||
@ -453,6 +455,7 @@ public class MaterialMapStore {
|
||||
enchantables.addAll(tridents);
|
||||
enchantables.addAll(bows);
|
||||
enchantables.addAll(crossbows);
|
||||
enchantables.addAll(maces);
|
||||
|
||||
enchantables.add("shears");
|
||||
enchantables.add("fishing_rod");
|
||||
@ -476,6 +479,7 @@ public class MaterialMapStore {
|
||||
fillHoes();
|
||||
fillShovels();
|
||||
fillTridents();
|
||||
fillMaces();
|
||||
fillStringTools();
|
||||
fillBows();
|
||||
fillCrossbows();
|
||||
@ -491,6 +495,7 @@ public class MaterialMapStore {
|
||||
tools.addAll(stringTools);
|
||||
tools.addAll(bows);
|
||||
tools.addAll(crossbows);
|
||||
tools.addAll(maces);
|
||||
}
|
||||
|
||||
private void fillBows() {
|
||||
@ -507,6 +512,10 @@ public class MaterialMapStore {
|
||||
stringTools.add("carrot_on_a_stick");
|
||||
}
|
||||
|
||||
private void fillMaces() {
|
||||
maces.add("mace");
|
||||
}
|
||||
|
||||
private void fillTridents() {
|
||||
tridents.add("trident");
|
||||
}
|
||||
@ -824,6 +833,14 @@ public class MaterialMapStore {
|
||||
return tridents.contains(id);
|
||||
}
|
||||
|
||||
public boolean isMace(@NotNull Material material) {
|
||||
return isMace(material.getKey().getKey());
|
||||
}
|
||||
|
||||
public boolean isMace(@NotNull String id) {
|
||||
return maces.contains(id);
|
||||
}
|
||||
|
||||
public boolean isLeatherArmor(@NotNull Material material) {
|
||||
return isLeatherArmor(material.getKey().getKey());
|
||||
}
|
||||
|
@ -246,6 +246,14 @@ public final class Permissions {
|
||||
}
|
||||
public static boolean tridentsLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }
|
||||
|
||||
/* MACES */
|
||||
public static boolean macesSuper(Permissible permissible) {
|
||||
// TODO: When a super is added, change this
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean macesLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.maces.limitbreak"); }
|
||||
|
||||
/*
|
||||
* PARTY
|
||||
*/
|
||||
|
@ -0,0 +1,6 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
public enum PotionCompatibilityType {
|
||||
PRE_1_20_5,
|
||||
POST_1_20_5
|
||||
}
|
142
src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java
Normal file
142
src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java
Normal file
@ -0,0 +1,142 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
final public class PotionEffectMapper {
|
||||
private static final PotionEffectType haste;
|
||||
private static final PotionEffectType nausea;
|
||||
private static final Method potionEffectTypeWrapperGetPotionEffectType;
|
||||
private static final Class<?> classPotionEffectTypeWrapper;
|
||||
|
||||
private PotionEffectMapper() {
|
||||
// Utility class
|
||||
}
|
||||
|
||||
static {
|
||||
potionEffectTypeWrapperGetPotionEffectType = getPotionEffectTypeWrapperGetPotionEffectType();
|
||||
classPotionEffectTypeWrapper = getClassPotionEffectTypeWrapper();
|
||||
|
||||
haste = initHaste();
|
||||
nausea = initNausea();
|
||||
}
|
||||
|
||||
private static Method getPotionEffectTypeWrapperGetPotionEffectType() {
|
||||
try {
|
||||
return classPotionEffectTypeWrapper.getMethod("getType");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> getClassPotionEffectTypeWrapper() {
|
||||
try {
|
||||
return Class.forName("org.bukkit.potion.PotionEffectTypeWrapper");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType initNausea() {
|
||||
if (classPotionEffectTypeWrapper != null) {
|
||||
return getNauseaLegacy();
|
||||
} else {
|
||||
return getNauseaModern();
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType getNauseaModern() {
|
||||
// PotionEffectType potionEffectType = Registry.EFFECT.match("nausea");
|
||||
// if (potionEffectType != null) {
|
||||
// return potionEffectType;
|
||||
// }
|
||||
//
|
||||
// // Look for the potion effect type by name
|
||||
// for (PotionEffectType pet : Registry.EFFECT) {
|
||||
// if (pet.getKey().getKey().equalsIgnoreCase("CONFUSION")
|
||||
// || pet.getKey().getKey().equalsIgnoreCase("NAUSEA")
|
||||
// || pet.getName().equalsIgnoreCase("CONFUSION")
|
||||
// || pet.getName().equalsIgnoreCase("NAUSEA")) {
|
||||
// return pet;
|
||||
// }
|
||||
// }
|
||||
|
||||
try {
|
||||
return (PotionEffectType) PotionEffectType.class.getField("NAUSEA").get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Nausea potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType getNauseaLegacy() {
|
||||
try {
|
||||
Object potionEffectTypeWrapper = PotionEffectType.class.getField("CONFUSION").get(null);
|
||||
PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType
|
||||
.invoke(potionEffectTypeWrapper);
|
||||
return potionEffectType;
|
||||
} catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Nausea potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType initHaste() {
|
||||
|
||||
|
||||
mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Haste potion effect type");
|
||||
}
|
||||
|
||||
private static PotionEffectType getHasteLegacy() {
|
||||
try {
|
||||
Object potionEffectTypeWrapper = PotionEffectType.class.getField("FAST_DIGGING").get(null);
|
||||
PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType
|
||||
.invoke(potionEffectTypeWrapper);
|
||||
return potionEffectType;
|
||||
} catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Haste potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType getHasteModern() {
|
||||
// PotionEffectType potionEffectType = Registry.EFFECT.match("haste");
|
||||
// if (potionEffectType != null) {
|
||||
// return potionEffectType;
|
||||
// }
|
||||
//
|
||||
// // Look for the potion effect type by name
|
||||
// for (PotionEffectType pet : Registry.EFFECT) {
|
||||
// if (pet.getKey().getKey().equalsIgnoreCase("HASTE")
|
||||
// || pet.getKey().getKey().equalsIgnoreCase("FAST_DIGGING")
|
||||
// || pet.getName().equalsIgnoreCase("HASTE")
|
||||
// || pet.getName().equalsIgnoreCase("FAST_DIGGING")) {
|
||||
// return pet;
|
||||
// }
|
||||
// }
|
||||
|
||||
try {
|
||||
return (PotionEffectType) PotionEffectType.class.getField("HASTE").get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Haste potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
public static PotionEffectType getHaste() {
|
||||
return haste;
|
||||
}
|
||||
|
||||
public static PotionEffectType getNausea() {
|
||||
return nausea;
|
||||
}
|
||||
}
|
447
src/main/java/com/gmail/nossr50/util/PotionUtil.java
Normal file
447
src/main/java/com/gmail/nossr50/util/PotionUtil.java
Normal file
@ -0,0 +1,447 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PotionUtil {
|
||||
// Some of the old potion types got renamed, our configs can still contain these old names
|
||||
private static final Map<String, String> legacyPotionTypes = new HashMap<>();
|
||||
private static final Method methodPotionTypeGetKey;
|
||||
private static final Method methodPotionTypeGetEffectType;
|
||||
private static final Method methodPotionTypeGetPotionEffects;
|
||||
private static final Method methodPotionDataIsUpgraded;
|
||||
private static final Method methodPotionDataIsExtended;
|
||||
private static final Method methodPotionDataGetType;
|
||||
private static final Method methodPotionMetaGetBasePotionData;
|
||||
private static final Method methodPotionMetaGetBasePotionType;
|
||||
private static final Method methodPotionMetaSetBasePotionType;
|
||||
private static final Method methodSetBasePotionData;
|
||||
private static final Class<?> potionDataClass;
|
||||
|
||||
public static final String STRONG = "STRONG";
|
||||
public static final String LONG = "LONG";
|
||||
public static final String LEGACY_WATER_POTION_TYPE = "WATER";
|
||||
|
||||
private static final PotionCompatibilityType COMPATIBILITY_MODE;
|
||||
|
||||
static {
|
||||
// We used to use uncraftable as the potion type
|
||||
// this type isn't available anymore, so water will do
|
||||
legacyPotionTypes.put("UNCRAFTABLE", "WATER");
|
||||
legacyPotionTypes.put("JUMP", "LEAPING");
|
||||
legacyPotionTypes.put("SPEED", "SWIFTNESS");
|
||||
legacyPotionTypes.put("INSTANT_HEAL", "HEALING");
|
||||
legacyPotionTypes.put("INSTANT_DAMAGE", "HARMING");
|
||||
legacyPotionTypes.put("REGEN", "REGENERATION");
|
||||
methodPotionTypeGetKey = getKeyMethod();
|
||||
methodPotionDataIsUpgraded = getPotionDataIsUpgraded();
|
||||
methodPotionDataIsExtended = getIsExtended();
|
||||
methodPotionMetaGetBasePotionData = getBasePotionData();
|
||||
methodPotionMetaGetBasePotionType = getBasePotionType();
|
||||
methodPotionMetaSetBasePotionType = getMethodPotionMetaSetBasePotionType();
|
||||
methodPotionDataGetType = getPotionDataGetType();
|
||||
methodPotionTypeGetEffectType = getPotionTypeEffectType();
|
||||
methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects();
|
||||
methodSetBasePotionData = getSetBasePotionData();
|
||||
potionDataClass = getPotionDataClass();
|
||||
|
||||
if (methodPotionMetaGetBasePotionData != null) {
|
||||
COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
|
||||
} else {
|
||||
COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a potion from a partial name, and whether it should be upgraded or extended.
|
||||
* @param partialName potion type as a string, can be a substring of the potion type but must match exactly
|
||||
* @return The potion type
|
||||
*/
|
||||
public static PotionType matchPotionType(String partialName, boolean isUpgraded, boolean isExtended) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return matchLegacyPotionType(partialName);
|
||||
} else {
|
||||
String updatedName = convertLegacyNames(partialName);
|
||||
return Arrays.stream(PotionType.values())
|
||||
.filter(potionType -> getKeyGetKey(potionType).toUpperCase().contains(partialName)
|
||||
|| getKeyGetKey(potionType).toUpperCase().contains(convertLegacyNames(updatedName)))
|
||||
.filter(potionType -> !isUpgraded || potionType.name().toUpperCase().contains(STRONG))
|
||||
.filter(potionType -> !isExtended || potionType.name().toUpperCase().contains(LONG))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getKeyGetKey(PotionType potionType) {
|
||||
try {
|
||||
if (getKeyMethod() != null) {
|
||||
NamespacedKey key = (NamespacedKey) methodPotionTypeGetKey.invoke(potionType);
|
||||
return key.getKey();
|
||||
} else {
|
||||
return potionType.name();
|
||||
}
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
mcMMO.p.getLogger().warning("Failed to get potion key for " + potionType.name());
|
||||
return potionType.name();
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> getPotionDataClass() {
|
||||
try {
|
||||
return Class.forName("org.bukkit.potion.PotionData");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Older versions of Spigot do not have getKey() in PotionType
|
||||
* We need to check for the existence of this method before calling it
|
||||
* @return The getKey method
|
||||
*/
|
||||
private static @Nullable Method getKeyMethod() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getKey");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getMethodPotionMetaSetBasePotionType() {
|
||||
try {
|
||||
return PotionMeta.class.getMethod("setBasePotionType", PotionType.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getSetBasePotionData() {
|
||||
try {
|
||||
return PotionMeta.class.getMethod("setBasePotionData", potionDataClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Method getPotionDataIsUpgraded() {
|
||||
try {
|
||||
// TODO: <?> Needed?
|
||||
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
|
||||
return clazz.getMethod("isUpgraded");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Method getIsExtended() {
|
||||
try {
|
||||
// TODO: <?> Needed?
|
||||
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
|
||||
return clazz.getMethod("isExtended");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Newer versions of Spigot do not have getBasePotionData() in PotionMeta
|
||||
*
|
||||
* @return the getBasePotionData method, or null if it does not exist
|
||||
*/
|
||||
private static @Nullable Method getBasePotionData() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getBasePotionData");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getBasePotionType() {
|
||||
try {
|
||||
return PotionMeta.class.getMethod("getBasePotionType");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getPotionDataGetType() {
|
||||
try {
|
||||
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
|
||||
return clazz.getMethod("getType");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getPotionTypeEffectType() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getEffectType");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getPotionTypeGetPotionEffects() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getPotionEffects");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy matching for {@link PotionType}
|
||||
*
|
||||
* @param partialName The partial name of the potion
|
||||
* @return The potion type
|
||||
*/
|
||||
private static PotionType matchLegacyPotionType(String partialName) {
|
||||
String updatedName = convertLegacyNames(partialName);
|
||||
|
||||
return Arrays.stream(PotionType.values())
|
||||
.filter(potionType -> getKeyGetKey(potionType).equalsIgnoreCase(partialName)
|
||||
|| getKeyGetKey(potionType).equalsIgnoreCase(convertLegacyNames(updatedName))
|
||||
|| potionType.name().equalsIgnoreCase(partialName)
|
||||
|| potionType.name().equalsIgnoreCase(convertLegacyNames(updatedName)))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
public static String convertPotionConfigName(String legacyName) {
|
||||
String replacementName = legacyName;
|
||||
|
||||
// Remove generated potions.yml config naming convention
|
||||
if (replacementName.contains("POTION_OF_")) {
|
||||
replacementName = replacementName.replace("POTION_OF_", "");
|
||||
}
|
||||
|
||||
if (replacementName.contains("_II")) {
|
||||
replacementName = replacementName.replace("_II", "");
|
||||
replacementName = "STRONG_" + replacementName;
|
||||
} else if (replacementName.contains("_EXTENDED")) {
|
||||
replacementName = replacementName.replace("_EXTENDED", "");
|
||||
replacementName = "LONG_" + replacementName;
|
||||
}
|
||||
return replacementName;
|
||||
}
|
||||
|
||||
public static String convertLegacyNames(String legacyPotionType) {
|
||||
String modernized = legacyPotionType;
|
||||
// check for legacy names
|
||||
for (var key : legacyPotionTypes.keySet()) {
|
||||
if (modernized.contains(key)) {
|
||||
// Replace the legacy name with the new name
|
||||
modernized = modernized.replace(key, legacyPotionTypes.get(key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return modernized;
|
||||
}
|
||||
|
||||
public static boolean hasLegacyName(String potionType) {
|
||||
for (var key : legacyPotionTypes.keySet()) {
|
||||
if (potionType.contains(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isStrong(PotionMeta potionMeta) {
|
||||
if (methodPotionMetaGetBasePotionData == null) {
|
||||
return isStrongModern(potionMeta);
|
||||
} else {
|
||||
return isStrongLegacy(potionMeta);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isLong(PotionMeta potionMeta) {
|
||||
if (methodPotionMetaGetBasePotionData == null) {
|
||||
return isLongModern(potionMeta);
|
||||
} else {
|
||||
return isLongLegacy(potionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLongLegacy(PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
return (boolean) methodPotionDataIsExtended.invoke(potionData);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLongModern(PotionMeta potionMeta) {
|
||||
try {
|
||||
return getModernPotionTypeKey(potionMeta).getKey().startsWith(LONG);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isStrongLegacy(PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
return (boolean) methodPotionDataIsUpgraded.invoke(potionData);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isStrongModern(PotionMeta potionMeta) {
|
||||
try {
|
||||
return getModernPotionTypeKey(potionMeta).getKey().startsWith(STRONG);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static NamespacedKey getModernPotionTypeKey(PotionMeta potionMeta) throws IllegalAccessException, InvocationTargetException {
|
||||
PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
|
||||
return (NamespacedKey) methodPotionTypeGetKey.invoke(potionType);
|
||||
}
|
||||
|
||||
public static boolean isPotionTypeWater(@NotNull PotionMeta potionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return isPotionTypeWaterLegacy(potionMeta);
|
||||
} else {
|
||||
return isPotionTypeWaterModern(potionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPotionTypeWaterLegacy(@NotNull PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
|
||||
return potionType.name().equalsIgnoreCase(LEGACY_WATER_POTION_TYPE)
|
||||
|| PotionType.valueOf(LEGACY_WATER_POTION_TYPE) == potionType;
|
||||
} catch (InvocationTargetException | IllegalAccessException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPotionTypeWaterModern(@NotNull PotionMeta potionMeta) {
|
||||
try {
|
||||
return getModernPotionTypeKey(potionMeta).getKey().equalsIgnoreCase(LEGACY_WATER_POTION_TYPE);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean samePotionType(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return samePotionTypeLegacy(potionMeta, otherPotionMeta);
|
||||
} else {
|
||||
return samePotionTypeModern(potionMeta, otherPotionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean samePotionTypeLegacy(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
Object otherPotionData = methodPotionMetaGetBasePotionData.invoke(otherPotionMeta);
|
||||
PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
|
||||
PotionType otherPotionType = (PotionType) methodPotionDataGetType.invoke(otherPotionData);
|
||||
return potionType == otherPotionType;
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean samePotionTypeModern(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
try {
|
||||
PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
|
||||
PotionType otherPotionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(otherPotionMeta);
|
||||
return potionType == otherPotionType;
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean samePotionEffects(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return true;
|
||||
} else {
|
||||
return samePotionEffectsModern(potionMeta, otherPotionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean samePotionEffectsModern(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
return potionMeta.getCustomEffects().equals(otherPotionMeta.getCustomEffects());
|
||||
}
|
||||
|
||||
public static boolean hasBasePotionEffects(PotionMeta potionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return hasBasePotionEffectsLegacy(potionMeta);
|
||||
} else {
|
||||
return hasBasePotionEffectsModern(potionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasBasePotionEffectsLegacy(PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
|
||||
return methodPotionTypeGetEffectType.invoke(potionType) != null;
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasBasePotionEffectsModern(PotionMeta potionMeta) {
|
||||
try {
|
||||
PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
|
||||
List<PotionEffectType> potionEffectTypeList = (List<PotionEffectType>) methodPotionTypeGetPotionEffects.invoke(potionType);
|
||||
return potionEffectTypeList != null || !potionEffectTypeList.isEmpty();
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base potion type of a potion meta.
|
||||
* Note that extended/upgraded are ignored in 1.20.5 and later.
|
||||
*
|
||||
* @param potionMeta the potion meta
|
||||
* @param extended true if the potion is extended
|
||||
* @param upgraded true if the potion is upgraded
|
||||
*/
|
||||
public static void setBasePotionType(PotionMeta potionMeta, PotionType potionType, boolean extended, boolean upgraded) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
setBasePotionTypeLegacy(potionMeta, potionType, extended, upgraded);
|
||||
} else {
|
||||
setBasePotionTypeModern(potionMeta, potionType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setBasePotionTypeLegacy(PotionMeta potionMeta, PotionType potionType, boolean extended,
|
||||
boolean upgraded) {
|
||||
try {
|
||||
Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class)
|
||||
.newInstance(potionType, extended, upgraded);
|
||||
methodSetBasePotionData.invoke(potionMeta, potionData);
|
||||
} catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setBasePotionTypeModern(PotionMeta potionMeta, PotionType potionType) {
|
||||
try {
|
||||
methodPotionMetaSetBasePotionType.invoke(potionMeta, potionType);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -33,6 +33,9 @@ public final class CommandRegistrationManager {
|
||||
|
||||
private static void registerSkillCommands() {
|
||||
for (PrimarySkillType skill : PrimarySkillType.values()) {
|
||||
if (skill == PrimarySkillType.MACES)
|
||||
continue;
|
||||
|
||||
String commandName = skill.toString().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
@ -77,6 +80,10 @@ public final class CommandRegistrationManager {
|
||||
command.setExecutor(new HerbalismCommand());
|
||||
break;
|
||||
|
||||
case MACES:
|
||||
// command.setExecutor(new MacesCommand());
|
||||
break;
|
||||
|
||||
case MINING:
|
||||
command.setExecutor(new MiningCommand());
|
||||
break;
|
||||
@ -113,7 +120,7 @@ public final class CommandRegistrationManager {
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
throw new IllegalStateException("Unexpected value: " + skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import java.util.HashMap;
|
||||
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||
*
|
||||
*/
|
||||
//TODO: I need to delete this crap
|
||||
public class CompatibilityManager {
|
||||
private @NotNull HashMap<CompatibilityType, Boolean> supportedLayers;
|
||||
private boolean isFullyCompatibleServerSoftware = true; //true if all compatibility layers load successfully
|
||||
@ -159,7 +158,7 @@ public class CompatibilityManager {
|
||||
return masterAnglerCompatibility;
|
||||
}
|
||||
|
||||
public @Nullable MinecraftGameVersion getMinecraftGameVersion() {
|
||||
public @NotNull MinecraftGameVersion getMinecraftGameVersion() {
|
||||
return minecraftGameVersion;
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ public final class CombatUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void processTridentCombatMelee(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.THORNS) {
|
||||
return;
|
||||
@ -214,6 +215,32 @@ public final class CombatUtils {
|
||||
delayArrowMetaCleanup(arrow);
|
||||
}
|
||||
|
||||
private static void processMacesCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.THORNS) {
|
||||
return;
|
||||
}
|
||||
|
||||
double boostedDamage = event.getDamage();
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Make sure the profiles been loaded
|
||||
if(mcMMOPlayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MacesManager macesManager = mcMMOPlayer.getMacesManager();
|
||||
|
||||
if(canUseLimitBreak(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK)) {
|
||||
boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
|
||||
}
|
||||
|
||||
event.setDamage(boostedDamage);
|
||||
processCombatXP(mcMMOPlayer, target, PrimarySkillType.MACES);
|
||||
|
||||
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||
}
|
||||
|
||||
private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.THORNS) {
|
||||
return;
|
||||
@ -498,6 +525,15 @@ public final class CombatUtils {
|
||||
processTridentCombatMelee(target, player, event);
|
||||
}
|
||||
}
|
||||
else if (ItemUtils.isMace(heldItem)) {
|
||||
if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.MACES, target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.MACES)) {
|
||||
processMacesCombat(target, player, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (entityType == EntityType.WOLF) {
|
||||
|
@ -198,6 +198,7 @@ public class SkillTools {
|
||||
case SUPER_SHOTGUN -> PrimarySkillType.CROSSBOWS;
|
||||
case TRIDENTS_SUPER_ABILITY -> PrimarySkillType.TRIDENTS;
|
||||
case EXPLOSIVE_SHOT -> PrimarySkillType.ARCHERY;
|
||||
case MACES_SUPER_ABILITY -> PrimarySkillType.MACES;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ import com.gmail.nossr50.util.text.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
@ -28,12 +27,13 @@ import org.bukkit.inventory.ShapedRecipe;
|
||||
import org.bukkit.inventory.ShapelessRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionEffectMapper.getHaste;
|
||||
|
||||
public final class SkillUtils {
|
||||
/**
|
||||
* This is a static utility class, therefore we don't want any instances of
|
||||
@ -148,13 +148,8 @@ public final class SkillUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
int originalDigSpeed = heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED);
|
||||
|
||||
//Add dig speed
|
||||
|
||||
//Lore no longer gets added, no point to it afaik
|
||||
//ItemUtils.addAbilityLore(heldItem); //lore can be a secondary failsafe for 1.13 and below
|
||||
ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED));
|
||||
int originalDigSpeed = heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency());
|
||||
ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency()));
|
||||
|
||||
//1.13.2+ will have persistent metadata for this item
|
||||
mcMMO.getMetadataService().getItemMetadataService().setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
|
||||
@ -162,9 +157,9 @@ public final class SkillUtils {
|
||||
int duration = 0;
|
||||
int amplifier = 0;
|
||||
|
||||
if (player.hasPotionEffect(PotionEffectType.FAST_DIGGING)) {
|
||||
if (player.hasPotionEffect(getHaste())) {
|
||||
for (PotionEffect effect : player.getActivePotionEffects()) {
|
||||
if (effect.getType() == PotionEffectType.FAST_DIGGING) {
|
||||
if (effect.getType() == getHaste()) {
|
||||
duration = effect.getDuration();
|
||||
amplifier = effect.getAmplifier();
|
||||
break;
|
||||
@ -194,7 +189,7 @@ public final class SkillUtils {
|
||||
mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill))) * Misc.TICK_CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
PotionEffect abilityBuff = new PotionEffect(PotionEffectType.FAST_DIGGING, duration + ticks, amplifier + 10);
|
||||
PotionEffect abilityBuff = new PotionEffect(getHaste(), duration + ticks, amplifier + 10);
|
||||
player.addPotionEffect(abilityBuff, true);
|
||||
}
|
||||
}
|
||||
@ -221,7 +216,7 @@ public final class SkillUtils {
|
||||
|
||||
if(itemMeta != null) {
|
||||
// This is safe to call without prior checks.
|
||||
itemMeta.removeEnchant(Enchantment.DIG_SPEED);
|
||||
itemMeta.removeEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency());
|
||||
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
ItemUtils.removeAbilityLore(itemStack);
|
||||
@ -251,7 +246,7 @@ public final class SkillUtils {
|
||||
|
||||
Material type = itemStack.getType();
|
||||
short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability();
|
||||
durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(Enchantment.DURABILITY) + 1), maxDurability * maxDamageModifier);
|
||||
durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1), maxDurability * maxDamageModifier);
|
||||
|
||||
itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability));
|
||||
}
|
||||
@ -281,7 +276,7 @@ public final class SkillUtils {
|
||||
|
||||
Material type = itemStack.getType();
|
||||
short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability();
|
||||
durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(Enchantment.DURABILITY) + 1)), maxDurability * maxDamageModifier);
|
||||
durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1)), maxDurability * maxDamageModifier);
|
||||
|
||||
itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability));
|
||||
}
|
||||
|
@ -1,13 +1,3 @@
|
||||
#
|
||||
# Experience configuration
|
||||
# Last updated on ${project.version}-b${BUILD_NUMBER}
|
||||
#
|
||||
# Configure the experience formula and experience settings here.
|
||||
#
|
||||
#####
|
||||
|
||||
|
||||
|
||||
# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BarColor.html
|
||||
# These are the only valid colors for Experience Bars, use the exact name found here
|
||||
# BLUE, GREEN, PINK, PURPLE, RED, WHITE, YELLOW (As of the time of this update these are the only Bar colors available, this could change in the future so check the BarColor enum to see if it has)
|
||||
@ -48,7 +38,7 @@ Fishing_ExploitFix_Options:
|
||||
MoveRange: 3
|
||||
OverFishLimit: 10
|
||||
Experience_Bars:
|
||||
# Turn this to false if you wanna disable XP bars
|
||||
# Turn this to false if you want to disable XP bars
|
||||
Enable: true
|
||||
Update:
|
||||
# XP that you gained from your party but not yourself
|
||||
@ -98,6 +88,10 @@ Experience_Bars:
|
||||
Enable: true
|
||||
Color: YELLOW
|
||||
BarStyle: SEGMENTED_6
|
||||
Maces:
|
||||
Enable: true
|
||||
Color: BLUE
|
||||
BarStyle: SEGMENTED_6
|
||||
Repair:
|
||||
Enable: true
|
||||
Color: PURPLE
|
||||
@ -170,6 +164,7 @@ Experience_Formula:
|
||||
|
||||
# Experience gained will get multiplied by these values. 1.0 by default, 0.5 means half XP gained. This happens right before multiplying the XP by the global multiplier.
|
||||
Skill_Multiplier:
|
||||
Maces: 1.0
|
||||
Crossbows: 1.0
|
||||
Tridents: 1.0
|
||||
Swords: 1.0
|
||||
@ -217,6 +212,9 @@ Diminished_Returns:
|
||||
Repair: 20000
|
||||
Fishing: 20000
|
||||
Alchemy: 20000
|
||||
Crossbows: 20000
|
||||
Tridents: 20000
|
||||
Maces: 20000
|
||||
|
||||
Time_Interval: 10
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
Placeholder= This value is for any WIP locale entries that will not be displayed to users
|
||||
JSON.Rank=Rank
|
||||
JSON.DescriptionHeader=Description:
|
||||
JSON.JWrapper.Header=Details
|
||||
@ -26,6 +27,7 @@ JSON.Salvage=Salvage
|
||||
JSON.Swords=Swords
|
||||
JSON.Taming=Taming
|
||||
JSON.Tridents=Tridents
|
||||
JSON.Maces=Maces
|
||||
JSON.Unarmed=Unarmed
|
||||
JSON.Woodcutting=Woodcutting
|
||||
JSON.URL.Website=The official mcMMO Website!
|
||||
@ -96,6 +98,7 @@ Overhaul.Name.Smelting=Smelting
|
||||
Overhaul.Name.Swords=Swords
|
||||
Overhaul.Name.Taming=Taming
|
||||
Overhaul.Name.Tridents=Tridents
|
||||
Overhaul.Name.Maces=Maces
|
||||
Overhaul.Name.Unarmed=Unarmed
|
||||
Overhaul.Name.Woodcutting=Woodcutting
|
||||
# /mcMMO Command Style Stuff
|
||||
@ -122,6 +125,7 @@ XPBar.Smelting=Smelting Lv.&6{0}
|
||||
XPBar.Swords=Swords Lv.&6{0}
|
||||
XPBar.Taming=Taming Lv.&6{0}
|
||||
XPBar.Tridents=Tridents Lv.&6{0}
|
||||
XPBar.Maces=Maces Lv.&6{0}
|
||||
XPBar.Unarmed=Unarmed Lv.&6{0}
|
||||
XPBar.Woodcutting=Woodcutting Lv.&6{0}
|
||||
#This is just a preset template that gets used if the 'ExtraDetails' setting is turned on in experience.yml (off by default), you can ignore this template and just edit the strings above
|
||||
@ -457,9 +461,6 @@ Tridents.Listener=Tridents:
|
||||
Maces.SkillName=MACES
|
||||
Maces.Ability.Lower=&7You lower your mace.
|
||||
Maces.Ability.Ready=&3You &6ready&3 your Mace.
|
||||
Maces.Skills.MaceSmash.Refresh=&aYour &eGiga Smash &aability is refreshed!
|
||||
Maces.Skills.MaceSmash.Other.On=&a{0}&2 used &cGiga Smash!
|
||||
Maces.SubSkill.GigaSmash.Name=Giga Smash
|
||||
Maces.SubSkill.MacesLimitBreak.Name=Maces Limit Break
|
||||
Maces.SubSkill.MacesLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether it will boost damage in PVE.
|
||||
Maces.SubSkill.MacesLimitBreak.Stat=Limit Break Max DMG
|
||||
|
@ -154,6 +154,9 @@ commands:
|
||||
salvage:
|
||||
description: Detailed mcMMO skill info
|
||||
permission: mcmmo.commands.salvage
|
||||
maces:
|
||||
description: Detailed mcMMO skill info
|
||||
permission: mcmmo.commands.maces
|
||||
mmopower:
|
||||
description: Shows skill mastery and power level info
|
||||
permission: mcmmo.commands.mmopower
|
||||
|
@ -443,6 +443,30 @@ Salvage:
|
||||
Rank_6: 750
|
||||
Rank_7: 850
|
||||
Rank_8: 1000
|
||||
Maces:
|
||||
TridentsLimitBreak:
|
||||
Standard:
|
||||
Rank_1: 10
|
||||
Rank_2: 20
|
||||
Rank_3: 30
|
||||
Rank_4: 40
|
||||
Rank_5: 50
|
||||
Rank_6: 60
|
||||
Rank_7: 70
|
||||
Rank_8: 80
|
||||
Rank_9: 90
|
||||
Rank_10: 100
|
||||
RetroMode:
|
||||
Rank_1: 100
|
||||
Rank_2: 200
|
||||
Rank_3: 300
|
||||
Rank_4: 400
|
||||
Rank_5: 500
|
||||
Rank_6: 600
|
||||
Rank_7: 700
|
||||
Rank_8: 800
|
||||
Rank_9: 900
|
||||
Rank_10: 1000
|
||||
Mining:
|
||||
MotherLode:
|
||||
Standard:
|
||||
|
@ -16,13 +16,12 @@ import com.gmail.nossr50.util.blockmeta.ChunkManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillTools;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemFactory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
@ -31,9 +30,10 @@ import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public abstract class MMOTestEnvironment {
|
||||
protected MockedStatic<Bukkit> mockedBukkit;
|
||||
protected MockedStatic<mcMMO> mockedMcMMO;
|
||||
protected MockedStatic<ChatConfig> mockedChatConfig;
|
||||
protected MockedStatic<ExperienceConfig> experienceConfig;
|
||||
@ -63,26 +63,27 @@ public abstract class MMOTestEnvironment {
|
||||
protected PlayerProfile playerProfile;
|
||||
protected McMMOPlayer mmoPlayer;
|
||||
protected String playerName = "testPlayer";
|
||||
protected ItemFactory itemFactory;
|
||||
|
||||
protected ChunkManager chunkManager;
|
||||
protected MaterialMapStore materialMapStore;
|
||||
|
||||
protected void mockBaseEnvironment(Logger logger) throws InvalidSkillException {
|
||||
mockedMcMMO = Mockito.mockStatic(mcMMO.class);
|
||||
mcMMO.p = Mockito.mock(mcMMO.class);
|
||||
mockedMcMMO = mockStatic(mcMMO.class);
|
||||
mcMMO.p = mock(mcMMO.class);
|
||||
when(mcMMO.p.getLogger()).thenReturn(logger);
|
||||
|
||||
// place store
|
||||
chunkManager = Mockito.mock(ChunkManager.class);
|
||||
chunkManager = mock(ChunkManager.class);
|
||||
when(mcMMO.getPlaceStore()).thenReturn(chunkManager);
|
||||
|
||||
// shut off mod manager for woodcutting
|
||||
when(mcMMO.getModManager()).thenReturn(Mockito.mock(ModManager.class));
|
||||
when(mcMMO.getModManager()).thenReturn(mock(ModManager.class));
|
||||
when(mcMMO.getModManager().isCustomLog(any())).thenReturn(false);
|
||||
|
||||
// chat config
|
||||
mockedChatConfig = Mockito.mockStatic(ChatConfig.class);
|
||||
when(ChatConfig.getInstance()).thenReturn(Mockito.mock(ChatConfig.class));
|
||||
mockedChatConfig = mockStatic(ChatConfig.class);
|
||||
when(ChatConfig.getInstance()).thenReturn(mock(ChatConfig.class));
|
||||
|
||||
// general config
|
||||
mockGeneralConfig();
|
||||
@ -108,29 +109,34 @@ public abstract class MMOTestEnvironment {
|
||||
|
||||
mockPermissions();
|
||||
|
||||
mockedRankUtils = Mockito.mockStatic(RankUtils.class);
|
||||
mockedRankUtils = mockStatic(RankUtils.class);
|
||||
|
||||
// wire server
|
||||
this.server = Mockito.mock(Server.class);
|
||||
this.server = mock(Server.class);
|
||||
when(mcMMO.p.getServer()).thenReturn(server);
|
||||
|
||||
mockedBukkit = mockStatic(Bukkit.class);
|
||||
when(Bukkit.getItemFactory()).thenReturn(itemFactory);
|
||||
itemFactory = mock(ItemFactory.class);
|
||||
// when(itemFactory.getItemMeta(any())).thenReturn(mock(ItemMeta.class));
|
||||
|
||||
// wire plugin manager
|
||||
this.pluginManager = Mockito.mock(PluginManager.class);
|
||||
this.pluginManager = mock(PluginManager.class);
|
||||
when(server.getPluginManager()).thenReturn(pluginManager);
|
||||
|
||||
// wire world
|
||||
this.world = Mockito.mock(World.class);
|
||||
this.world = mock(World.class);
|
||||
|
||||
// wire Misc
|
||||
this.mockedMisc = Mockito.mockStatic(Misc.class);
|
||||
this.mockedMisc = mockStatic(Misc.class);
|
||||
when(Misc.getBlockCenter(any())).thenReturn(new Location(world, 0, 0, 0));
|
||||
|
||||
// setup player and player related mocks after everything else
|
||||
this.player = Mockito.mock(Player.class);
|
||||
this.player = mock(Player.class);
|
||||
when(player.getUniqueId()).thenReturn(playerUUID);
|
||||
|
||||
// wire inventory
|
||||
this.playerInventory = Mockito.mock(PlayerInventory.class);
|
||||
this.playerInventory = mock(PlayerInventory.class);
|
||||
when(player.getInventory()).thenReturn(playerInventory);
|
||||
|
||||
// PlayerProfile and McMMOPlayer are partially mocked
|
||||
@ -138,7 +144,7 @@ public abstract class MMOTestEnvironment {
|
||||
mmoPlayer = Mockito.spy(new McMMOPlayer(player, playerProfile));
|
||||
|
||||
// wire user manager
|
||||
this.mockedUserManager = Mockito.mockStatic(UserManager.class);
|
||||
this.mockedUserManager = mockStatic(UserManager.class);
|
||||
when(UserManager.getPlayer(player)).thenReturn(mmoPlayer);
|
||||
|
||||
this.materialMapStore = new MaterialMapStore();
|
||||
@ -146,7 +152,7 @@ public abstract class MMOTestEnvironment {
|
||||
}
|
||||
|
||||
private void mockPermissions() {
|
||||
mockedPermissions = Mockito.mockStatic(Permissions.class);
|
||||
mockedPermissions = mockStatic(Permissions.class);
|
||||
when(Permissions.isSubSkillEnabled(any(Player.class), any(SubSkillType.class))).thenReturn(true);
|
||||
when(Permissions.canUseSubSkill(any(Player.class), any(SubSkillType.class))).thenReturn(true);
|
||||
when(Permissions.isSubSkillEnabled(any(Player.class), any(SubSkillType.class))).thenReturn(true);
|
||||
@ -155,16 +161,16 @@ public abstract class MMOTestEnvironment {
|
||||
}
|
||||
|
||||
private void mockRankConfig() {
|
||||
rankConfig = Mockito.mock(RankConfig.class);
|
||||
rankConfig = mock(RankConfig.class);
|
||||
}
|
||||
|
||||
private void mockAdvancedConfig() {
|
||||
this.advancedConfig = Mockito.mock(AdvancedConfig.class);
|
||||
this.advancedConfig = mock(AdvancedConfig.class);
|
||||
when(mcMMO.p.getAdvancedConfig()).thenReturn(advancedConfig);
|
||||
}
|
||||
|
||||
private void mockGeneralConfig() {
|
||||
generalConfig = Mockito.mock(GeneralConfig.class);
|
||||
generalConfig = mock(GeneralConfig.class);
|
||||
when(generalConfig.getTreeFellerThreshold()).thenReturn(100);
|
||||
when(generalConfig.getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, Material.OAK_LOG)).thenReturn(true);
|
||||
when(generalConfig.getLocale()).thenReturn("en_US");
|
||||
@ -172,15 +178,15 @@ public abstract class MMOTestEnvironment {
|
||||
}
|
||||
|
||||
private void mockPartyConfig() {
|
||||
partyConfig = Mockito.mock(PartyConfig.class);
|
||||
partyConfig = mock(PartyConfig.class);
|
||||
when(partyConfig.isPartyEnabled()).thenReturn(false);
|
||||
when(mcMMO.p.getPartyConfig()).thenReturn(partyConfig);
|
||||
}
|
||||
|
||||
private void mockExperienceConfig() {
|
||||
experienceConfig = Mockito.mockStatic(ExperienceConfig.class);
|
||||
experienceConfig = mockStatic(ExperienceConfig.class);
|
||||
|
||||
when(ExperienceConfig.getInstance()).thenReturn(Mockito.mock(ExperienceConfig.class));
|
||||
when(ExperienceConfig.getInstance()).thenReturn(mock(ExperienceConfig.class));
|
||||
|
||||
// Combat
|
||||
when(ExperienceConfig.getInstance().getCombatXP("Cow")).thenReturn(1D);
|
||||
@ -212,5 +218,8 @@ public abstract class MMOTestEnvironment {
|
||||
if (mockedEventUtils != null) {
|
||||
mockedEventUtils.close();
|
||||
}
|
||||
if (mockedBukkit != null) {
|
||||
mockedBukkit.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
//package com.gmail.nossr50.config.skills.alchemy;
|
||||
//
|
||||
//import com.gmail.nossr50.MMOTestEnvironment;
|
||||
//import org.bukkit.inventory.meta.ItemMeta;
|
||||
//import org.bukkit.inventory.meta.PotionMeta;
|
||||
//import org.junit.jupiter.api.AfterEach;
|
||||
//import org.junit.jupiter.api.BeforeEach;
|
||||
//import org.junit.jupiter.api.Test;
|
||||
//
|
||||
//import java.io.File;
|
||||
//import java.net.URL;
|
||||
//import java.util.logging.Logger;
|
||||
//
|
||||
//import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
//import static org.mockito.ArgumentMatchers.any;
|
||||
//import static org.mockito.Mockito.mock;
|
||||
//import static org.mockito.Mockito.when;
|
||||
//
|
||||
//class PotionConfigTest extends MMOTestEnvironment {
|
||||
//
|
||||
// public static final String POTION_LEGACY_POTION_YML = "potion/legacy_potion.yml";
|
||||
// public static final String POTION_MODERN_YML = "potion/modern_potion.yml";
|
||||
// public static final Logger logger = Logger.getLogger(PotionConfigTest.class.getName());
|
||||
//
|
||||
// @BeforeEach
|
||||
// void setUp() {
|
||||
// mockBaseEnvironment(logger);
|
||||
// final PotionMeta potionMeta = mock(PotionMeta.class);
|
||||
// when(itemFactory.getItemMeta(any())).thenReturn(potionMeta);
|
||||
// }
|
||||
//
|
||||
// @AfterEach
|
||||
// void tearDown() {
|
||||
// cleanupBaseEnvironment();
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// void testLoadLegacyConfig() {
|
||||
// final PotionConfig potionConfig = getPotionConfig(POTION_LEGACY_POTION_YML);
|
||||
// assertNotNull(potionConfig);
|
||||
//
|
||||
// potionConfig.loadConcoctions();
|
||||
// int loaded = potionConfig.loadPotionMap();
|
||||
// System.out.println("Loaded " + loaded + " potions");
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// void testModernConfig() {
|
||||
// final PotionConfig potionConfig = getPotionConfig(POTION_MODERN_YML);
|
||||
// assertNotNull(potionConfig);
|
||||
//
|
||||
// potionConfig.loadConcoctions();
|
||||
// int loaded = potionConfig.loadPotionMap();
|
||||
// System.out.println("Loaded " + loaded + " potions");
|
||||
// }
|
||||
//
|
||||
// private PotionConfig getPotionConfig(String path) {
|
||||
// // Get the file URL using the class loader
|
||||
// final URL resource = getClass().getClassLoader().getResource(path);
|
||||
// if (resource == null) {
|
||||
// throw new IllegalArgumentException("file not found!");
|
||||
// } else {
|
||||
// // Convert URL to a File object
|
||||
// final File potionFile = new File(resource.getFile());
|
||||
// System.out.println("File path: " + potionFile.getAbsolutePath());
|
||||
// return new PotionConfig(potionFile);
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -10,7 +10,6 @@ import com.gmail.nossr50.util.skills.SkillTools;
|
||||
import com.google.common.io.Files;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -38,32 +37,30 @@ class FlatFileDatabaseManagerTest {
|
||||
public static final @NotNull String BAD_DATA_FILE_LINE_TWENTY_THREE = "nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:";
|
||||
public static final @NotNull String DB_BADDATA = "baddatadb.users";
|
||||
public static final @NotNull String DB_HEALTHY = "healthydb.users";
|
||||
public static final @NotNull String HEALTHY_DB_LINE_1 = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:140:14:150:15:1111:2222:3333";
|
||||
public static final @NotNull String HEALTHY_DB_LINE_ONE_UUID_STR = "588fe472-1c82-4c4e-9aa1-7eefccb277e3";
|
||||
public static final String DB_MISSING_LAST_LOGIN = "missinglastlogin.users";
|
||||
public static final String LINE_TWO_FROM_MISSING_DB = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:";
|
||||
private static File tempDir;
|
||||
private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||
private final long PURGE_TIME = 2630000000L;
|
||||
private static @Nullable FlatFileDatabaseManager db;
|
||||
|
||||
//Making them all unique makes it easier on us to edit this stuff later
|
||||
int expectedLvlMining = 1, expectedLvlWoodcutting = 2, expectedLvlRepair = 3,
|
||||
expectedLvlUnarmed = 4, expectedLvlHerbalism = 5, expectedLvlExcavation = 6,
|
||||
expectedLvlArchery = 7, expectedLvlSwords = 8, expectedLvlAxes = 9, expectedLvlAcrobatics = 10,
|
||||
expectedLvlTaming = 11, expectedLvlFishing = 12, expectedLvlAlchemy = 13, expectedLvlCrossbows = 14,
|
||||
expectedLvlTridents = 15;
|
||||
expectedLvlTridents = 15, expectedLvlMaces = 16;
|
||||
|
||||
float expectedExpMining = 10, expectedExpWoodcutting = 20, expectedExpRepair = 30,
|
||||
expectedExpUnarmed = 40, expectedExpHerbalism = 50, expectedExpExcavation = 60,
|
||||
expectedExpArchery = 70, expectedExpSwords = 80, expectedExpAxes = 90, expectedExpAcrobatics = 100,
|
||||
expectedExpTaming = 110, expectedExpFishing = 120, expectedExpAlchemy = 130, expectedExpCrossbows = 140,
|
||||
expectedExpTridents = 150;
|
||||
expectedExpTridents = 150, expectedExpMaces = 160;
|
||||
|
||||
long expectedBerserkCd = 111, expectedGigaDrillBreakerCd = 222, expectedTreeFellerCd = 333,
|
||||
expectedGreenTerraCd = 444, expectedSerratedStrikesCd = 555, expectedSkullSplitterCd = 666,
|
||||
expectedSuperBreakerCd = 777, expectedBlastMiningCd = 888, expectedChimaeraWingCd = 999,
|
||||
expectedSuperShotgunCd = 1111, expectedTridentSuperCd = 2222, expectedExplosiveShotCd = 3333;
|
||||
expectedSuperShotgunCd = 1111, expectedTridentSuperCd = 2222, expectedExplosiveShotCd = 3333,
|
||||
expectedMacesSuperCd = 4444;
|
||||
|
||||
int expectedScoreboardTips = 1111;
|
||||
Long expectedLastLogin = 2020L;
|
||||
@ -75,10 +72,8 @@ class FlatFileDatabaseManagerTest {
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
assertNull(db);
|
||||
//noinspection UnstableApiUsage
|
||||
tempDir = Files.createTempDir();
|
||||
db = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
}
|
||||
|
||||
private @NotNull String getTemporaryUserFilePath() {
|
||||
@ -88,7 +83,6 @@ class FlatFileDatabaseManagerTest {
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
recursiveDelete(tempDir);
|
||||
db = null;
|
||||
}
|
||||
|
||||
//Nothing wrong with this database
|
||||
@ -150,17 +144,19 @@ class FlatFileDatabaseManagerTest {
|
||||
|
||||
@Test
|
||||
void testDefaultInit() {
|
||||
db = new FlatFileDatabaseManager(getTemporaryUserFilePath(), logger, PURGE_TIME, 0);
|
||||
new FlatFileDatabaseManager(getTemporaryUserFilePath(), logger, PURGE_TIME, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateLeaderboards() {
|
||||
assertNotNull(db);
|
||||
assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
assertNotNull(flatFileDatabaseManager);
|
||||
assertEquals(LeaderboardStatus.UPDATED, flatFileDatabaseManager.updateLeaderboards());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSaveUser() {
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
//Make a Profile to save and check to see if it worked
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
String playerName = "nossr50";
|
||||
@ -168,15 +164,15 @@ class FlatFileDatabaseManagerTest {
|
||||
//The above profile should be "zero" initialized
|
||||
|
||||
//Save the zero version and see if it looks correct
|
||||
assertNotNull(db);
|
||||
assertTrue(db.getUsersFile().exists()); //Users file should have been created from the above com.gmail.nossr50.database.FlatFileDatabaseManager.checkFileHealthAndStructure
|
||||
assertNotNull(db.getUsersFile());
|
||||
assertNotNull(flatFileDatabaseManager);
|
||||
assertTrue(flatFileDatabaseManager.getUsersFile().exists()); //Users file should have been created from the above com.gmail.nossr50.database.FlatFileDatabaseManager.checkFileHealthAndStructure
|
||||
assertNotNull(flatFileDatabaseManager.getUsersFile());
|
||||
|
||||
//The DB is empty at this point, add our user
|
||||
assertTrue(db.saveUser(testProfile)); //True means we saved the user
|
||||
//The flatFileDatabaseManager is empty at this point, add our user
|
||||
assertTrue(flatFileDatabaseManager.saveUser(testProfile)); //True means we saved the user
|
||||
|
||||
//Check for the empty profile
|
||||
PlayerProfile retrievedFromData = db.loadPlayerProfile(uuid);
|
||||
PlayerProfile retrievedFromData = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
|
||||
assertEquals(uuid, retrievedFromData.getUniqueId());
|
||||
assertEquals(playerName, retrievedFromData.getPlayerName());
|
||||
@ -187,9 +183,9 @@ class FlatFileDatabaseManagerTest {
|
||||
|
||||
String alteredName = "changedmyname";
|
||||
PlayerProfile changedNameProfile = new PlayerProfile(alteredName, uuid, 0);
|
||||
assertTrue(db.saveUser(changedNameProfile)); //True means we saved the user
|
||||
assertTrue(flatFileDatabaseManager.saveUser(changedNameProfile)); //True means we saved the user
|
||||
|
||||
retrievedFromData = db.loadPlayerProfile(uuid);
|
||||
retrievedFromData = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
|
||||
assertEquals(uuid, retrievedFromData.getUniqueId());
|
||||
assertEquals(alteredName, retrievedFromData.getPlayerName());
|
||||
@ -198,49 +194,27 @@ class FlatFileDatabaseManagerTest {
|
||||
@Test
|
||||
void testAddedMissingLastLoginValues() {
|
||||
File dbFile = prepareDatabaseTestResource(DB_MISSING_LAST_LOGIN);
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(dbFile);
|
||||
logger.info("File Path: "+ dbFile.getAbsolutePath());
|
||||
assertArrayEquals(LINE_TWO_FROM_MISSING_DB.split(":"), dataFromFile.get(1));
|
||||
assertEquals(dataFromFile.get(1)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
assertNotNull(flagsFound);
|
||||
assertTrue(flagsFound.contains(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE));
|
||||
|
||||
//Check for the fixed value
|
||||
PlayerProfile profile = db.loadPlayerProfile("nossr50");
|
||||
PlayerProfile profile = flatFileDatabaseManager.loadPlayerProfile("nossr50");
|
||||
assertEquals(-1, (long) profile.getLastLogin());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadByName() {
|
||||
File healthyDB = prepareDatabaseTestResource(DB_HEALTHY);
|
||||
|
||||
/*
|
||||
* We have established the files are in good order, so now for the actual testing
|
||||
*/
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(healthyDB);
|
||||
logger.info("File Path: "+healthyDB.getAbsolutePath());
|
||||
assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
assertNull(flagsFound); //No flags should be found
|
||||
|
||||
/*
|
||||
* Once the DB looks fine load the profile
|
||||
*/
|
||||
|
||||
String playerName = "nossr50";
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
|
||||
PlayerProfile profile = db.loadPlayerProfile(playerName);
|
||||
PlayerProfile profile = flatFileDatabaseManager.loadPlayerProfile(playerName);
|
||||
testHealthyDataProfileValues(playerName, uuid, profile);
|
||||
}
|
||||
|
||||
@ -251,16 +225,16 @@ class FlatFileDatabaseManagerTest {
|
||||
String playerName = "nossr50";
|
||||
|
||||
int newUserTestStartingLvl = 1337;
|
||||
db = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true);
|
||||
db.checkFileHealthAndStructure();
|
||||
var flatFileDatabaseManager = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true);
|
||||
flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
|
||||
PlayerProfile playerProfile = db.newUser(playerName, uuid);
|
||||
PlayerProfile playerProfile = flatFileDatabaseManager.newUser(playerName, uuid);
|
||||
|
||||
assertTrue(playerProfile.isLoaded());
|
||||
assertEquals(playerName, playerProfile.getPlayerName());
|
||||
assertEquals(uuid, playerProfile.getUniqueId());
|
||||
|
||||
PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
|
||||
PlayerProfile retrievedFromDisk = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromDisk.isLoaded());
|
||||
assertEquals(playerName, retrievedFromDisk.getPlayerName());
|
||||
assertEquals(uuid, retrievedFromDisk.getUniqueId());
|
||||
@ -270,11 +244,11 @@ class FlatFileDatabaseManagerTest {
|
||||
checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
|
||||
|
||||
//TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
|
||||
db.newUser("disco", new UUID(3, 3));
|
||||
db.newUser("dingus", new UUID(3, 4));
|
||||
db.newUser("duped_dingus", new UUID(3, 4));
|
||||
flatFileDatabaseManager.newUser("disco", new UUID(3, 3));
|
||||
flatFileDatabaseManager.newUser("dingus", new UUID(3, 4));
|
||||
flatFileDatabaseManager.newUser("duped_dingus", new UUID(3, 4));
|
||||
|
||||
assertEquals(5, getSplitDataFromFile(db.getUsersFile()).size());
|
||||
assertEquals(5, getSplitDataFromFile(flatFileDatabaseManager.getUsersFile()).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -286,16 +260,16 @@ class FlatFileDatabaseManagerTest {
|
||||
File file = prepareDatabaseTestResource(DB_HEALTHY); //Existing DB
|
||||
|
||||
int newUserTestStartingLvl = 1337;
|
||||
db = new FlatFileDatabaseManager(file, logger, PURGE_TIME, newUserTestStartingLvl, true);
|
||||
db.checkFileHealthAndStructure();
|
||||
var flatFileDatabaseManager = new FlatFileDatabaseManager(file, logger, PURGE_TIME, newUserTestStartingLvl, true);
|
||||
flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
|
||||
PlayerProfile playerProfile = db.newUser(playerName, uuid);
|
||||
PlayerProfile playerProfile = flatFileDatabaseManager.newUser(playerName, uuid);
|
||||
|
||||
assertTrue(playerProfile.isLoaded());
|
||||
assertEquals(playerName, playerProfile.getPlayerName());
|
||||
assertEquals(uuid, playerProfile.getUniqueId());
|
||||
|
||||
PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
|
||||
PlayerProfile retrievedFromDisk = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromDisk.isLoaded());
|
||||
assertEquals(playerName, retrievedFromDisk.getPlayerName());
|
||||
assertEquals(uuid, retrievedFromDisk.getUniqueId());
|
||||
@ -305,15 +279,15 @@ class FlatFileDatabaseManagerTest {
|
||||
checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
|
||||
|
||||
//TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
|
||||
db.newUser("bidoof", new UUID(3, 3));
|
||||
db.newUser("derp", new UUID(3, 4));
|
||||
db.newUser("pizza", new UUID(3, 4));
|
||||
flatFileDatabaseManager.newUser("bidoof", new UUID(3, 3));
|
||||
flatFileDatabaseManager.newUser("derp", new UUID(3, 4));
|
||||
flatFileDatabaseManager.newUser("pizza", new UUID(3, 4));
|
||||
|
||||
assertEquals(7, getSplitDataFromFile(db.getUsersFile()).size());
|
||||
assertEquals(7, getSplitDataFromFile(flatFileDatabaseManager.getUsersFile()).size());
|
||||
|
||||
//Now we *fix* the DB and there should be one less
|
||||
db.checkFileHealthAndStructure();
|
||||
assertEquals(6, getSplitDataFromFile(db.getUsersFile()).size());
|
||||
//Now we *fix* the flatFileDatabaseManager and there should be one less
|
||||
flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
assertEquals(6, getSplitDataFromFile(flatFileDatabaseManager.getUsersFile()).size());
|
||||
}
|
||||
|
||||
private void checkNewUserValues(@NotNull PlayerProfile playerProfile, int startingLevel) {
|
||||
@ -338,71 +312,45 @@ class FlatFileDatabaseManagerTest {
|
||||
@Test
|
||||
void testLoadByUUID() {
|
||||
File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
|
||||
|
||||
/*
|
||||
* We have established the files are in good order, so now for the actual testing
|
||||
*/
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(dbFile);
|
||||
logger.info("File Path: " + dbFile.getAbsolutePath());
|
||||
assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
var flatFileDatabaseManager = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
assertNull(flagsFound); //No flags should be found
|
||||
|
||||
/*
|
||||
* Once the DB looks fine load the profile
|
||||
* Once the flatFileDatabaseManager looks fine load the profile
|
||||
*/
|
||||
|
||||
String playerName = "nossr50";
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
|
||||
PlayerProfile profile1 = db.loadPlayerProfile(uuid);
|
||||
PlayerProfile profile1 = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
testHealthyDataProfileValues(playerName, uuid, profile1);
|
||||
|
||||
|
||||
assertFalse(db.loadPlayerProfile(new UUID(0, 1)).isLoaded()); //This profile should not exist and therefor will return unloaded
|
||||
assertFalse(flatFileDatabaseManager.loadPlayerProfile(new UUID(0, 1)).isLoaded()); //This profile should not exist and therefor will return unloaded
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadByUUIDAndName() {
|
||||
File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
|
||||
|
||||
/*
|
||||
* We have established the files are in good order, so now for the actual testing
|
||||
*/
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(dbFile);
|
||||
logger.info("File Path: " + dbFile.getAbsolutePath());
|
||||
assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
var flatFileDatabaseManager = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
assertNull(flagsFound); //No flags should be found
|
||||
|
||||
/*
|
||||
* Once the DB looks fine load the profile
|
||||
*/
|
||||
|
||||
String playerName = "nossr50";
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
|
||||
Player player = initMockPlayer(playerName, uuid);
|
||||
PlayerProfile profile1 = db.loadPlayerProfile(player);
|
||||
PlayerProfile profile1 = flatFileDatabaseManager.loadPlayerProfile(player);
|
||||
testHealthyDataProfileValues(playerName, uuid, profile1);
|
||||
|
||||
String updatedName = "updatedName";
|
||||
Player updatedNamePlayer = initMockPlayer(updatedName, uuid);
|
||||
PlayerProfile updatedNameProfile = db.loadPlayerProfile(updatedNamePlayer);
|
||||
PlayerProfile updatedNameProfile = flatFileDatabaseManager.loadPlayerProfile(updatedNamePlayer);
|
||||
testHealthyDataProfileValues(updatedName, uuid, updatedNameProfile);
|
||||
|
||||
Player shouldNotExist = initMockPlayer("doesntexist", new UUID(0, 1));
|
||||
PlayerProfile profile3 = db.loadPlayerProfile(shouldNotExist);
|
||||
PlayerProfile profile3 = flatFileDatabaseManager.loadPlayerProfile(shouldNotExist);
|
||||
assertFalse(profile3.isLoaded());
|
||||
}
|
||||
|
||||
@ -484,6 +432,7 @@ class FlatFileDatabaseManagerTest {
|
||||
case BLAST_MINING -> expectedBlastMiningCd;
|
||||
case TRIDENTS_SUPER_ABILITY -> expectedTridentSuperCd;
|
||||
case EXPLOSIVE_SHOT -> expectedExplosiveShotCd;
|
||||
case MACES_SUPER_ABILITY -> expectedMacesSuperCd;
|
||||
default -> throw new RuntimeException("Values not defined for super ability please add " +
|
||||
"values for " + superAbilityType.toString() + " to the test");
|
||||
};
|
||||
@ -491,165 +440,147 @@ class FlatFileDatabaseManagerTest {
|
||||
}
|
||||
|
||||
private float getExpectedExperienceHealthyDBEntryOne(@NotNull PrimarySkillType primarySkillType) {
|
||||
switch(primarySkillType) {
|
||||
case ACROBATICS:
|
||||
return expectedExpAcrobatics;
|
||||
case ALCHEMY:
|
||||
return expectedExpAlchemy;
|
||||
case ARCHERY:
|
||||
return expectedExpArchery;
|
||||
case AXES:
|
||||
return expectedExpAxes;
|
||||
case CROSSBOWS:
|
||||
return expectedExpCrossbows;
|
||||
case EXCAVATION:
|
||||
return expectedExpExcavation;
|
||||
case FISHING:
|
||||
return expectedExpFishing;
|
||||
case HERBALISM:
|
||||
return expectedExpHerbalism;
|
||||
case MINING:
|
||||
return expectedExpMining;
|
||||
case REPAIR:
|
||||
return expectedExpRepair;
|
||||
case SALVAGE:
|
||||
case SMELTING:
|
||||
return 0;
|
||||
case SWORDS:
|
||||
return expectedExpSwords;
|
||||
case TAMING:
|
||||
return expectedExpTaming;
|
||||
case TRIDENTS:
|
||||
return expectedExpTridents;
|
||||
case UNARMED:
|
||||
return expectedExpUnarmed;
|
||||
case WOODCUTTING:
|
||||
return expectedExpWoodcutting;
|
||||
}
|
||||
|
||||
return switch (primarySkillType) {
|
||||
case ACROBATICS -> expectedExpAcrobatics;
|
||||
case ALCHEMY -> expectedExpAlchemy;
|
||||
case ARCHERY -> expectedExpArchery;
|
||||
case AXES -> expectedExpAxes;
|
||||
case CROSSBOWS -> expectedExpCrossbows;
|
||||
case EXCAVATION -> expectedExpExcavation;
|
||||
case FISHING -> expectedExpFishing;
|
||||
case HERBALISM -> expectedExpHerbalism;
|
||||
case MINING -> expectedExpMining;
|
||||
case REPAIR -> expectedExpRepair;
|
||||
case SALVAGE, SMELTING -> 0;
|
||||
case SWORDS -> expectedExpSwords;
|
||||
case TAMING -> expectedExpTaming;
|
||||
case TRIDENTS -> expectedExpTridents;
|
||||
case UNARMED -> expectedExpUnarmed;
|
||||
case WOODCUTTING -> expectedExpWoodcutting;
|
||||
case MACES -> expectedExpMaces;
|
||||
default ->
|
||||
throw new RuntimeException("Values for skill not defined, please add values for " + primarySkillType.toString() + " to the test");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private int getExpectedLevelHealthyDBEntryOne(@NotNull PrimarySkillType primarySkillType) {
|
||||
switch(primarySkillType) {
|
||||
case ACROBATICS:
|
||||
return expectedLvlAcrobatics;
|
||||
case ALCHEMY:
|
||||
return expectedLvlAlchemy;
|
||||
case ARCHERY:
|
||||
return expectedLvlArchery;
|
||||
case AXES:
|
||||
return expectedLvlAxes;
|
||||
case CROSSBOWS:
|
||||
return expectedLvlCrossbows;
|
||||
case EXCAVATION:
|
||||
return expectedLvlExcavation;
|
||||
case FISHING:
|
||||
return expectedLvlFishing;
|
||||
case HERBALISM:
|
||||
return expectedLvlHerbalism;
|
||||
case MINING:
|
||||
return expectedLvlMining;
|
||||
case REPAIR:
|
||||
return expectedLvlRepair;
|
||||
case SALVAGE:
|
||||
case SMELTING:
|
||||
return 0;
|
||||
case SWORDS:
|
||||
return expectedLvlSwords;
|
||||
case TAMING:
|
||||
return expectedLvlTaming;
|
||||
case TRIDENTS:
|
||||
return expectedLvlTridents;
|
||||
case UNARMED:
|
||||
return expectedLvlUnarmed;
|
||||
case WOODCUTTING:
|
||||
return expectedLvlWoodcutting;
|
||||
}
|
||||
|
||||
return switch (primarySkillType) {
|
||||
case ACROBATICS -> expectedLvlAcrobatics;
|
||||
case ALCHEMY -> expectedLvlAlchemy;
|
||||
case ARCHERY -> expectedLvlArchery;
|
||||
case AXES -> expectedLvlAxes;
|
||||
case CROSSBOWS -> expectedLvlCrossbows;
|
||||
case EXCAVATION -> expectedLvlExcavation;
|
||||
case FISHING -> expectedLvlFishing;
|
||||
case HERBALISM -> expectedLvlHerbalism;
|
||||
case MINING -> expectedLvlMining;
|
||||
case REPAIR -> expectedLvlRepair;
|
||||
case SALVAGE, SMELTING -> 0;
|
||||
case SWORDS -> expectedLvlSwords;
|
||||
case TAMING -> expectedLvlTaming;
|
||||
case TRIDENTS -> expectedLvlTridents;
|
||||
case UNARMED -> expectedLvlUnarmed;
|
||||
case WOODCUTTING -> expectedLvlWoodcutting;
|
||||
case MACES -> expectedLvlMaces;
|
||||
default ->
|
||||
throw new RuntimeException("Values for skill not defined, please add values for " + primarySkillType.toString() + " to the test");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOverwriteName() {
|
||||
overwriteDataAndCheckForFlag(db, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
|
||||
ArrayList<String[]> splitDataLines = getSplitDataFromFile(db.getUsersFile());
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
|
||||
ArrayList<String[]> splitDataLines = getSplitDataFromFile(flatFileDatabaseManager.getUsersFile());
|
||||
assertNotEquals(splitDataLines.get(1)[0], splitDataLines.get(0)[0]); //Name comparison
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDataNotFound() {
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
//Save the zero version and see if it looks correct
|
||||
assertNotNull(db);
|
||||
assertTrue(db.getUsersFile().exists());
|
||||
assertNotNull(db.getUsersFile());
|
||||
assertNotNull(flatFileDatabaseManager);
|
||||
assertTrue(flatFileDatabaseManager.getUsersFile().exists());
|
||||
assertNotNull(flatFileDatabaseManager.getUsersFile());
|
||||
|
||||
//Check for the "unloaded" profile
|
||||
PlayerProfile retrievedFromData = db.loadPlayerProfile("nossr50");
|
||||
PlayerProfile retrievedFromData = flatFileDatabaseManager.loadPlayerProfile("nossr50");
|
||||
assertFalse(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns false if data doesn't exist for the user
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPurgePowerlessUsers() {
|
||||
replaceDataInFile(db, normalDatabaseData);
|
||||
int purgeCount = db.purgePowerlessUsers();
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
replaceDataInFile(flatFileDatabaseManager, normalDatabaseData);
|
||||
int purgeCount = flatFileDatabaseManager.purgePowerlessUsers();
|
||||
assertEquals(purgeCount, 1); //1 User should have been purged
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckFileHealthAndStructure() {
|
||||
replaceDataInFile(db, badDatabaseData);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
replaceDataInFile(flatFileDatabaseManager, badDatabaseData);
|
||||
|
||||
List<FlatFileDataFlag> dataFlags = db.checkFileHealthAndStructure();
|
||||
List<FlatFileDataFlag> dataFlags = flatFileDatabaseManager.checkFileHealthAndStructure();
|
||||
assertNotNull(dataFlags);
|
||||
assertNotEquals(dataFlags.size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindFixableDuplicateNames() {
|
||||
overwriteDataAndCheckForFlag(db, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindDuplicateUUIDs() {
|
||||
overwriteDataAndCheckForFlag(db, duplicateUUIDDatabaseData, FlatFileDataFlag.DUPLICATE_UUID);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, duplicateUUIDDatabaseData, FlatFileDataFlag.DUPLICATE_UUID);
|
||||
}
|
||||
|
||||
@Test()
|
||||
void findBadUUIDData() {
|
||||
overwriteDataAndCheckForFlag(db, badUUIDDatabaseData, FlatFileDataFlag.BAD_UUID_DATA);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, badUUIDDatabaseData, FlatFileDataFlag.BAD_UUID_DATA);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindCorruptData() {
|
||||
overwriteDataAndCheckForFlag(db, corruptDatabaseData, FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, corruptDatabaseData, FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindEmptyNames() {
|
||||
overwriteDataAndCheckForFlag(db, emptyNameDatabaseData, FlatFileDataFlag.MISSING_NAME);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, emptyNameDatabaseData, FlatFileDataFlag.MISSING_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindBadValues() {
|
||||
overwriteDataAndCheckForFlag(db, badDatabaseData, FlatFileDataFlag.BAD_VALUES);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, badDatabaseData, FlatFileDataFlag.BAD_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindOutdatedData() {
|
||||
overwriteDataAndCheckForFlag(db, outdatedDatabaseData, FlatFileDataFlag.INCOMPLETE);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
overwriteDataAndCheckForFlag(flatFileDatabaseManager, outdatedDatabaseData, FlatFileDataFlag.INCOMPLETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDatabaseType() {
|
||||
assertNotNull(db);
|
||||
assertEquals(db.getDatabaseType(), DatabaseType.FLATFILE);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
assertNotNull(flatFileDatabaseManager);
|
||||
assertEquals(flatFileDatabaseManager.getDatabaseType(), DatabaseType.FLATFILE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadRank() {
|
||||
//This is an empty DB
|
||||
assertNotNull(db);
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
String rankBoyName = "rankBoy";
|
||||
UUID rankBoyUUID = new UUID(1337, 1337);
|
||||
String rankGirlName = "rankGirl";
|
||||
@ -658,9 +589,9 @@ class FlatFileDatabaseManagerTest {
|
||||
PlayerProfile rankGirlProfile = addPlayerProfileWithLevelsAndSave(rankGirlName, rankGirlUUID, 100); //Rank 1
|
||||
PlayerProfile rankBoyProfile = addPlayerProfileWithLevelsAndSave(rankBoyName, rankBoyUUID, 10); //Rank 2
|
||||
|
||||
assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
|
||||
Map<PrimarySkillType, Integer> rankGirlPositions = db.readRank(rankGirlName);
|
||||
Map<PrimarySkillType, Integer> rankBoyPositions = db.readRank(rankBoyName);
|
||||
assertEquals(LeaderboardStatus.UPDATED, flatFileDatabaseManager.updateLeaderboards());
|
||||
Map<PrimarySkillType, Integer> rankGirlPositions = flatFileDatabaseManager.readRank(rankGirlName);
|
||||
Map<PrimarySkillType, Integer> rankBoyPositions = flatFileDatabaseManager.readRank(rankBoyName);
|
||||
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(primarySkillType.isChildSkill()) {
|
||||
@ -672,8 +603,8 @@ class FlatFileDatabaseManagerTest {
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(1, db.readRank(rankGirlName).get(null)); //Girl should be position 1
|
||||
assertEquals(2, db.readRank(rankBoyName).get(null)); //Boy should be position 2
|
||||
assertEquals(1, flatFileDatabaseManager.readRank(rankGirlName).get(null)); //Girl should be position 1
|
||||
assertEquals(2, flatFileDatabaseManager.readRank(rankBoyName).get(null)); //Boy should be position 2
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -741,11 +672,11 @@ class FlatFileDatabaseManagerTest {
|
||||
}
|
||||
|
||||
private @NotNull PlayerProfile addPlayerProfileWithLevelsAndSave(String playerName, UUID uuid, int levels) {
|
||||
assertNotNull(db);
|
||||
assertFalse(db.loadPlayerProfile(uuid).isLoaded());
|
||||
FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
assertFalse(flatFileDatabaseManager.loadPlayerProfile(uuid).isLoaded());
|
||||
|
||||
db.newUser(playerName, uuid);
|
||||
PlayerProfile leveledProfile = db.loadPlayerProfile(uuid);
|
||||
flatFileDatabaseManager.newUser(playerName, uuid);
|
||||
PlayerProfile leveledProfile = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
|
||||
assertTrue(leveledProfile.isLoaded());
|
||||
assertEquals(playerName, leveledProfile.getPlayerName());
|
||||
@ -758,8 +689,8 @@ class FlatFileDatabaseManagerTest {
|
||||
leveledProfile.modifySkill(primarySkillType, levels); //TODO: This method also resets XP, not cool
|
||||
}
|
||||
|
||||
db.saveUser(leveledProfile);
|
||||
leveledProfile = db.loadPlayerProfile(uuid);
|
||||
flatFileDatabaseManager.saveUser(leveledProfile);
|
||||
leveledProfile = flatFileDatabaseManager.loadPlayerProfile(uuid);
|
||||
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(SkillTools.isChildSkill(primarySkillType)) {
|
||||
|
51
src/test/java/com/gmail/nossr50/util/PotionUtilTest.java
Normal file
51
src/test/java/com/gmail/nossr50/util/PotionUtilTest.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionUtil.convertLegacyNames;
|
||||
import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class PotionUtilTest {
|
||||
|
||||
@Test
|
||||
void testDisplay() {
|
||||
// System.out.println("\n");
|
||||
// System.out.println("\n");
|
||||
// System.out.println("\n");
|
||||
// System.out.println("\n");
|
||||
// for(var s : PotionType.values()) {
|
||||
// System.out.println("PotionType.getKey().getKey(): " + s.getKey().getKey());
|
||||
// System.out.println("PotionType.name(): " + s.name());
|
||||
// System.out.println("PotionType.toString():" + s.toString());
|
||||
// System.out.println("\n");
|
||||
// }
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMatchPotionType() {
|
||||
String potionTypeStr = "UNCRAFTABLE";
|
||||
PotionType potionType = matchPotionType(potionTypeStr, false, false);
|
||||
assertEquals(PotionType.WATER, potionType);
|
||||
|
||||
String potionTypeStr2 = "NIGHT_VISION";
|
||||
PotionType potionType2 = matchPotionType(potionTypeStr2, false, false);
|
||||
assertEquals(PotionType.NIGHT_VISION, potionType2);
|
||||
|
||||
String nightVisionLong = "NIGHT_VISION";
|
||||
PotionType potionType3 = matchPotionType(nightVisionLong, false, true);
|
||||
assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
|
||||
|
||||
nightVisionLong = "LONG_NIGHT_VISION";
|
||||
potionType3 = matchPotionType(nightVisionLong, false, true);
|
||||
assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvertLegacyNames() {
|
||||
final String potionTypeStr = "UNCRAFTABLE";
|
||||
final String converted = convertLegacyNames(potionTypeStr);
|
||||
assertEquals("WATER", converted);
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:140:14:150:15:1111:2222:3333:
|
||||
mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:3030:0:0:0:0:0:0:0:
|
||||
powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:4040:0:0:0:0:0:0:0:
|
||||
nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:140:14:150:15:1111:2222:3333:160:16:4444:
|
||||
mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:3030:0:0:0:0:0:0:0:0:0:0:
|
||||
powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:4040:0:0:0:0:0:0:0:0:0:0:
|
Loading…
Reference in New Issue
Block a user