Implement server-side regeneration speed management to nullify the effectiveness of regen hacks

This commit is contained in:
AlexTheCoder 2017-08-26 02:10:28 -04:00
parent bc7401196c
commit 1ac59b409b
3 changed files with 199 additions and 2 deletions

View File

@ -365,7 +365,7 @@ public class Chat extends MiniPlugin
for (Function<AsyncPlayerChatEvent, Boolean> filter : _highPriorityFilters)
{
if (filter.apply(event).booleanValue())
if (filter.apply(event))
{
event.setCancelled(true);
return;
@ -433,7 +433,7 @@ public class Chat extends MiniPlugin
for (Function<AsyncPlayerChatEvent, Boolean> filter : _lowPriorityFilters)
{
if (filter.apply(event).booleanValue())
if (filter.apply(event))
{
event.setCancelled(true);
return;

View File

@ -0,0 +1,193 @@
package mineplex.core.regeneration;
import java.util.Collection;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ReflectivelyCreateMiniPlugin
public class RegenerationManager extends MiniPlugin
{
private static final String REGEN_COOLDOWN_IDENTIFIER = "Natural Health Regeneration Cooldown";
private static final long REGEN_COOLDOWN_MILLIS = 4000;
private static final String MAGIC_REGEN_COOLDOWN_IDENTIFIER = "Magic Health Regeneration Cooldown";
private RegenerationManager()
{
super("Regeneration Manager");
addCommand(new CommandBase<RegenerationManager>(this, Rank.ADMIN, "regeninfo")
{
@Override
public void Execute(Player caller, String[] args)
{
Player target = caller;
if (args.length > 0)
{
if (Bukkit.getPlayer(args[0]) != null)
{
target = Bukkit.getPlayer(args[0]);
}
}
caller.sendMessage("____[" + target.getName() + "]____");
caller.sendMessage("Health: " + target.getHealth() + "/" + target.getMaxHealth());
caller.sendMessage("Food: " + target.getFoodLevel() + "/" + 20);
caller.sendMessage("Regeneration Cooldown: " + Recharge.Instance.usable(target, REGEN_COOLDOWN_IDENTIFIER));
}
});
}
private long getDurationForAmplifierLevel(int amplifier)
{
if (amplifier < 0)
{
return 0;
}
long duration = 0;
switch(amplifier)
{
case 0:
duration = 2500; //50 ticks
break;
case 1:
duration = 1250; //25 ticks
break;
case 2:
duration = 600; //12 ticks
break;
case 3:
duration = 300; //6 ticks
break;
case 4:
duration = 150; //3 ticks
break;
default:
duration = 50; //1 tick
break;
}
return duration;
}
@SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onStandardHeal(EntityRegainHealthEvent event)
{
if (!(event.getEntity() instanceof Player))
{
return;
}
if (event.getRegainReason() == RegainReason.SATIATED)
{
if (!Recharge.Instance.use((Player)event.getEntity(), REGEN_COOLDOWN_IDENTIFIER, REGEN_COOLDOWN_MILLIS, false, false))
{
event.setCancelled(true);
}
}
if (event.getRegainReason() == RegainReason.MAGIC_REGEN)
{
if (!Recharge.Instance.usable((Player)event.getEntity(), MAGIC_REGEN_COOLDOWN_IDENTIFIER))
{
event.setCancelled(true);
return;
}
Collection<PotionEffect> effects = ((Player)event.getEntity()).getActivePotionEffects();
int amplifier = -1;
for (PotionEffect effect : effects)
{
if (effect.getType().getId() == PotionEffectType.REGENERATION.getId())
{
amplifier = Math.max(amplifier, effect.getAmplifier());
}
}
long cooldown = getDurationForAmplifierLevel(amplifier);
if (cooldown > 0)
{
Recharge.Instance.use((Player)event.getEntity(), MAGIC_REGEN_COOLDOWN_IDENTIFIER, cooldown, false, false);
}
}
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Bukkit.getOnlinePlayers().forEach(player ->
{
if (!Recharge.Instance.usable(player, MAGIC_REGEN_COOLDOWN_IDENTIFIER) && !player.hasPotionEffect(PotionEffectType.REGENERATION))
{
Recharge.Instance.recharge(player, MAGIC_REGEN_COOLDOWN_IDENTIFIER);
UtilEnt.removeMetadata(player, "REGEN POTION AMPLIFIER LOG");
}
if (UtilEnt.GetMetadata(player, "REGEN POTION AMPLIFIER LOG") != null)
{
Integer recorded = UtilEnt.GetMetadata(player, "REGEN POTION AMPLIFIER LOG");
Collection<PotionEffect> effects = player.getActivePotionEffects();
int amplifier = -1;
for (PotionEffect effect : effects)
{
if (effect.getType().getId() == PotionEffectType.REGENERATION.getId())
{
amplifier = Math.max(amplifier, effect.getAmplifier());
}
}
if (recorded != amplifier)
{
if (amplifier > -1)
{
UtilEnt.SetMetadata(player, "REGEN POTION AMPLIFIER LOG", amplifier);
}
else
{
UtilEnt.removeMetadata(player, "REGEN POTION AMPLIFIER LOG");
}
Recharge.Instance.recharge(player, MAGIC_REGEN_COOLDOWN_IDENTIFIER);
}
}
else
{
if (player.hasPotionEffect(PotionEffectType.REGENERATION))
{
Collection<PotionEffect> effects = player.getActivePotionEffects();
int amplifier = -1;
for (PotionEffect effect : effects)
{
if (effect.getType().getId() == PotionEffectType.REGENERATION.getId())
{
amplifier = Math.max(amplifier, effect.getAmplifier());
}
}
if (amplifier > -1)
{
UtilEnt.SetMetadata(player, "REGEN POTION AMPLIFIER LOG", amplifier);
}
}
}
});
}
}

View File

@ -20,6 +20,7 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
import mineplex.core.account.event.ClientUnloadEvent;
import mineplex.core.common.util.C;
@ -31,6 +32,7 @@ import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.regeneration.RegenerationManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.combat.event.ClearCombatEvent;
@ -59,6 +61,8 @@ public class CombatManager extends MiniPlugin
public CombatManager(JavaPlugin plugin)
{
super("Combat", plugin);
Managers.require(RegenerationManager.class);
}
@EventHandler