Merge branch 'master' of github.com:mcMMO-Dev/mcMMO into configurable

This commit is contained in:
nossr50 2019-06-15 23:51:36 -07:00
commit fb08bbb79d
19 changed files with 138 additions and 61 deletions

View File

@ -169,6 +169,20 @@ Version 2.2.0
Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition
Added API method to check if a skill was being level capped Added API method to check if a skill was being level capped
Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill
Version 2.1.81
Fixed a bug where Arrow Deflect would never trigger outside of PVP
Fixed a bug where failing to salvage enchantments incorrectly colored the text
mcMMO no longer allows players to keep enchantments exceeding normal limitations by default when salvaging or repairing (you can turn this off in the config, see below)
Added new setting 'ExploitFix.UnsafeEnchantments' to experience.yml, turn this on to allow players to salvage/repair enchantments higher than normal game restrictions
NOTES:
If a player tries to salvage/repair an item with an illegal enchant (for example Sharpness X) it will downgrade that item to the highest legal version when calculating rewards
If you don't like this change you can turn it off in experience.yml under 'ExploitFix.UnsafeEnchantments'
Version 2.1.80
(Fix) mcMMO now respects the NBT "Unbreakable" tag and does not deal durability damage to items with that tag
Version 2.1.79 Version 2.1.79
Updated Japanese locale (Thanks snake0053) Updated Japanese locale (Thanks snake0053)
Fixed a NPE that could happen when using Tree Feller with an unenchanted Axe Fixed a NPE that could happen when using Tree Feller with an unenchanted Axe

View File

@ -5,7 +5,6 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.StringUtils;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -1,31 +0,0 @@
package com.gmail.nossr50.config.hocon.antiexploit;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ConfigSerializable
public class AntiExploit {
public static final boolean SPAWNED_MOBS_DEFAULT = true;
private static final boolean ENDERMEN_ENDERMITE_DEFAULT = true;
private static final boolean PISTONS_MARK_BLOCKS_DEFAULT = true;
/*
* CONFIG NODES
*/
@Setting(value = "Endermen-Endermite-Fix",
comment = "Removes XP from Endermen that target endermite, this is a common exploit in The End because of how rapidly they can spawn." +
"\nIt is recommended that you leave this on as it allows players to easily gain massive amounts of combat XP" +
"\nDefault value: " + ENDERMEN_ENDERMITE_DEFAULT)
private boolean endermenEndermiteFix = ENDERMEN_ENDERMITE_DEFAULT;
@Setting(value = "Pistons-Mark-Blocks-As-Unnatural",
comment = "Unnatural blocks give no XP." +
"This helps prevent complex automated stone farms that enable auto clickers to gain XP passively.")
private boolean pistonsMarkBlocksUnnatural = PISTONS_MARK_BLOCKS_DEFAULT;
@Setting(value = "Spawned-Mobs-Give-No-XP",
comment = "Spawned mobs will not give players combat XP." +
"\nThis includes mobs spawned from a nether portal, mob spawner, or eggs." +
"\nThis will not include mobs spawned from commands, typically.")
private boolean spawnedMobsGiveNoXP = SPAWNED_MOBS_DEFAULT;
}

View File

@ -103,4 +103,12 @@ public class ConfigExploitPrevention {
public boolean isPreventVehicleAutoFarming() { public boolean isPreventVehicleAutoFarming() {
return configSectionExploitSkills.isPreventVehicleAutoFarming(); return configSectionExploitSkills.isPreventVehicleAutoFarming();
} }
public ConfigSectionExploitRepair getConfigSectionExploitRepair() {
return configSectionExploitSkills.getConfigSectionExploitRepair();
}
public ConfigSectionExploitSalvage getConfigSectionExploitSalvage() {
return configSectionExploitSkills.getConfigSectionExploitSalvage();
}
} }

View File

@ -0,0 +1,20 @@
package com.gmail.nossr50.config.hocon.antiexploit;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ConfigSerializable
public class ConfigSectionExploitRepair {
private static final boolean ALLOW_UNSAFE_DEFAULT = false;
@Setting(value = "Allow-Illegal-Enchantments", comment = "If set to true, mcMMO will allow repair to keep illegal enchantments on equipment when repairing." +
"\nIf set to false, mcMMO will downgrade the enchantment to its native max level before calculating results." +
"\nAn illegal enchant is one that is not obtainable through normal gameplay without mods or cheats." +
"\nDefault value: "+ALLOW_UNSAFE_DEFAULT)
private boolean allowUnsafeEnchants = ALLOW_UNSAFE_DEFAULT;
public boolean isAllowUnsafeEnchants() {
return allowUnsafeEnchants;
}
}

View File

@ -0,0 +1,19 @@
package com.gmail.nossr50.config.hocon.antiexploit;
import ninja.leaping.configurate.objectmapping.Setting;
public class ConfigSectionExploitSalvage {
private static final boolean ALLOW_UNSAFE_DEFAULT = false;
@Setting(value = "Allow-Illegal-Enchantments", comment = "If set to true, mcMMO will allow salvage to create books with illegal enchants." +
"\nIf set to false, mcMMO will downgrade the enchantment to its native max level before calculating results." +
"\nAn illegal enchant is one that is not obtainable through normal gameplay without mods or cheats." +
"\nDefault value: "+ALLOW_UNSAFE_DEFAULT)
private boolean allowUnsafeEnchants = ALLOW_UNSAFE_DEFAULT;
public boolean isAllowUnsafeEnchants() {
return allowUnsafeEnchants;
}
}

View File

@ -17,6 +17,12 @@ public class ConfigSectionExploitSkills {
@Setting(value = "Herbalism", comment = "Exploit settings related to Herbalism.") @Setting(value = "Herbalism", comment = "Exploit settings related to Herbalism.")
private ConfigSectionExploitHerbalism configSectionExploitHerbalism = new ConfigSectionExploitHerbalism(); private ConfigSectionExploitHerbalism configSectionExploitHerbalism = new ConfigSectionExploitHerbalism();
@Setting(value = "Repair", comment = "Exploit settings related to Repair.")
private ConfigSectionExploitRepair configSectionExploitRepair = new ConfigSectionExploitRepair();
@Setting(value = "Salvage", comment = "Exploit settings related to Salvage")
private ConfigSectionExploitSalvage configSectionExploitSalvage = new ConfigSectionExploitSalvage();
public ConfigSectionExploitAcrobatics getConfigSectionExploitAcrobatics() { public ConfigSectionExploitAcrobatics getConfigSectionExploitAcrobatics() {
return configSectionExploitAcrobatics; return configSectionExploitAcrobatics;
} }
@ -76,4 +82,12 @@ public class ConfigSectionExploitSkills {
public boolean isPreventAcrobaticsAbuse() { public boolean isPreventAcrobaticsAbuse() {
return configSectionExploitAcrobatics.isPreventAcrobaticsAbuse(); return configSectionExploitAcrobatics.isPreventAcrobaticsAbuse();
} }
public ConfigSectionExploitRepair getConfigSectionExploitRepair() {
return configSectionExploitRepair;
}
public ConfigSectionExploitSalvage getConfigSectionExploitSalvage() {
return configSectionExploitSalvage;
}
} }

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.listeners; package com.gmail.nossr50.listeners;
import com.gmail.nossr50.config.MainConfig;
import com.gmail.nossr50.config.WorldBlacklist; import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.core.MetadataConstants; import com.gmail.nossr50.core.MetadataConstants;
import com.gmail.nossr50.datatypes.meta.BonusDropMeta; import com.gmail.nossr50.datatypes.meta.BonusDropMeta;

View File

@ -15,6 +15,7 @@ import com.gmail.nossr50.skills.mining.BlastMining;
import com.gmail.nossr50.skills.mining.MiningManager; import com.gmail.nossr50.skills.mining.MiningManager;
import com.gmail.nossr50.skills.taming.Taming; import com.gmail.nossr50.skills.taming.Taming;
import com.gmail.nossr50.skills.taming.TamingManager; import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.util.BlockUtils; import com.gmail.nossr50.util.BlockUtils;
import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
@ -325,7 +326,20 @@ public class EntityListener implements Listener {
if (projectileSource instanceof LivingEntity) { if (projectileSource instanceof LivingEntity) {
attacker = (LivingEntity) projectileSource; attacker = (LivingEntity) projectileSource;
} }
} else if (attacker instanceof Tameable) {
if(defender instanceof Player) {
Player playerDefender = (Player) defender;
UnarmedManager unarmedManager = UserManager.getPlayer(playerDefender).getUnarmedManager();
if (unarmedManager.canDeflect()) {
if(unarmedManager.deflectCheck()) {
event.setCancelled(true);
return;
}
}
}
}
else if (attacker instanceof Tameable) {
AnimalTamer animalTamer = ((Tameable) attacker).getOwner(); AnimalTamer animalTamer = ((Tameable) attacker).getOwner();
if (animalTamer != null && ((OfflinePlayer) animalTamer).isOnline()) { if (animalTamer != null && ((OfflinePlayer) animalTamer).isOnline()) {

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.listeners; package com.gmail.nossr50.listeners;
import com.gmail.nossr50.config.MainConfig;
import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;

View File

@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.mining; package com.gmail.nossr50.skills.mining;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.MainConfig;
import com.gmail.nossr50.core.MetadataConstants; import com.gmail.nossr50.core.MetadataConstants;
import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.interactions.NotificationType;

View File

@ -328,10 +328,19 @@ public class RepairManager extends SkillManager {
boolean downgraded = false; boolean downgraded = false;
for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) { for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
int enchantLevel = enchant.getValue();
if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitRepair().isAllowUnsafeEnchants()) {
if(enchantLevel > enchant.getKey().getMaxLevel()) {
enchantLevel = enchant.getKey().getMaxLevel();
item.addEnchantment(enchant.getKey(), enchantLevel);
}
}
Enchantment enchantment = enchant.getKey(); Enchantment enchantment = enchant.getKey();
if (RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getKeepEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING))) { if (RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getKeepEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING))) {
int enchantLevel = enchant.getValue();
if (mcMMO.getConfigManager().getConfigRepair().getArcaneForging().isDowngradesEnabled() && enchantLevel > 1 if (mcMMO.getConfigManager().getConfigRepair().getArcaneForging().isDowngradesEnabled() && enchantLevel > 1
&& (!RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(100 - getDowngradeEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING)))) { && (!RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(100 - getDowngradeEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING)))) {
@ -346,11 +355,13 @@ public class RepairManager extends SkillManager {
Map<Enchantment, Integer> newEnchants = item.getEnchantments(); Map<Enchantment, Integer> newEnchants = item.getEnchantments();
if (newEnchants.isEmpty()) { if (newEnchants.isEmpty()) {
mcMMO.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Repair.Arcane.Fail"); mcMMO.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Repair.Arcane.Fail");
} else if (downgraded || newEnchants.size() < enchants.size()) { }
mcMMO.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Repair.Arcane.Downgrade"); else if (downgraded || newEnchants.size() < enchants.size()) {
} else { mcMMO.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Repair.Arcane.Downgrade");
mcMMO.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Repair.Arcane.Perfect"); }
else {
mcMMO.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Repair.Arcane.Perfect");
} }
} }

View File

@ -211,7 +211,7 @@ public class SalvageManager extends SkillManager {
Player player = getPlayer(); Player player = getPlayer();
if (!RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE) || !Permissions.arcaneSalvage(player)) { if (!RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE) || !Permissions.arcaneSalvage(player)) {
mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcaneFailed"); mcMMO.getNotificationManager().sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcaneFailed");
return null; return null;
} }
@ -222,25 +222,38 @@ public class SalvageManager extends SkillManager {
int arcaneFailureCount = 0; int arcaneFailureCount = 0;
for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) { for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
int enchantLevel = enchant.getValue();
if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitSkills().getConfigSectionExploitSalvage().isAllowUnsafeEnchants()) {
if(enchantLevel > enchant.getKey().getMaxLevel()) {
enchantLevel = enchant.getKey().getMaxLevel();
}
}
if (!Salvage.arcaneSalvageEnchantLoss if (!Salvage.arcaneSalvageEnchantLoss
|| Permissions.hasSalvageEnchantBypassPerk(player) || Permissions.hasSalvageEnchantBypassPerk(player)
|| RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) { || RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
enchantMeta.addStoredEnchant(enchant.getKey(), enchant.getValue(), true);
} else if (enchant.getValue() > 1 enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel, true);
}
else if (enchantLevel > 1
&& Salvage.arcaneSalvageDowngrades && Salvage.arcaneSalvageDowngrades
&& RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) { && RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
enchantMeta.addStoredEnchant(enchant.getKey(), enchant.getValue() - 1, true); enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel - 1, true);
downgraded = true; downgraded = true;
} else { } else {
arcaneFailureCount++; arcaneFailureCount++;
} }
} }
if (failedAllEnchants(arcaneFailureCount, enchants.entrySet().size())) { if(failedAllEnchants(arcaneFailureCount, enchants.entrySet().size()))
mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcaneFailed"); {
mcMMO.getNotificationManager().sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcaneFailed");
return null; return null;
} else if (downgraded) { } else if(downgraded)
mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcanePartial"); {
mcMMO.getNotificationManager().sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcanePartial");
} }
book.setItemMeta(enchantMeta); book.setItemMeta(enchantMeta);

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.skills.unarmed; package com.gmail.nossr50.skills.unarmed;
import com.gmail.nossr50.config.MainConfig;
import com.gmail.nossr50.util.sounds.SoundManager; import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType; import com.gmail.nossr50.util.sounds.SoundType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.skills.woodcutting; package com.gmail.nossr50.skills.woodcutting;
import com.gmail.nossr50.config.MainConfig;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.BlockUtils; import com.gmail.nossr50.util.BlockUtils;
import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Misc;
@ -138,8 +137,8 @@ public final class Woodcutting {
*/ */
protected static boolean handleDurabilityLoss(Set<BlockState> treeFellerBlocks, ItemStack inHand) { protected static boolean handleDurabilityLoss(Set<BlockState> treeFellerBlocks, ItemStack inHand) {
if(inHand.getItemMeta().getEnchants().get(Enchantment.DURABILITY) != null if((inHand.getItemMeta().getEnchants().get(Enchantment.DURABILITY) != null && inHand.getItemMeta().getEnchants().get(Enchantment.DURABILITY) >= 1)
&& inHand.getItemMeta().getEnchants().get(Enchantment.DURABILITY) >= 1) { || (inHand.getItemMeta() != null && inHand.getItemMeta().isUnbreakable())) {
return true; return true;
} }

View File

@ -59,8 +59,7 @@ public class NotificationManager {
/** /**
* Sends players notifications from mcMMO * Sends players notifications from mcMMO
* This does this by sending out an event so other plugins can cancel it * Does so by sending out an event so other plugins can cancel it
*
* @param player target player * @param player target player
* @param notificationType notifications defined type * @param notificationType notifications defined type
* @param key the locale key for the notifications defined message * @param key the locale key for the notifications defined message

View File

@ -27,7 +27,7 @@ public class RandomChanceUtil {
* @param skillActivationType this value represents what kind of activation procedures this sub-skill uses * @param skillActivationType this value represents what kind of activation procedures this sub-skill uses
* @param subSkillType The identifier for this specific sub-skill * @param subSkillType The identifier for this specific sub-skill
* @param player The owner of this sub-skill * @param player The owner of this sub-skill
* @return returns true if all conditions are met and they event is not cancelled * @return returns true if all conditions are met and the event is not cancelled
*/ */
public static boolean isActivationSuccessful(SkillActivationType skillActivationType, SubSkillType subSkillType, Player player) { public static boolean isActivationSuccessful(SkillActivationType skillActivationType, SubSkillType subSkillType, Player player) {
switch (skillActivationType) { switch (skillActivationType) {

View File

@ -227,7 +227,8 @@ public class SkillUtils {
* @param maxDamageModifier the amount to adjust the max damage by * @param maxDamageModifier the amount to adjust the max damage by
*/ */
public static void handleDurabilityChange(ItemStack itemStack, double durabilityModifier, double maxDamageModifier) { public static void handleDurabilityChange(ItemStack itemStack, double durabilityModifier, double maxDamageModifier) {
if (itemStack.getEnchantments().get(Enchantment.DURABILITY) != null && itemStack.getEnchantments().get(Enchantment.DURABILITY) >= 1) { if((itemStack.getItemMeta().getEnchants().get(Enchantment.DURABILITY) != null && itemStack.getItemMeta().getEnchants().get(Enchantment.DURABILITY) >= 1)
|| (itemStack.getItemMeta() != null && itemStack.getItemMeta().isUnbreakable())) {
return; return;
} }

View File

@ -26,6 +26,7 @@ EarlyGameBoost:
#Used to determine the cap of the max boot, with default level cap it will be 5 on standard, and 50 on retro #Used to determine the cap of the max boot, with default level cap it will be 5 on standard, and 50 on retro
MaxLevelMultiplier: 0.05 MaxLevelMultiplier: 0.05
ExploitFix: ExploitFix:
UnsafeEnchantments: false
# Prevent many exploits related to fishing # Prevent many exploits related to fishing
Fishing: true Fishing: true
EndermanEndermiteFarms: true EndermanEndermiteFarms: true