Master Angler reworked

This commit is contained in:
nossr50
2020-11-09 16:46:52 -08:00
parent f4f6abd9d5
commit ba7e235e64
30 changed files with 715 additions and 437 deletions

View File

@@ -8,10 +8,13 @@ import com.gmail.nossr50.util.compat.layers.bungee.BungeeModernSerializerCompati
import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer;
import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataLayer_1_13;
import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataLayer_1_14;
import com.gmail.nossr50.util.compat.layers.skills.AbstractMasterAnglerCompatibility;
import com.gmail.nossr50.util.compat.layers.skills.MasterAnglerCompatibilityLayer;
import com.gmail.nossr50.util.nms.NMSVersion;
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
@@ -21,6 +24,7 @@ import java.util.HashMap;
* In 2.2 we are switching to modules and that will clean things up significantly
*
*/
//TODO: I need to rewrite this crap
public class CompatibilityManager {
private HashMap<CompatibilityType, Boolean> supportedLayers;
private boolean isFullyCompatibleServerSoftware = true; //true if all compatibility layers load successfully
@@ -31,6 +35,7 @@ public class CompatibilityManager {
// private PlayerAttackCooldownExploitPreventionLayer playerAttackCooldownExploitPreventionLayer;
private AbstractPersistentDataLayer persistentDataLayer;
private AbstractBungeeSerializerCompatibilityLayer bungeeSerializerCompatibilityLayer;
private AbstractMasterAnglerCompatibility masterAnglerCompatibility;
public CompatibilityManager(MinecraftGameVersion minecraftGameVersion) {
mcMMO.p.getLogger().info("Loading compatibility layers...");
@@ -49,10 +54,6 @@ public class CompatibilityManager {
supportedLayers = new HashMap<>(); //Init map
for(CompatibilityType compatibilityType : CompatibilityType.values()) {
//TODO: Remove later
if(compatibilityType == CompatibilityType.PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION)
continue;
supportedLayers.put(compatibilityType, false); //All layers are set to false when initialized
}
}
@@ -64,16 +65,39 @@ public class CompatibilityManager {
private void initCompatibilityLayers() {
initPersistentDataLayer();
initBungeeSerializerLayer();
initMasterAnglerLayer();
isFullyCompatibleServerSoftware = true;
}
private void initMasterAnglerLayer() {
if(minecraftGameVersion.getMinorVersion().asInt() >= 16 || minecraftGameVersion.getMajorVersion().asInt() >= 2) {
if(hasNewFishingHookAPI()) {
masterAnglerCompatibility = new MasterAnglerCompatibilityLayer();
}
} else {
masterAnglerCompatibility = null;
}
}
private boolean hasNewFishingHookAPI() {
try {
Class<?> checkForClass = Class.forName("org.bukkit.entity.FishHook");
checkForClass.getMethod("getMinWaitTime");
return true;
} catch (ClassNotFoundException | NoSuchMethodException e) {
return false;
}
}
private void initBungeeSerializerLayer() {
if(minecraftGameVersion.getMinorVersion().asInt() >= 16) {
bungeeSerializerCompatibilityLayer = new BungeeModernSerializerCompatibilityLayer();
} else {
bungeeSerializerCompatibilityLayer = new BungeeLegacySerializerCompatibilityLayer();
}
supportedLayers.put(CompatibilityType.BUNGEE_SERIALIZER, true);
}
private void initPersistentDataLayer() {
@@ -145,11 +169,6 @@ public class CompatibilityManager {
return NMSVersion.UNSUPPORTED;
}
// public PlayerAttackCooldownExploitPreventionLayer getPlayerAttackCooldownExploitPreventionLayer() {
// return playerAttackCooldownExploitPreventionLayer;
// }
public AbstractBungeeSerializerCompatibilityLayer getBungeeSerializerCompatibilityLayer() {
return bungeeSerializerCompatibilityLayer;
}
@@ -157,4 +176,8 @@ public class CompatibilityManager {
public AbstractPersistentDataLayer getPersistentDataLayer() {
return persistentDataLayer;
}
public @Nullable AbstractMasterAnglerCompatibility getMasterAnglerCompatibilityLayer() {
return masterAnglerCompatibility;
}
}

View File

@@ -1,7 +1,7 @@
package com.gmail.nossr50.util.compat;
public enum CompatibilityType {
PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION,
PERSISTENT_DATA,
BUNGEE_SERIALIZER
BUNGEE_SERIALIZER,
MASTER_ANGLER,
}

View File

@@ -1,32 +1,32 @@
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
}
}
//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
// }
//}

View File

@@ -1,202 +1,202 @@
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;
}
}
//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;
// }
//}

View File

@@ -1,19 +1,19 @@
package com.gmail.nossr50.util.compat.layers.attackcooldown;
import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
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
* @param player target player
* @return the float value of the player's attack strength
*/
float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException;
void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
}
//package com.gmail.nossr50.util.compat.layers.attackcooldown;
//
//import org.bukkit.entity.Player;
//
//import java.lang.reflect.InvocationTargetException;
//
//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
// * @param player target player
// * @return the float value of the player's attack strength
// */
// float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
//
// float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException;
//
// void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
//}

View File

@@ -0,0 +1,6 @@
package com.gmail.nossr50.util.compat.layers.skills;
import com.gmail.nossr50.util.compat.layers.AbstractCompatibilityLayer;
public abstract class AbstractMasterAnglerCompatibility extends AbstractCompatibilityLayer {
}

View File

@@ -0,0 +1,91 @@
package com.gmail.nossr50.util.compat.layers.skills;
import org.bukkit.entity.FishHook;
import org.jetbrains.annotations.NotNull;
public class MasterAnglerCompatibilityLayer extends AbstractMasterAnglerCompatibility {
@Override
public boolean initializeLayer() {
return true;
}
/**
* Get the minimum number of ticks one has to wait for a fish biting.
* <p>
* The default is 100 ticks (5 seconds).<br>
* Note that this is before applying lure.
*
* @return Minimum number of ticks one has to wait for a fish biting
*/
public int getMinWaitTime(@NotNull FishHook fishHook) {
return fishHook.getMinWaitTime();
}
/**
* Set the minimum number of ticks one has to wait for a fish biting.
* <p>
* The default is 100 ticks (5 seconds).<br>
* Note that this is before applying lure.
*
* @param minWaitTime Minimum number of ticks one has to wait for a fish
* biting
*/
public void setMinWaitTime(@NotNull FishHook fishHook, int minWaitTime) {
fishHook.setMinWaitTime(minWaitTime);
}
/**
* Get the maximum number of ticks one has to wait for a fish biting.
* <p>
* The default is 600 ticks (30 seconds).<br>
* Note that this is before applying lure.
*
* @return Maximum number of ticks one has to wait for a fish biting
*/
public int getMaxWaitTime(@NotNull FishHook fishHook) {
return fishHook.getMaxWaitTime();
}
/**
* Set the maximum number of ticks one has to wait for a fish biting.
* <p>
* The default is 600 ticks (30 seconds).<br>
* Note that this is before applying lure.
*
* @param maxWaitTime Maximum number of ticks one has to wait for a fish
* biting
*/
public void setMaxWaitTime(@NotNull FishHook fishHook, int maxWaitTime) {
fishHook.setMaxWaitTime(maxWaitTime);
}
/**
* Get whether the lure enchantment should be applied to reduce the wait
* time.
* <p>
* The default is true.<br>
* Lure reduces the wait time by 100 ticks (5 seconds) for each level of the
* enchantment.
*
* @return Whether the lure enchantment should be applied to reduce the wait
* time
*/
public boolean getApplyLure(@NotNull FishHook fishHook) {
return fishHook.getApplyLure();
}
/**
* Set whether the lure enchantment should be applied to reduce the wait
* time.
* <p>
* The default is true.<br>
* Lure reduces the wait time by 100 ticks (5 seconds) for each level of the
* enchantment.
*
* @param applyLure Whether the lure enchantment should be applied to reduce
* the wait time
*/
public void setApplyLure(@NotNull FishHook fishHook, boolean applyLure) {
fishHook.setApplyLure(applyLure);
}
}