mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-24 22:26:46 +01:00
Merge branch 'master' of github.com:mcMMO-Dev/mcMMO into tridentsxbows
This commit is contained in:
commit
a2a41e77ea
@ -91,6 +91,28 @@ Version 2.2.000
|
|||||||
Parties got unnecessarily complex in my absence, I have removed many party features in order to simplify parties and bring them closer to my vision. I have also added new features which should improve parties where it matters.
|
Parties got unnecessarily complex in my absence, I have removed many party features in order to simplify parties and bring them closer to my vision. I have also added new features which should improve parties where it matters.
|
||||||
About the removed party features, all the features I removed I consider poor quality features and I don't think they belong in mcMMO. Feel free to yell at me in discord if you disagree.
|
About the removed party features, all the features I removed I consider poor quality features and I don't think they belong in mcMMO. Feel free to yell at me in discord if you disagree.
|
||||||
I don't know what genius decided to make parties public by default, when I found out that parties had been changed to such a system I could barely contain my disgust. Parties are back to being private, you get invited by a party leader or party officer. That is the only way to join a party.
|
I don't know what genius decided to make parties public by default, when I found out that parties had been changed to such a system I could barely contain my disgust. Parties are back to being private, you get invited by a party leader or party officer. That is the only way to join a party.
|
||||||
|
Version 2.1.160
|
||||||
|
Fixed another 9+ year old exploit
|
||||||
|
Silenced a harmless "error" related to Rupture/Bleed often produced when using mcMMO and crazy enchantments together
|
||||||
|
|
||||||
|
Version 2.1.159
|
||||||
|
Fixed a memory leak involving renamed mobs
|
||||||
|
Updated Adventure library (used in our chat code)
|
||||||
|
|
||||||
|
Version 2.1.158
|
||||||
|
Fixed a bug where Lure level 4 and above would break fishing with the new Master Angler
|
||||||
|
URLs in party/admin chat work again (use https:// in front to make links clickable)
|
||||||
|
Updated nl locale (thanks xl3ehindTim)
|
||||||
|
* Added Crossbow to string repairables (Thanks Momshroom)
|
||||||
|
* Added Shield to wood repairables, with oak planks as material (Thanks Momshroom)
|
||||||
|
* Added Elytra and Trident to Other repairables, using phantom membrane and prismarine crystals respectively. (Thanks Momshroom)
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
* You'll need to update repair.vanilla.yml yourself or delete the file and regenerate it (lazy easy way).
|
||||||
|
Links in party/admin chat might not be clickable without https:// added in front of the url
|
||||||
|
Added some stuff to Repair, a rework to Repair is coming in the future, this stuff will work for now as a placeholder.
|
||||||
|
Master Angler will emulate the effects of Lure if the level is higher than 3 instead of attempting to stack with it to avoid a vanilla Minecraft bug where fish are never caught
|
||||||
|
|
||||||
Version 2.1.157
|
Version 2.1.157
|
||||||
Fixed a NPE that prevented mctop (Leaderboards) from working
|
Fixed a NPE that prevented mctop (Leaderboards) from working
|
||||||
|
|
||||||
|
6
pom.xml
6
pom.xml
@ -214,12 +214,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-text-serializer-gson</artifactId>
|
<artifactId>adventure-text-serializer-gson</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.3.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-api</artifactId>
|
<artifactId>adventure-api</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
@ -244,7 +244,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.scm</groupId>
|
<groupId>org.apache.maven.scm</groupId>
|
||||||
<artifactId>maven-scm-provider-gitexe</artifactId>
|
<artifactId>maven-scm-provider-gitexe</artifactId>
|
||||||
<version>1.8.1</version>
|
<version>1.9.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bstats</groupId>
|
<groupId>org.bstats</groupId>
|
||||||
|
@ -92,7 +92,7 @@ public class FishingCommand extends SkillCommand {
|
|||||||
// MASTER ANGLER
|
// MASTER ANGLER
|
||||||
if (canMasterAngler) {
|
if (canMasterAngler) {
|
||||||
maMinWaitTime = StringUtils.ticksToSeconds(fishingManager.getMasterAnglerTickMinWaitReduction(RankUtils.getRank(mmoPlayer, SubSkillType.FISHING_MASTER_ANGLER), false));
|
maMinWaitTime = StringUtils.ticksToSeconds(fishingManager.getMasterAnglerTickMinWaitReduction(RankUtils.getRank(mmoPlayer, SubSkillType.FISHING_MASTER_ANGLER), false));
|
||||||
maMaxWaitTime = StringUtils.ticksToSeconds(fishingManager.getMasterAnglerTickMaxWaitReduction(RankUtils.getRank(mmoPlayer, SubSkillType.FISHING_MASTER_ANGLER), false));
|
maMaxWaitTime = StringUtils.ticksToSeconds(fishingManager.getMasterAnglerTickMaxWaitReduction(RankUtils.getRank(mmoPlayer, SubSkillType.FISHING_MASTER_ANGLER), false, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ public class BlockListener implements Listener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor blocks formed by entities (snowmen)
|
* Monitor blocks formed by entities (snowmen)
|
||||||
|
* Does not seem to monitor stuff like a falling block creating a new block
|
||||||
*
|
*
|
||||||
* @param event The event to watch
|
* @param event The event to watch
|
||||||
*/
|
*/
|
||||||
@ -175,6 +176,9 @@ public class BlockListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does not monitor stuff like a falling block replacing a liquid
|
||||||
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockFormEvent(BlockFormEvent event)
|
public void onBlockFormEvent(BlockFormEvent event)
|
||||||
{
|
{
|
||||||
@ -182,12 +186,12 @@ public class BlockListener implements Listener {
|
|||||||
if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
|
if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ExperienceConfig.getInstance().preventStoneLavaFarming())
|
BlockState newState = event.getNewState();
|
||||||
{
|
|
||||||
if(event.getNewState().getType() != Material.OBSIDIAN
|
if(ExperienceConfig.getInstance().preventStoneLavaFarming()) {
|
||||||
&& ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.MINING, event.getNewState().getBlockData()))
|
if(newState.getType() != Material.OBSIDIAN
|
||||||
{
|
&& ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.MINING, newState.getBlockData())) {
|
||||||
mcMMO.getPlaceStore().setTrue(event.getNewState());
|
mcMMO.getPlaceStore().setTrue(newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,17 +247,6 @@ public class BlockListener implements Listener {
|
|||||||
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
|
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
|
||||||
mcMMO.getPlaceStore().setTrue(blockState);
|
mcMMO.getPlaceStore().setTrue(blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /* WORLD BLACKLIST CHECK */
|
|
||||||
// if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld())) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Player player = event.getPlayer();
|
|
||||||
//
|
|
||||||
// if (!UserManager.hasPlayerDataKey(player)) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
@ -264,11 +257,6 @@ public class BlockListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
BlockState blockState = event.getBlock().getState();
|
BlockState blockState = event.getBlock().getState();
|
||||||
|
|
||||||
// if (!BlockUtils.shouldBeWatched(blockState)) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
mcMMO.getPlaceStore().setFalse(blockState);
|
mcMMO.getPlaceStore().setFalse(blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,18 +241,24 @@ public class EntityListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Block block = event.getBlock();
|
Block block = event.getBlock();
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
Material notYetReplacedType = block.getState().getType(); //because its from getState() this is the block that hasn't been changed yet, which is likely air/lava/water etc
|
||||||
|
|
||||||
|
|
||||||
// When the event is fired for the falling block that changes back to a
|
// When the event is fired for the falling block that changes back to a
|
||||||
// normal block
|
// normal block
|
||||||
// event.getBlock().getType() returns AIR
|
// event.getBlock().getType() returns AIR
|
||||||
if (!BlockUtils.shouldBeWatched(block.getState())
|
if (!BlockUtils.shouldBeWatched(block.getState())
|
||||||
&& block.getState().getType() != Material.WATER
|
&& notYetReplacedType != Material.WATER && notYetReplacedType != Material.LAVA
|
||||||
&& block.getType() != Material.AIR) {
|
&& block.getType() != Material.AIR && block.getType() != Material.CAVE_AIR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//I could just have it mark all blocks after this but it would potentially cause some really edge case consistency issues that no one would notice
|
||||||
|
|
||||||
Entity entity = event.getEntity();
|
/*
|
||||||
|
* This mess of code tries to avoid marking the moved block as true in our place store
|
||||||
|
* It's a headache to read but it works, I'm tempted to just remove it
|
||||||
|
*/
|
||||||
if (entity instanceof FallingBlock || entity instanceof Enderman) {
|
if (entity instanceof FallingBlock || entity instanceof Enderman) {
|
||||||
boolean isTracked = entity.hasMetadata(mcMMO.travelingBlock);
|
boolean isTracked = entity.hasMetadata(mcMMO.travelingBlock);
|
||||||
|
|
||||||
@ -273,63 +279,6 @@ public class EntityListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Monitor EntityChangeBlock events.
|
|
||||||
// *
|
|
||||||
// * @param event
|
|
||||||
// * The event to watch
|
|
||||||
// */
|
|
||||||
// @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
// public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
|
||||||
// /* WORLD BLACKLIST CHECK */
|
|
||||||
// if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// Block block = event.getBlock();
|
|
||||||
//
|
|
||||||
// // When the event is fired for the falling block that changes back to a
|
|
||||||
// // normal block
|
|
||||||
// // event.getBlock().getType() returns AIR
|
|
||||||
// if (!BlockUtils.shouldBeWatched(block.getState())
|
|
||||||
// && block.getState().getType() != Material.WATER
|
|
||||||
// && block.getType() != Material.AIR) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Entity entity = event.getEntity();
|
|
||||||
//
|
|
||||||
// if (entity instanceof FallingBlock || entity instanceof Enderman) {
|
|
||||||
// trackMovingBlocks(block, entity); //ignore the IDE warning
|
|
||||||
// //Apparently redstone ore will throw these events
|
|
||||||
// } else if ((block.getType() != Material.REDSTONE_ORE)) {
|
|
||||||
// if (mcMMO.getPlaceStore().isTrue(block)) {
|
|
||||||
// mcMMO.getPlaceStore().setFalse(block);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * This is a complex hack to track blocks for this event
|
|
||||||
// * This event is called when a block starts its movement, or ends its movement
|
|
||||||
// * It can start the movement through physics (falling blocks) or through being picked up (endermen)
|
|
||||||
// * Since this event can be cancelled, its even weirder to track this stuff
|
|
||||||
// * @param block this will either be the block that was originally picked up, or the block in its final destination
|
|
||||||
// * @param movementSourceEntity this will either be an Endermen or a Falling Block
|
|
||||||
// */
|
|
||||||
// private void trackMovingBlocks(@NotNull Block block, @NotNull Entity movementSourceEntity) {
|
|
||||||
//
|
|
||||||
// //A block that has reached its destination, either being placed by endermen or having finished its fall
|
|
||||||
// if(movementSourceEntity.hasMetadata(mcMMO.travelingBlock)) {
|
|
||||||
// mcMMO.getPlaceStore().setTrue(block);
|
|
||||||
// movementSourceEntity.removeMetadata(mcMMO.travelingBlock, pluginRef);
|
|
||||||
// } else {
|
|
||||||
// //A block that is starting movement (from either Endermen or Falling/Physics)
|
|
||||||
// if(mcMMO.getPlaceStore().isTrue(block)) {
|
|
||||||
// mcMMO.getPlaceStore().setFalse(block);
|
|
||||||
// movementSourceEntity.setMetadata(mcMMO.blockMetadataKey, mcMMO.metadataValue);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onEntityCombustByEntityEvent(EntityCombustByEntityEvent event) {
|
public void onEntityCombustByEntityEvent(EntityCombustByEntityEvent event) {
|
||||||
|
@ -28,6 +28,8 @@ import com.gmail.nossr50.worldguard.WorldGuardUtils;
|
|||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.*;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.entity.minecart.PoweredMinecart;
|
import org.bukkit.entity.minecart.PoweredMinecart;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
@ -380,7 +382,21 @@ public class PlayerListener implements Listener {
|
|||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case FISHING:
|
case FISHING:
|
||||||
if (fishingManager.canMasterAngler()) {
|
if (fishingManager.canMasterAngler()) {
|
||||||
fishingManager.masterAngler(event.getHook());
|
int lureLevel = 0;
|
||||||
|
ItemStack inHand = player.getInventory().getItemInMainHand();
|
||||||
|
|
||||||
|
//Grab lure level
|
||||||
|
if(inHand != null && inHand.getType().getKey().getKey().equalsIgnoreCase("fishing_rod")) {
|
||||||
|
if(inHand.getItemMeta().hasEnchants()) {
|
||||||
|
for(Enchantment enchantment : inHand.getItemMeta().getEnchants().keySet()) {
|
||||||
|
if(enchantment.toString().toLowerCase().contains("lure")) {
|
||||||
|
lureLevel = inHand.getEnchantmentLevel(enchantment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fishingManager.masterAngler(event.getHook(), lureLevel);
|
||||||
fishingManager.setFishingTarget();
|
fishingManager.setFishingTarget();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -16,6 +16,7 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -23,7 +24,7 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
public class BleedTimerTask extends BukkitRunnable {
|
public class BleedTimerTask extends BukkitRunnable {
|
||||||
private static final Map<LivingEntity, BleedContainer> bleedList = new HashMap<>();
|
private static final @NotNull Map<LivingEntity, BleedContainer> bleedList = new HashMap<>();
|
||||||
private static boolean isIterating = false;
|
private static boolean isIterating = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -148,7 +149,7 @@ public class BleedTimerTask extends BukkitRunnable {
|
|||||||
isIterating = false;
|
isIterating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BleedContainer copyContainer(BleedContainer container)
|
public static @NotNull BleedContainer copyContainer(@NotNull BleedContainer container)
|
||||||
{
|
{
|
||||||
LivingEntity target = container.target;
|
LivingEntity target = container.target;
|
||||||
LivingEntity source = container.damageSource;
|
LivingEntity source = container.damageSource;
|
||||||
@ -164,7 +165,7 @@ public class BleedTimerTask extends BukkitRunnable {
|
|||||||
*
|
*
|
||||||
* @param entity LivingEntity to bleed out
|
* @param entity LivingEntity to bleed out
|
||||||
*/
|
*/
|
||||||
public static void bleedOut(LivingEntity entity) {
|
public static void bleedOut(@NotNull LivingEntity entity) {
|
||||||
/*
|
/*
|
||||||
* Don't remove anything from the list outside of run()
|
* Don't remove anything from the list outside of run()
|
||||||
*/
|
*/
|
||||||
@ -178,26 +179,36 @@ public class BleedTimerTask extends BukkitRunnable {
|
|||||||
* Add a LivingEntity to the bleedList if it is not in it.
|
* Add a LivingEntity to the bleedList if it is not in it.
|
||||||
*
|
*
|
||||||
* @param entity LivingEntity to add
|
* @param entity LivingEntity to add
|
||||||
|
* @param attacker source of the bleed/rupture
|
||||||
* @param ticks Number of bleeding ticks
|
* @param ticks Number of bleeding ticks
|
||||||
*/
|
*/
|
||||||
public static void add(LivingEntity entity, LivingEntity attacker, int ticks, int bleedRank, int toolTier) {
|
public static void add(@NotNull LivingEntity entity, @NotNull LivingEntity attacker, int ticks, int bleedRank, int toolTier) {
|
||||||
if (!Bukkit.isPrimaryThread()) {
|
if (!Bukkit.isPrimaryThread()) {
|
||||||
throw new IllegalStateException("Cannot add bleed task async!");
|
throw new IllegalStateException("Cannot add bleed task async!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isIterating) throw new IllegalStateException("Cannot add task while iterating timers!");
|
if(isIterating) {
|
||||||
|
//Used to throw an error here, but in reality all we are really doing is preventing concurrency issues from other plugins being naughty and its not really needed
|
||||||
|
//I'm not really a fan of silent errors, but I'm sick of seeing people using crazy enchantments come in and report this "bug"
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (isIterating) throw new IllegalStateException("Cannot add task while iterating timers!");
|
||||||
|
|
||||||
if(toolTier < 4)
|
if(toolTier < 4)
|
||||||
ticks = Math.max(1, (ticks / 3));
|
ticks = Math.max(1, (ticks / 3));
|
||||||
|
|
||||||
ticks+=1;
|
ticks+=1;
|
||||||
|
|
||||||
|
|
||||||
BleedContainer newBleedContainer = new BleedContainer(entity, ticks, bleedRank, toolTier, attacker);
|
BleedContainer newBleedContainer = new BleedContainer(entity, ticks, bleedRank, toolTier, attacker);
|
||||||
bleedList.put(entity, newBleedContainer);
|
bleedList.put(entity, newBleedContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBleeding(LivingEntity entity) {
|
public static boolean isBleedOperationAllowed() {
|
||||||
|
return !isIterating && Bukkit.isPrimaryThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBleeding(@NotNull LivingEntity entity) {
|
||||||
return bleedList.containsKey(entity);
|
return bleedList.containsKey(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,16 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public class MasterAnglerTask extends BukkitRunnable {
|
public class MasterAnglerTask extends BukkitRunnable {
|
||||||
private final @NotNull FishHook fishHook;
|
private final @NotNull FishHook fishHook;
|
||||||
private final @NotNull FishingManager fishingManager;
|
private final @NotNull FishingManager fishingManager;
|
||||||
|
private final int lureLevel;
|
||||||
|
|
||||||
public MasterAnglerTask(@NotNull FishHook fishHook, @NotNull FishingManager fishingManager) {
|
public MasterAnglerTask(@NotNull FishHook fishHook, @NotNull FishingManager fishingManager, int lureLevel) {
|
||||||
this.fishHook = fishHook;
|
this.fishHook = fishHook;
|
||||||
this.fishingManager = fishingManager;
|
this.fishingManager = fishingManager;
|
||||||
|
this.lureLevel = lureLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fishingManager.processMasterAngler(fishHook);
|
fishingManager.processMasterAngler(fishHook, lureLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,8 +247,8 @@ public class FishingManager extends SkillManager {
|
|||||||
EventUtils.callFakeFishEvent(getPlayer(), hook);
|
EventUtils.callFakeFishEvent(getPlayer(), hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void masterAngler(@NotNull FishHook hook) {
|
public void masterAngler(@NotNull FishHook hook, int lureLevel) {
|
||||||
new MasterAnglerTask(hook, this).runTaskLater(mcMMO.p, 0); //We run later to get the lure bonus applied
|
new MasterAnglerTask(hook, this, lureLevel).runTaskLater(mcMMO.p, 0); //We run later to get the lure bonus applied
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,7 +256,7 @@ public class FishingManager extends SkillManager {
|
|||||||
* Reduced tick time on fish hook, etc
|
* Reduced tick time on fish hook, etc
|
||||||
* @param fishHook target fish hook
|
* @param fishHook target fish hook
|
||||||
*/
|
*/
|
||||||
public void processMasterAngler(@NotNull FishHook fishHook) {
|
public void processMasterAngler(@NotNull FishHook fishHook, int lureLevel) {
|
||||||
MasterAnglerCompatibilityLayer masterAnglerCompatibilityLayer = (MasterAnglerCompatibilityLayer) mcMMO.getCompatibilityManager().getMasterAnglerCompatibilityLayer();
|
MasterAnglerCompatibilityLayer masterAnglerCompatibilityLayer = (MasterAnglerCompatibilityLayer) mcMMO.getCompatibilityManager().getMasterAnglerCompatibilityLayer();
|
||||||
|
|
||||||
if(masterAnglerCompatibilityLayer != null) {
|
if(masterAnglerCompatibilityLayer != null) {
|
||||||
@ -264,10 +264,17 @@ public class FishingManager extends SkillManager {
|
|||||||
int minWaitTicks = masterAnglerCompatibilityLayer.getMinWaitTime(fishHook);
|
int minWaitTicks = masterAnglerCompatibilityLayer.getMinWaitTime(fishHook);
|
||||||
|
|
||||||
int masterAnglerRank = RankUtils.getRank(mmoPlayer, SubSkillType.FISHING_MASTER_ANGLER);
|
int masterAnglerRank = RankUtils.getRank(mmoPlayer, SubSkillType.FISHING_MASTER_ANGLER);
|
||||||
|
int convertedLureBonus = 0;
|
||||||
|
|
||||||
|
//This avoids a Minecraft bug where lure levels above 3 break fishing
|
||||||
|
if(lureLevel > 3) {
|
||||||
|
masterAnglerCompatibilityLayer.setApplyLure(fishHook, false);
|
||||||
|
convertedLureBonus = lureLevel * 100;
|
||||||
|
}
|
||||||
|
|
||||||
boolean boatBonus = isInBoat();
|
boolean boatBonus = isInBoat();
|
||||||
int minWaitReduction = getMasterAnglerTickMinWaitReduction(masterAnglerRank, boatBonus);
|
int minWaitReduction = getMasterAnglerTickMinWaitReduction(masterAnglerRank, boatBonus);
|
||||||
int maxWaitReduction = getMasterAnglerTickMaxWaitReduction(masterAnglerRank, boatBonus);
|
int maxWaitReduction = getMasterAnglerTickMaxWaitReduction(masterAnglerRank, boatBonus, convertedLureBonus);
|
||||||
|
|
||||||
//Ticks for minWait and maxWait never go below this value
|
//Ticks for minWait and maxWait never go below this value
|
||||||
int bonusCapMin = AdvancedConfig.getInstance().getFishingReductionMinWaitCap();
|
int bonusCapMin = AdvancedConfig.getInstance().getFishingReductionMinWaitCap();
|
||||||
@ -276,9 +283,21 @@ public class FishingManager extends SkillManager {
|
|||||||
int reducedMinWaitTime = getReducedTicks(minWaitTicks, minWaitReduction, bonusCapMin);
|
int reducedMinWaitTime = getReducedTicks(minWaitTicks, minWaitReduction, bonusCapMin);
|
||||||
int reducedMaxWaitTime = getReducedTicks(maxWaitTicks, maxWaitReduction, bonusCapMax);
|
int reducedMaxWaitTime = getReducedTicks(maxWaitTicks, maxWaitReduction, bonusCapMax);
|
||||||
|
|
||||||
|
boolean badValuesFix = false;
|
||||||
|
|
||||||
|
//If we find bad values correct it
|
||||||
|
if(reducedMaxWaitTime < reducedMinWaitTime) {
|
||||||
|
reducedMaxWaitTime = reducedMinWaitTime + 100;
|
||||||
|
badValuesFix = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(mmoPlayer.isDebugMode()) {
|
if(mmoPlayer.isDebugMode()) {
|
||||||
mmoPlayer.getPlayer().sendMessage(ChatColor.GOLD + "Master Angler Debug");
|
mmoPlayer.getPlayer().sendMessage(ChatColor.GOLD + "Master Angler Debug");
|
||||||
|
|
||||||
|
if(badValuesFix) {
|
||||||
|
mmoPlayer.getPlayer().sendMessage(ChatColor.RED + "Bad values were applied and corrected, check your configs, max wait should never be lower than min wait.");
|
||||||
|
}
|
||||||
|
|
||||||
mmoPlayer.getPlayer().sendMessage("ALLOW STACK WITH LURE: " + masterAnglerCompatibilityLayer.getApplyLure(fishHook));
|
mmoPlayer.getPlayer().sendMessage("ALLOW STACK WITH LURE: " + masterAnglerCompatibilityLayer.getApplyLure(fishHook));
|
||||||
mmoPlayer.getPlayer().sendMessage("MIN TICK REDUCTION: " + minWaitReduction);
|
mmoPlayer.getPlayer().sendMessage("MIN TICK REDUCTION: " + minWaitReduction);
|
||||||
mmoPlayer.getPlayer().sendMessage("MAX TICK REDUCTION: " + maxWaitReduction);
|
mmoPlayer.getPlayer().sendMessage("MAX TICK REDUCTION: " + maxWaitReduction);
|
||||||
@ -321,13 +340,15 @@ public class FishingManager extends SkillManager {
|
|||||||
return mmoPlayer.getPlayer().isInsideVehicle() && mmoPlayer.getPlayer().getVehicle() instanceof Boat;
|
return mmoPlayer.getPlayer().isInsideVehicle() && mmoPlayer.getPlayer().getVehicle() instanceof Boat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMasterAnglerTickMaxWaitReduction(int masterAnglerRank, boolean boatBonus) {
|
public int getMasterAnglerTickMaxWaitReduction(int masterAnglerRank, boolean boatBonus, int emulatedLureBonus) {
|
||||||
int totalBonus = AdvancedConfig.getInstance().getFishingReductionMaxWaitTicks() * masterAnglerRank;
|
int totalBonus = AdvancedConfig.getInstance().getFishingReductionMaxWaitTicks() * masterAnglerRank;
|
||||||
|
|
||||||
if(boatBonus) {
|
if(boatBonus) {
|
||||||
totalBonus += getFishingBoatMaxWaitReduction();
|
totalBonus += getFishingBoatMaxWaitReduction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalBonus += emulatedLureBonus;
|
||||||
|
|
||||||
return totalBonus;
|
return totalBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import org.bukkit.entity.LivingEntity;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -59,26 +60,28 @@ public class SwordsManager extends SkillManager {
|
|||||||
*
|
*
|
||||||
* @param target The defending entity
|
* @param target The defending entity
|
||||||
*/
|
*/
|
||||||
public void ruptureCheck(LivingEntity target) {
|
public void ruptureCheck(@NotNull LivingEntity target) throws IllegalStateException {
|
||||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.SWORDS_RUPTURE, getPlayer(), this.mmoPlayer.getAttackStrength())) {
|
if(BleedTimerTask.isBleedOperationAllowed()) {
|
||||||
|
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.SWORDS_RUPTURE, getPlayer(), this.mmoPlayer.getAttackStrength())) {
|
||||||
|
|
||||||
if (target instanceof Player) {
|
if (target instanceof Player) {
|
||||||
Player defender = (Player) target;
|
Player defender = (Player) target;
|
||||||
|
|
||||||
//Don't start or add to a bleed if they are blocking
|
//Don't start or add to a bleed if they are blocking
|
||||||
if(defender.isBlocking())
|
if(defender.isBlocking())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||||
if(!BleedTimerTask.isBleeding(defender))
|
if(!BleedTimerTask.isBleeding(defender))
|
||||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Started");
|
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Started");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
BleedTimerTask.add(target, getPlayer(), getRuptureBleedTicks(), RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_RUPTURE), getToolTier(getPlayer().getInventory().getItemInMainHand()));
|
BleedTimerTask.add(target, getPlayer(), getRuptureBleedTicks(), RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_RUPTURE), getToolTier(getPlayer().getInventory().getItemInMainHand()));
|
||||||
|
|
||||||
if (mmoPlayer.hasSkillChatNotifications()) {
|
if (mmoPlayer.hasSkillChatNotifications()) {
|
||||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding");
|
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.attribute.Attribute;
|
import org.bukkit.attribute.Attribute;
|
||||||
import org.bukkit.entity.*;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -147,7 +148,7 @@ public class TamingManager extends SkillManager {
|
|||||||
*
|
*
|
||||||
* @param entity The LivingEntity to award XP for
|
* @param entity The LivingEntity to award XP for
|
||||||
*/
|
*/
|
||||||
public void awardTamingXP(LivingEntity entity) {
|
public void awardTamingXP(@NotNull LivingEntity entity) {
|
||||||
applyXpGain(ExperienceConfig.getInstance().getTamingXP(entity.getType()), XPGainReason.PVE);
|
applyXpGain(ExperienceConfig.getInstance().getTamingXP(entity.getType()), XPGainReason.PVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ public class TamingManager extends SkillManager {
|
|||||||
* @param wolf The wolf using the ability
|
* @param wolf The wolf using the ability
|
||||||
* @param damage The damage being absorbed by the wolf
|
* @param damage The damage being absorbed by the wolf
|
||||||
*/
|
*/
|
||||||
public void fastFoodService(Wolf wolf, double damage) {
|
public void fastFoodService(@NotNull Wolf wolf, double damage) {
|
||||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.TAMING_FAST_FOOD_SERVICE, getPlayer())) {
|
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.TAMING_FAST_FOOD_SERVICE, getPlayer())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -177,20 +178,23 @@ public class TamingManager extends SkillManager {
|
|||||||
* @param target The LivingEntity to apply Gore on
|
* @param target The LivingEntity to apply Gore on
|
||||||
* @param damage The initial damage
|
* @param damage The initial damage
|
||||||
*/
|
*/
|
||||||
public double gore(LivingEntity target, double damage) {
|
public double gore(@NotNull LivingEntity target, double damage) {
|
||||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.TAMING_GORE, getPlayer())) {
|
if(BleedTimerTask.isBleedOperationAllowed()) {
|
||||||
return 0;
|
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.TAMING_GORE, getPlayer())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BleedTimerTask.add(target, getPlayer(), Taming.goreBleedTicks, 1, 2);
|
||||||
|
|
||||||
|
if (target instanceof Player) {
|
||||||
|
NotificationManager.sendPlayerInformation((Player)target, NotificationType.SUBSKILL_MESSAGE, "Combat.StruckByGore");
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Combat.Gore");
|
||||||
|
|
||||||
|
damage = (damage * Taming.goreModifier) - damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
BleedTimerTask.add(target, getPlayer(), Taming.goreBleedTicks, 1, 2);
|
|
||||||
|
|
||||||
if (target instanceof Player) {
|
|
||||||
NotificationManager.sendPlayerInformation((Player)target, NotificationType.SUBSKILL_MESSAGE, "Combat.StruckByGore");
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Combat.Gore");
|
|
||||||
|
|
||||||
damage = (damage * Taming.goreModifier) - damage;
|
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ public final class MobHealthbarUtils {
|
|||||||
/*
|
/*
|
||||||
* Store the name in metadata
|
* Store the name in metadata
|
||||||
*/
|
*/
|
||||||
if(target.getMetadata("mcMMO_oldName").size() <= 0 && originalName != null)
|
if(target.getMetadata(TransientMetadataTools.OLD_NAME_METAKEY).size() <= 0 && originalName != null)
|
||||||
target.setMetadata("mcMMO_oldName", new OldName(originalName, plugin));
|
target.setMetadata(TransientMetadataTools.OLD_NAME_METAKEY, new OldName(originalName, plugin));
|
||||||
|
|
||||||
if (oldName == null) {
|
if (oldName == null) {
|
||||||
oldName = "";
|
oldName = "";
|
||||||
|
@ -4,6 +4,7 @@ import com.gmail.nossr50.mcMMO;
|
|||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
public class TransientMetadataTools {
|
public class TransientMetadataTools {
|
||||||
|
public static final String OLD_NAME_METAKEY = TransientMetadataTools.OLD_NAME_METAKEY;
|
||||||
private final mcMMO pluginRef;
|
private final mcMMO pluginRef;
|
||||||
|
|
||||||
public TransientMetadataTools(mcMMO pluginRef) {
|
public TransientMetadataTools(mcMMO pluginRef) {
|
||||||
@ -17,6 +18,10 @@ public class TransientMetadataTools {
|
|||||||
livingEntity.removeMetadata(mcMMO.customNameKey, pluginRef);
|
livingEntity.removeMetadata(mcMMO.customNameKey, pluginRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(livingEntity.hasMetadata(OLD_NAME_METAKEY)) {
|
||||||
|
livingEntity.removeMetadata(OLD_NAME_METAKEY, pluginRef);
|
||||||
|
}
|
||||||
|
|
||||||
//Involved in changing mob names to hearts
|
//Involved in changing mob names to hearts
|
||||||
if (livingEntity.hasMetadata(mcMMO.customVisibleKey)) {
|
if (livingEntity.hasMetadata(mcMMO.customVisibleKey)) {
|
||||||
livingEntity.setCustomNameVisible(livingEntity.getMetadata(mcMMO.customVisibleKey).get(0).asBoolean());
|
livingEntity.setCustomNameVisible(livingEntity.getMetadata(mcMMO.customVisibleKey).get(0).asBoolean());
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
//package com.gmail.nossr50.util.compat.layers.attackcooldown;
|
|
||||||
//
|
|
||||||
//import com.gmail.nossr50.util.nms.NMSVersion;
|
|
||||||
//import org.bukkit.entity.Player;
|
|
||||||
//
|
|
||||||
//import java.lang.reflect.InvocationTargetException;
|
|
||||||
//
|
|
||||||
//public class DummyPlayerAttackCooldownExploitPreventionLayer extends PlayerAttackCooldownExploitPreventionLayer {
|
|
||||||
// public DummyPlayerAttackCooldownExploitPreventionLayer() {
|
|
||||||
// super(NMSVersion.UNSUPPORTED);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean initializeLayer() {
|
|
||||||
// return noErrorsOnInitialize;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
// return 1.0F; //Always full strength
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
// return 0F;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
// //Do nothing
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.gmail.nossr50.util.compat.layers.attackcooldown;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.nms.NMSVersion;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public class DummyPlayerAttackCooldownToolLayer extends PlayerAttackCooldownToolLayer {
|
||||||
|
public DummyPlayerAttackCooldownToolLayer() {
|
||||||
|
super(NMSVersion.UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initializeLayer() {
|
||||||
|
return noErrorsOnInitialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getAttackStrength(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
return 1.0F; //Always full strength
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCooldownValue(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
return 0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetAttackStrength(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
//Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCooldownFieldValue(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCooldownFieldValue(@NotNull Player player, int fieldValue) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
}
|
||||||
|
}
|
@ -1,202 +0,0 @@
|
|||||||
//package com.gmail.nossr50.util.compat.layers.attackcooldown;
|
|
||||||
//
|
|
||||||
//import com.gmail.nossr50.mcMMO;
|
|
||||||
//import com.gmail.nossr50.util.compat.layers.AbstractNMSCompatibilityLayer;
|
|
||||||
//import com.gmail.nossr50.util.nms.NMSConstants;
|
|
||||||
//import com.gmail.nossr50.util.nms.NMSVersion;
|
|
||||||
//import org.bukkit.entity.Player;
|
|
||||||
//import org.jetbrains.annotations.NotNull;
|
|
||||||
//import org.jetbrains.annotations.Nullable;
|
|
||||||
//
|
|
||||||
//import java.lang.reflect.InvocationTargetException;
|
|
||||||
//import java.lang.reflect.Method;
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// *
|
|
||||||
// * These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
|
||||||
// * In 2.2 we are switching to modules and that will clean things up significantly
|
|
||||||
// *
|
|
||||||
// */
|
|
||||||
//public class PlayerAttackCooldownExploitPreventionLayer extends AbstractNMSCompatibilityLayer implements PlayerAttackCooldownMethods{
|
|
||||||
//
|
|
||||||
// private final String cbNMSVersionPath;
|
|
||||||
//
|
|
||||||
// protected Class<?> craftPlayerClass;
|
|
||||||
// protected Class<?> entityHumanClass;
|
|
||||||
//
|
|
||||||
// protected Method playerAttackCooldownMethod;
|
|
||||||
// protected Method playerAttackStrengthMethod;
|
|
||||||
// protected Method resetPlayerAttackCooldownMethod;
|
|
||||||
// protected Method getHandleMethod;
|
|
||||||
//
|
|
||||||
// public PlayerAttackCooldownExploitPreventionLayer(@NotNull NMSVersion nmsVersion) {
|
|
||||||
// super(nmsVersion);
|
|
||||||
// mcMMO.p.getLogger().info("Loading Compatibility Layer... (Player Attack Cooldown Exploit Prevention)");
|
|
||||||
// if(!isCompatibleWithMinecraftVersion()) {
|
|
||||||
// mcMMO.p.getLogger().severe("this version of mcMMO does not support NMS for this version of Minecraft, try updating mcMMO or updating Minecraft. Not all versions of Minecraft will have NMS support built into mcMMO.");
|
|
||||||
// cbNMSVersionPath = "";
|
|
||||||
// } else {
|
|
||||||
// if(NMSConstants.getCraftBukkitVersionPath(nmsVersion) != null) {
|
|
||||||
// cbNMSVersionPath = NMSConstants.getCraftBukkitVersionPath(nmsVersion);
|
|
||||||
// noErrorsOnInitialize = initializeLayer();
|
|
||||||
//
|
|
||||||
// if(noErrorsOnInitialize) {
|
|
||||||
// mcMMO.p.getLogger().info("Successfully Loaded Compatibility Layer! (Player Attack Cooldown Exploit Prevention)");
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// mcMMO.p.getLogger().info("Failed to load - CL (Player Attack Cooldown Exploit Prevention) Could not find CB NMS path for CL");
|
|
||||||
// flagErrorsDuringStartup();
|
|
||||||
// mcMMO.p.getLogger().warning("Could not wire NMS package path for CraftBukkit!");
|
|
||||||
// cbNMSVersionPath = "";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private boolean isCompatibleWithMinecraftVersion() {
|
|
||||||
// switch(nmsVersion) {
|
|
||||||
// case NMS_1_13_2:
|
|
||||||
// case NMS_1_14_4:
|
|
||||||
// case NMS_1_15_2:
|
|
||||||
// case NMS_1_16_1:
|
|
||||||
// return true;
|
|
||||||
// default:
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Cache all reflection methods/types/classes needed for the NMS of this CompatibilityLayer
|
|
||||||
// * @param cooldownMethodName the cooldown method name
|
|
||||||
// * @param attackStrengthMethodName the attack strength method name
|
|
||||||
// * @param resetAttackCooldownMethodName the reset attack cooldown method name
|
|
||||||
// * @param getHandleMethodName the get handle method name
|
|
||||||
// * @return true if NMS was successfully wired
|
|
||||||
// */
|
|
||||||
// public boolean wireNMS(@NotNull String cooldownMethodName, @NotNull String attackStrengthMethodName, @NotNull String resetAttackCooldownMethodName, @NotNull String getHandleMethodName) {
|
|
||||||
// entityHumanClass = initEntityHumanClass();
|
|
||||||
// craftPlayerClass = initCraftPlayerClass();
|
|
||||||
//
|
|
||||||
// try {
|
|
||||||
// this.playerAttackCooldownMethod = entityHumanClass.getMethod(cooldownMethodName);
|
|
||||||
// this.playerAttackStrengthMethod = entityHumanClass.getMethod(attackStrengthMethodName, float.class);
|
|
||||||
// this.resetPlayerAttackCooldownMethod = entityHumanClass.getMethod(resetAttackCooldownMethodName);
|
|
||||||
// if (craftPlayerClass != null) {
|
|
||||||
// this.getHandleMethod = craftPlayerClass.getMethod(getHandleMethodName);
|
|
||||||
// } else {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
// } catch (NoSuchMethodException e) {
|
|
||||||
// flagErrorsDuringStartup();
|
|
||||||
// e.printStackTrace();
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Get the cached player attack cooldown method
|
|
||||||
// * @return the cached player attack cooldown method
|
|
||||||
// */
|
|
||||||
// private @Nullable Method getPlayerAttackCooldownMethod() {
|
|
||||||
// return playerAttackCooldownMethod;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Get the cached player attack strength method
|
|
||||||
// * @return the cached player attack strength method
|
|
||||||
// */
|
|
||||||
// private @Nullable Method getPlayerAttackStrengthMethod() {
|
|
||||||
// return playerAttackStrengthMethod;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Get the cached player attack cooldown reset method
|
|
||||||
// * @return the cached player attack cooldown reset method
|
|
||||||
// */
|
|
||||||
// private @Nullable Method getResetPlayerAttackCooldownMethod() {
|
|
||||||
// return resetPlayerAttackCooldownMethod;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Grab the CraftPlayer class type from NMS
|
|
||||||
// * @return the CraftPlayer class type from NMS
|
|
||||||
// */
|
|
||||||
// private @Nullable Class<?> initCraftPlayerClass() {
|
|
||||||
// try {
|
|
||||||
// return Class.forName(NMSConstants.getCraftPlayerClassPath(cbNMSVersionPath));
|
|
||||||
// } catch (ClassNotFoundException e) {
|
|
||||||
// flagErrorsDuringStartup();
|
|
||||||
// e.printStackTrace();
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Grab the EntityHuman class type from NMS
|
|
||||||
// * @return the EntityHuman class type from NMS
|
|
||||||
// */
|
|
||||||
// private @Nullable Class<?> initEntityHumanClass() {
|
|
||||||
// try {
|
|
||||||
// return Class.forName(NMSConstants.getEntityHumanClassPath(cbNMSVersionPath));
|
|
||||||
// } catch (ClassNotFoundException e) {
|
|
||||||
// flagErrorsDuringStartup();
|
|
||||||
// e.printStackTrace();
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void flagErrorsDuringStartup() {
|
|
||||||
// noErrorsOnInitialize = false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Grabs the attack strength for a player
|
|
||||||
// * Should be noted that as of today there is no way to capture a players current attack strength in spigot when they attack an entity outside of network packet listening
|
|
||||||
// * @param player target player
|
|
||||||
// * @return the float value of the player's attack strength
|
|
||||||
// */
|
|
||||||
// @Override
|
|
||||||
// public float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
// Object craftPlayer = craftPlayerClass.cast(player);
|
|
||||||
// Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
|
||||||
//
|
|
||||||
// return (float) playerAttackStrengthMethod.invoke(entityHuman, 0F); //Add no adjustment ticks
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
// Object craftPlayer = craftPlayerClass.cast(player);
|
|
||||||
// Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
|
||||||
//
|
|
||||||
// return (float) playerAttackCooldownMethod.invoke(entityHuman); //Add no adjustment ticks
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
// Object craftPlayer = craftPlayerClass.cast(player);
|
|
||||||
// Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
|
||||||
//
|
|
||||||
// resetPlayerAttackCooldownMethod.invoke(entityHuman);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean initializeLayer() {
|
|
||||||
// switch(nmsVersion) {
|
|
||||||
// case NMS_1_12_2:
|
|
||||||
// return wireNMS("dr", "n", "ds", "getHandle");
|
|
||||||
// case NMS_1_13_2:
|
|
||||||
// return wireNMS("dG", "r", "dH", "getHandle");
|
|
||||||
// case NMS_1_14_4:
|
|
||||||
// return wireNMS("dY", "s", "dZ", "getHandle");
|
|
||||||
// case NMS_1_15_2:
|
|
||||||
// return wireNMS("ex", "s", "ey", "getHandle");
|
|
||||||
// case NMS_1_16_1:
|
|
||||||
// return wireNMS("eR", "getAttackCooldown", "resetAttackCooldown", "getHandle");
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -1,19 +1,24 @@
|
|||||||
//package com.gmail.nossr50.util.compat.layers.attackcooldown;
|
package com.gmail.nossr50.util.compat.layers.attackcooldown;
|
||||||
//
|
|
||||||
//import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
//
|
import org.jetbrains.annotations.NotNull;
|
||||||
//import java.lang.reflect.InvocationTargetException;
|
|
||||||
//
|
import java.lang.reflect.InvocationTargetException;
|
||||||
//public interface PlayerAttackCooldownMethods {
|
|
||||||
// /**
|
public interface PlayerAttackCooldownMethods {
|
||||||
// * Grabs the attack strength for a player
|
/**
|
||||||
// * Should be noted that as of today there is no way to capture a players current attack strength in spigot when they attack an entity outside of network packet listening
|
* Grabs the attack strength for a player
|
||||||
// * @param player target player
|
* Should be noted that as of today there is no way to capture a players current attack strength in spigot when they attack an entity outside of network packet listening
|
||||||
// * @return the float value of the player's attack strength
|
* @param player target player
|
||||||
// */
|
* @return the float value of the player's attack strength
|
||||||
// float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
|
*/
|
||||||
//
|
float getAttackStrength(@NotNull Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
// float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException;
|
|
||||||
//
|
float getCooldownValue(@NotNull Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
// void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
|
|
||||||
//}
|
void resetAttackStrength(@NotNull Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
|
|
||||||
|
int getCooldownFieldValue(@NotNull Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
|
|
||||||
|
void setCooldownFieldValue(@NotNull Player player, int fieldValue) throws InvocationTargetException, IllegalAccessException;
|
||||||
|
}
|
||||||
|
@ -0,0 +1,237 @@
|
|||||||
|
package com.gmail.nossr50.util.compat.layers.attackcooldown;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.util.compat.layers.AbstractNMSCompatibilityLayer;
|
||||||
|
import com.gmail.nossr50.util.nms.NMSConstants;
|
||||||
|
import com.gmail.nossr50.util.nms.NMSVersion;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PlayerAttackCooldownToolLayer extends AbstractNMSCompatibilityLayer implements PlayerAttackCooldownMethods {
|
||||||
|
|
||||||
|
private final String cbNMSVersionPath;
|
||||||
|
|
||||||
|
protected Class<?> craftPlayerClass;
|
||||||
|
protected Class<?> entityHumanClass;
|
||||||
|
protected Class<?> entityLivingClass;
|
||||||
|
|
||||||
|
protected Method playerAttackCooldownMethod;
|
||||||
|
protected Method playerAttackStrengthMethod;
|
||||||
|
protected Method resetPlayerAttackCooldownMethod;
|
||||||
|
protected Method setPlayerAttackStrengthMethod;
|
||||||
|
protected Method getHandleMethod;
|
||||||
|
protected Field attackCooldownField;
|
||||||
|
protected String attackStrengthFieldName;
|
||||||
|
|
||||||
|
public PlayerAttackCooldownToolLayer(@NotNull NMSVersion nmsVersion) {
|
||||||
|
super(nmsVersion);
|
||||||
|
mcMMO.p.getLogger().info("Loading Compatibility Layer... (Player Attack Cooldown Exploit Prevention)");
|
||||||
|
if(!isCompatibleWithMinecraftVersion(nmsVersion)) {
|
||||||
|
mcMMO.p.getLogger().severe("this version of mcMMO does not support NMS for this version of Minecraft, try updating mcMMO or updating Minecraft. Not all versions of Minecraft will have NMS support built into mcMMO.");
|
||||||
|
cbNMSVersionPath = "";
|
||||||
|
} else {
|
||||||
|
if(NMSConstants.getCraftBukkitVersionPath(nmsVersion) != null) {
|
||||||
|
cbNMSVersionPath = NMSConstants.getCraftBukkitVersionPath(nmsVersion);
|
||||||
|
noErrorsOnInitialize = initializeLayer();
|
||||||
|
|
||||||
|
if(noErrorsOnInitialize) {
|
||||||
|
mcMMO.p.getLogger().info("Successfully Loaded Compatibility Layer! (Player Attack Cooldown Exploit Prevention)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mcMMO.p.getLogger().info("Failed to load - CL (Player Attack Cooldown Exploit Prevention) Could not find CB NMS path for CL");
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
mcMMO.p.getLogger().warning("Could not wire NMS package path for CraftBukkit!");
|
||||||
|
cbNMSVersionPath = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCompatibleWithMinecraftVersion(@NotNull NMSVersion nmsVersion) {
|
||||||
|
switch(nmsVersion) {
|
||||||
|
case NMS_1_13_2:
|
||||||
|
case NMS_1_14_4:
|
||||||
|
case NMS_1_15_2:
|
||||||
|
case NMS_1_16_4:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache all reflection methods/types/classes needed for the NMS of this CompatibilityLayer
|
||||||
|
* @param cooldownMethodName the cooldown method name
|
||||||
|
* @param attackStrengthMethodName the attack strength method name
|
||||||
|
* @param resetAttackCooldownMethodName the reset attack cooldown method name
|
||||||
|
* @param getHandleMethodName the get handle method name
|
||||||
|
* @return true if NMS was successfully wired
|
||||||
|
*/
|
||||||
|
public boolean wireNMS(@NotNull String cooldownMethodName, @NotNull String attackStrengthMethodName, @NotNull String resetAttackCooldownMethodName, @NotNull String getHandleMethodName, @NotNull String attackStrengthFieldName) {
|
||||||
|
entityHumanClass = initEntityHumanClass();
|
||||||
|
|
||||||
|
if (entityHumanClass != null) {
|
||||||
|
entityLivingClass = entityHumanClass.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
craftPlayerClass = initCraftPlayerClass();
|
||||||
|
this.attackStrengthFieldName = attackStrengthFieldName;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.attackCooldownField = entityLivingClass.getDeclaredField(attackStrengthFieldName);
|
||||||
|
this.attackCooldownField.setAccessible(true);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.playerAttackCooldownMethod = entityHumanClass.getMethod(cooldownMethodName);
|
||||||
|
this.playerAttackStrengthMethod = entityHumanClass.getMethod(attackStrengthMethodName, float.class);
|
||||||
|
this.resetPlayerAttackCooldownMethod = entityHumanClass.getMethod(resetAttackCooldownMethodName);
|
||||||
|
|
||||||
|
if (craftPlayerClass != null) {
|
||||||
|
this.getHandleMethod = craftPlayerClass.getMethod(getHandleMethodName);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached player attack cooldown method
|
||||||
|
* @return the cached player attack cooldown method
|
||||||
|
*/
|
||||||
|
private @Nullable Method getPlayerAttackCooldownMethod() {
|
||||||
|
return playerAttackCooldownMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached player attack strength method
|
||||||
|
* @return the cached player attack strength method
|
||||||
|
*/
|
||||||
|
private @Nullable Method getPlayerAttackStrengthMethod() {
|
||||||
|
return playerAttackStrengthMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached player attack cooldown reset method
|
||||||
|
* @return the cached player attack cooldown reset method
|
||||||
|
*/
|
||||||
|
private @Nullable Method getResetPlayerAttackCooldownMethod() {
|
||||||
|
return resetPlayerAttackCooldownMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grab the CraftPlayer class type from NMS
|
||||||
|
* @return the CraftPlayer class type from NMS
|
||||||
|
*/
|
||||||
|
private @Nullable Class<?> initCraftPlayerClass() {
|
||||||
|
try {
|
||||||
|
return Class.forName(NMSConstants.getCraftPlayerClassPath(cbNMSVersionPath));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grab the EntityHuman class type from NMS
|
||||||
|
* @return the EntityHuman class type from NMS
|
||||||
|
*/
|
||||||
|
private @Nullable Class<?> initEntityHumanClass() {
|
||||||
|
try {
|
||||||
|
return Class.forName(NMSConstants.getEntityHumanClassPath(cbNMSVersionPath));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flagErrorsDuringStartup() {
|
||||||
|
noErrorsOnInitialize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the attack strength for a player
|
||||||
|
* Should be noted that as of today there is no way to capture a players current attack strength in spigot when they attack an entity outside of network packet listening
|
||||||
|
* @param player target player
|
||||||
|
* @return the float value of the player's attack strength
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public float getAttackStrength(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
|
||||||
|
return (float) playerAttackStrengthMethod.invoke(entityHuman, 0F); //Add no adjustment ticks
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCooldownValue(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
|
||||||
|
return (float) playerAttackCooldownMethod.invoke(entityHuman); //Add no adjustment ticks
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetAttackStrength(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
Object entityLiving = entityLivingClass.cast(entityHuman);
|
||||||
|
|
||||||
|
resetPlayerAttackCooldownMethod.invoke(entityLiving);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCooldownFieldValue(@NotNull Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
Object entityLiving = entityLivingClass.cast(entityHuman);
|
||||||
|
|
||||||
|
return attackCooldownField.getInt(entityLiving);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCooldownFieldValue(@NotNull Player player, int fieldValue) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
|
||||||
|
attackCooldownField.setInt(entityHuman, fieldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initializeLayer() {
|
||||||
|
switch(nmsVersion) {
|
||||||
|
case NMS_1_12_2:
|
||||||
|
return wireNMS("dr", "n", "ds", "getHandle", "at");
|
||||||
|
case NMS_1_13_2:
|
||||||
|
return wireNMS("dG", "r", "dH", "getHandle", "at");
|
||||||
|
case NMS_1_14_4:
|
||||||
|
return wireNMS("dY", "s", "dZ", "getHandle", "at");
|
||||||
|
case NMS_1_15_2:
|
||||||
|
return wireNMS("ex", "s", "ey", "getHandle", "at");
|
||||||
|
case NMS_1_16_4:
|
||||||
|
return wireNMS("eR", "getAttackCooldown", "resetAttackCooldown", "getHandle", "at");
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unexpected NMS version support in PlayerAttackCooldown compatibility layer initialization!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -50,6 +50,8 @@ public class NMSConstants {
|
|||||||
return "v1_15_R1";
|
return "v1_15_R1";
|
||||||
case NMS_1_16_1:
|
case NMS_1_16_1:
|
||||||
return "v1_16_R1";
|
return "v1_16_R1";
|
||||||
|
case NMS_1_16_4:
|
||||||
|
return "v1_16_R3";
|
||||||
case UNSUPPORTED:
|
case UNSUPPORTED:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,7 @@ public final class CombatUtils {
|
|||||||
*/
|
*/
|
||||||
public static void fixNames(@NotNull LivingEntity entity)
|
public static void fixNames(@NotNull LivingEntity entity)
|
||||||
{
|
{
|
||||||
List<MetadataValue> metadataValue = entity.getMetadata("mcMMO_oldName");
|
List<MetadataValue> metadataValue = entity.getMetadata(TransientMetadataTools.OLD_NAME_METAKEY);
|
||||||
|
|
||||||
if(metadataValue.size() <= 0)
|
if(metadataValue.size() <= 0)
|
||||||
return;
|
return;
|
||||||
@ -693,7 +693,7 @@ public final class CombatUtils {
|
|||||||
return processingNoInvulnDamage;
|
return processingNoInvulnDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dealNoInvulnerabilityTickDamage(@NotNull LivingEntity target, double damage, Entity attacker) {
|
public static void dealNoInvulnerabilityTickDamage(@NotNull LivingEntity target, double damage, @Nullable Entity attacker) {
|
||||||
if (target.isDead()) {
|
if (target.isDead()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import net.kyori.adventure.text.ComponentBuilder;
|
|||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.event.HoverEvent;
|
import net.kyori.adventure.text.event.HoverEvent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.format.Style;
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -107,7 +109,7 @@ public class TextUtils {
|
|||||||
return LegacyComponentSerializer.legacySection().deserialize(rawString);
|
return LegacyComponentSerializer.legacySection().deserialize(rawString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull TextComponent colorizeText(String rawtext) {
|
public static @NotNull TextComponent colorizeText(@NotNull String rawtext) {
|
||||||
if(customLegacySerializer == null) {
|
if(customLegacySerializer == null) {
|
||||||
customLegacySerializer = getSerializer();
|
customLegacySerializer = getSerializer();
|
||||||
}
|
}
|
||||||
@ -117,7 +119,20 @@ public class TextUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static LegacyComponentSerializer getSerializer() {
|
private static LegacyComponentSerializer getSerializer() {
|
||||||
return LegacyComponentSerializer.builder().hexColors().useUnusualXRepeatedCharacterHexFormat().character('&').hexCharacter('#').build();
|
return LegacyComponentSerializer.builder()
|
||||||
|
.hexColors()
|
||||||
|
.useUnusualXRepeatedCharacterHexFormat()
|
||||||
|
.character('&')
|
||||||
|
.hexCharacter('#')
|
||||||
|
.extractUrls(Style.style()
|
||||||
|
.decorate(getURLStyle())
|
||||||
|
.color(NamedTextColor.DARK_AQUA)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull TextDecoration[] getURLStyle() {
|
||||||
|
return new TextDecoration[]{TextDecoration.UNDERLINED};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull String sanitizeForSerializer(@NotNull String string) {
|
public static @NotNull String sanitizeForSerializer(@NotNull String string) {
|
||||||
|
@ -264,7 +264,7 @@ Commands.mcrank.Player=DOELWIT: &f{0}
|
|||||||
Commands.mmoedit=[player] <Kracht> <Nieuwe waarde> &c - Pas doel aan
|
Commands.mmoedit=[player] <Kracht> <Nieuwe waarde> &c - Pas doel aan
|
||||||
Commands.mmoedit.Modified.1=&aUw level in {0} is veranderd naar {1}
|
Commands.mmoedit.Modified.1=&aUw level in {0} is veranderd naar {1}
|
||||||
Commands.mmoedit.Modified.2={0} is aangepast voor {1}.
|
Commands.mmoedit.Modified.2={0} is aangepast voor {1}.
|
||||||
Commands.mcconvert.Database.Same= Je makt al gebruik van de {0} database!
|
Commands.mcconvert.Database.Same= Je maakt al gebruik van de {0} database!
|
||||||
Commands.mcconvert.Database.InvalidType= {0} is geen geldig soort database.
|
Commands.mcconvert.Database.InvalidType= {0} is geen geldig soort database.
|
||||||
Commands.ModDescription=- Lees instructie mod beschrijving
|
Commands.ModDescription=- Lees instructie mod beschrijving
|
||||||
Commands.NoConsole=Deze commando wordt niet ondersteund vanuit de console.
|
Commands.NoConsole=Deze commando wordt niet ondersteund vanuit de console.
|
||||||
@ -416,7 +416,7 @@ Smelting.SubSkill.FuelEfficiency.Name=Brandstof Effici\u00ebntie
|
|||||||
Smelting.Listener=Smelten:
|
Smelting.Listener=Smelten:
|
||||||
Smelting.SkillName=SMELTEN
|
Smelting.SkillName=SMELTEN
|
||||||
Commands.Description.mcstats=Toon je mcMMO niveaus en XP
|
Commands.Description.mcstats=Toon je mcMMO niveaus en XP
|
||||||
Commands.Description.party=Beheer verscheidene mcMMO groep instellingen
|
Commands.Description.party=Beheer verschillende mcMMO groep instellingen
|
||||||
Commands.Description.ptp=Teleport naar een groepslid
|
Commands.Description.ptp=Teleport naar een groepslid
|
||||||
UpdateChecker.Outdated=U gebruikt een verouderde versie van mcMMO!
|
UpdateChecker.Outdated=U gebruikt een verouderde versie van mcMMO!
|
||||||
UpdateChecker.NewAvailable=Er is een nieuwe versie beschikbaar op BukkitDev.
|
UpdateChecker.NewAvailable=Er is een nieuwe versie beschikbaar op BukkitDev.
|
||||||
|
@ -45,6 +45,14 @@ Repairables:
|
|||||||
# Wooden repairables
|
# Wooden repairables
|
||||||
###
|
###
|
||||||
# Tools
|
# Tools
|
||||||
|
SHIELD:
|
||||||
|
MinimumLevel: 0
|
||||||
|
XpMultiplier: .25
|
||||||
|
ItemType: OTHER
|
||||||
|
ItemMaterialCategory: WOOD
|
||||||
|
RepairMaterial: OAK_PLANKS
|
||||||
|
MinimumQuantity: 6
|
||||||
|
MaximumDurability: 336
|
||||||
WOODEN_SWORD:
|
WOODEN_SWORD:
|
||||||
MinimumLevel: 0
|
MinimumLevel: 0
|
||||||
XpMultiplier: .25
|
XpMultiplier: .25
|
||||||
@ -183,7 +191,7 @@ Repairables:
|
|||||||
XpMultiplier: 6
|
XpMultiplier: 6
|
||||||
|
|
||||||
#
|
#
|
||||||
# Diamond repairables
|
# Netherite repairables
|
||||||
###
|
###
|
||||||
# Tools
|
# Tools
|
||||||
NETHERITE_SWORD:
|
NETHERITE_SWORD:
|
||||||
@ -243,3 +251,38 @@ Repairables:
|
|||||||
CARROT_ON_A_STICK:
|
CARROT_ON_A_STICK:
|
||||||
MinimumLevel: 0
|
MinimumLevel: 0
|
||||||
XpMultiplier: .5
|
XpMultiplier: .5
|
||||||
|
CROSSBOW:
|
||||||
|
MinimumLevel: 0
|
||||||
|
XpMultiplier: .5
|
||||||
|
ItemType: TOOL
|
||||||
|
ItemMaterialCategory: STRING
|
||||||
|
RepairMaterial: STRING
|
||||||
|
MinimumQuantity: 3
|
||||||
|
MaximumDurability: 326
|
||||||
|
WARPED_FUNGUS_ON_A_STICK:
|
||||||
|
MinimumLevel: 0
|
||||||
|
XpMultiplier: .5
|
||||||
|
ItemType: TOOL
|
||||||
|
ItemMaterialCategory: STRING
|
||||||
|
RepairMaterial: STRING
|
||||||
|
MinimumQuantity: 3
|
||||||
|
MaximumDurability: 100
|
||||||
|
#
|
||||||
|
# Other
|
||||||
|
###
|
||||||
|
ELYTRA:
|
||||||
|
MinimumLevel: 0
|
||||||
|
XpMultiplier: 3
|
||||||
|
ItemType: OTHER
|
||||||
|
ItemMaterialCategory: OTHER
|
||||||
|
RepairMaterial: PHANTOM_MEMBRANE
|
||||||
|
MinimumQuantity: 8
|
||||||
|
MaximumDurability: 432
|
||||||
|
TRIDENT:
|
||||||
|
MinimumLevel: 0
|
||||||
|
XpMultiplier: 3
|
||||||
|
ItemType: TOOL
|
||||||
|
ItemMaterialCategory: OTHER
|
||||||
|
RepairMaterial: PRISMARINE_CRYSTALS
|
||||||
|
MinimumQuantity: 16
|
||||||
|
MaximumDurability: 250
|
Loading…
Reference in New Issue
Block a user