Merge pull request #88 from Protonull/elytra-features

Expand upon ElytraFeatures
This commit is contained in:
wingzero54 authored and GitHub committed 2021-09-16 23:13:44 -05:00
commit 7b16512907
4 files changed
+290 -71

No files matched your search

@@ -0,0 +1,103 @@
package com.programmerdan.minecraft.simpleadminhacks.configs;
import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks;
import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHackConfig;
import javax.annotation.Nonnull;
import org.bukkit.configuration.ConfigurationSection;
import vg.civcraft.mc.civmodcore.util.CivLogger;
public final class ElytraFeaturesConfig extends SimpleHackConfig {
private final CivLogger logger;
private boolean disableFlight;
private boolean disableFlightInCombat;
private boolean disableFireworkBoosting;
private boolean disableFireworkBoostingInCombat;
private boolean disableSafeFireworkBoosting;
private int heightDamage;
private double heightDamageScaling;
private int heightBuffer;
private long heightDamageInterval;
public ElytraFeaturesConfig(@Nonnull final SimpleAdminHacks plugin,
@Nonnull final ConfigurationSection base) {
super(plugin, base, false);
this.logger = CivLogger.getLogger(getClass());
wireup(base);
}
@Override
protected void wireup(@Nonnull final ConfigurationSection config) {
this.disableFlight = config.getBoolean("disableFlight", false);
this.disableFlightInCombat = config.getBoolean("disableFlightInCombat", false);
this.disableFireworkBoosting = config.getBoolean("disableFireworkBoosting", false);
this.disableFireworkBoostingInCombat = config.getBoolean("disableFireworkBoostingInCombat", false);
this.disableSafeFireworkBoosting = config.getBoolean("disableSafeFireworkBoosting", false);
this.heightDamage = config.getInt("heightDamage.damage", 1);
if (this.heightDamage < 0) {
this.logger.warning("[heightDamage.damage] was set to [" + this.heightDamage + "], " +
"which is invalid, defaulting to: 1");
this.heightDamage = 1;
}
this.heightDamageScaling = config.getDouble("heightDamage.scales", 1d);
if (this.heightDamageScaling <= 0d) {
this.logger.warning("[heightDamage.scales] was set to [" + this.heightDamageScaling + "], " +
"which is invalid, defaulting to: 1.0d");
this.heightDamageScaling = 1d;
}
this.heightBuffer = config.getInt("heightDamage.buffer", 5);
this.heightDamageInterval = config.getLong("heightDamage.interval", 1000L);
if (this.heightDamageInterval < 1L) {
this.logger.warning("[heightDamage.interval] was set to [" + this.heightDamageInterval + "], " +
"which is invalid, defaulting to: 1000L");
this.heightDamageInterval = 1000L;
}
}
public boolean isFlightDisabled() {
return this.disableFlight;
}
public boolean isFlightDisabledInCombat() {
return this.disableFlightInCombat;
}
public boolean isBoostingDisabled() {
return this.disableFireworkBoosting;
}
public boolean isBoostingDisabledInCombat() {
return this.disableFireworkBoostingInCombat;
}
public boolean isSafeBoostingDisabled() {
return this.disableSafeFireworkBoosting;
}
public int getHeightDamage() {
return this.heightDamage;
}
public double isHeightDamageScaling() {
return this.heightDamageScaling;
}
public int getHeightBuffer() {
return this.heightBuffer;
}
public long getHeightDamageInterval() {
return this.heightDamageInterval;
}
}
@@ -0,0 +1,164 @@
package com.programmerdan.minecraft.simpleadminhacks.hacks;
import com.destroystokyo.paper.event.player.PlayerElytraBoostEvent;
import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks;
import com.programmerdan.minecraft.simpleadminhacks.configs.ElytraFeaturesConfig;
import com.programmerdan.minecraft.simpleadminhacks.framework.SimpleHack;
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import java.util.Comparator;
import javax.annotation.Nonnull;
import net.minelink.ctplus.CombatTagPlus;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityToggleGlideEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
public final class ElytraFeatures extends SimpleHack<ElytraFeaturesConfig> implements Listener {
public ElytraFeatures(@Nonnull final SimpleAdminHacks plugin,
@Nonnull final ElytraFeaturesConfig config) {
super(plugin, config);
}
public static ElytraFeaturesConfig generate(@Nonnull final SimpleAdminHacks plugin,
@Nonnull final ConfigurationSection config) {
return new ElytraFeaturesConfig(plugin, config);
}
@Override
public void onEnable() {
plugin().registerListener(this);
}
@Override
public void onDisable() {
HandlerList.unregisterAll(this);
}
private boolean INTERNAL_hasBypassPermission(final Entity entity) {
return entity instanceof Player && entity.hasPermission("simpleadmin.elytrabypass");
}
private boolean INTERNAL_isInCombat(final Entity entity) {
if (!(entity instanceof Player)) {
return false;
}
final PluginManager pluginManager = Bukkit.getPluginManager();
final Plugin foundPlugin = pluginManager.getPlugin("CombatTagPlus");
if (pluginManager.isPluginEnabled(foundPlugin)) {
final CombatTagPlus combatTagPlugin = (CombatTagPlus) foundPlugin;
return combatTagPlugin.getTagManager().isTagged(entity.getUniqueId());
}
return false;
}
// ------------------------------------------------------------
// Elytra flight
// ------------------------------------------------------------
@EventHandler(ignoreCancelled = true)
public void regulateElytraFlight(@Nonnull final EntityToggleGlideEvent event) {
boolean disableFlight = false;
if (config().isFlightDisabled()) {
disableFlight = true;
}
else {
if (config().isFlightDisabledInCombat()) {
disableFlight = INTERNAL_isInCombat(event.getEntity());
}
}
if (disableFlight) {
if (!INTERNAL_hasBypassPermission(event.getEntity())) {
event.setCancelled(true);
}
}
}
// ------------------------------------------------------------
// Elytra boosting
// ------------------------------------------------------------
@EventHandler(ignoreCancelled = true)
public void regulateElytraBoosting(@Nonnull final PlayerElytraBoostEvent event) {
boolean disableBoosting = false;
if (config().isBoostingDisabled()) {
disableBoosting = true;
}
else {
if (config().isBoostingDisabledInCombat()) {
if (INTERNAL_isInCombat(event.getPlayer())) {
disableBoosting = true;
}
}
if (config().isSafeBoostingDisabled()) {
if (!event.getFirework().getFireworkMeta().hasEffects()) {
disableBoosting = true;
}
}
}
if (disableBoosting) {
if (!INTERNAL_hasBypassPermission(event.getPlayer())) {
event.setCancelled(true);
}
}
}
// ------------------------------------------------------------
// Elytra damage
// ------------------------------------------------------------
private static final class ElytraDamage {
private long lastDamageTime;
private double damageToDeal;
}
private final Object2ObjectMap<Player, ElytraDamage> damageElytraFlightTracker =
new Object2ObjectAVLTreeMap<>(Comparator.comparing(Player::getUniqueId));
@EventHandler(ignoreCancelled = true)
public void damageFliersAboveWorldHeight(final PlayerMoveEvent event) {
if (config().getHeightDamage() <= 0) {
return;
}
final Player player = event.getPlayer();
if (!player.isGliding() || INTERNAL_hasBypassPermission(player)) {
return;
}
final Location fromLocation = event.getFrom();
final int allowedHeight = fromLocation.getWorld().getMaxHeight() + config().getHeightBuffer();
final int blocksAboveAllowedHeight = fromLocation.getBlockY() - allowedHeight;
// If the player is within the allowed height, do nothing
if (blocksAboveAllowedHeight <= 0) {
return;
}
final ElytraDamage details = this.damageElytraFlightTracker.computeIfAbsent(
player, (_key) -> new ElytraDamage());
details.damageToDeal = Math.max(details.damageToDeal,
config().getHeightDamage() * blocksAboveAllowedHeight * config().isHeightDamageScaling());
final long now = System.currentTimeMillis();
final long deltaInterval = now - details.lastDamageTime;
// If it's not the right time to damage the player, do nothing
if (deltaInterval < config().getHeightDamageInterval()) {
return;
}
player.damage(details.damageToDeal);
details.damageToDeal = 0;
details.lastDamageTime = now;
}
@EventHandler
public void resetDamageElytraFlightOnLogout(final PlayerQuitEvent event) {
this.damageElytraFlightTracker.remove(event.getPlayer());
}
}
@@ -1,66 +0,0 @@
package com.programmerdan.minecraft.simpleadminhacks.hacks.basic;
import com.destroystokyo.paper.event.player.PlayerElytraBoostEvent;
import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks;
import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack;
import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig;
import com.programmerdan.minecraft.simpleadminhacks.framework.autoload.AutoLoad;
import net.minelink.ctplus.CombatTagPlus;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityToggleGlideEvent;
public class ElytraFeatures extends BasicHack {
@AutoLoad
private boolean disableFlight;
@AutoLoad
private boolean disableFireworkBoosting;
@AutoLoad
private boolean disableFlightInCombat;
public ElytraFeatures(final SimpleAdminHacks plugin, final BasicHackConfig config) {
super(plugin, config);
}
private boolean hasBypassPermission(final Entity entity) {
if (!(entity instanceof Player)) {
return false;
}
return entity.hasPermission("simpleadmin.elytrabypass");
}
private boolean isInCombat(final Entity entity) {
if (!(entity instanceof Player)) {
return false;
}
final var pluginManager = Bukkit.getPluginManager();
final var foundPlugin = pluginManager.getPlugin("CombatTagPlus");
if (pluginManager.isPluginEnabled(foundPlugin)) {
final var combatTagPlugin = (CombatTagPlus) foundPlugin;
return combatTagPlugin.getTagManager().isTagged(entity.getUniqueId());
}
return false;
}
@EventHandler(ignoreCancelled = true)
public void disableElytraFlight(final EntityToggleGlideEvent event) {
if (this.disableFlight || (this.disableFlightInCombat && isInCombat(event.getEntity()))) {
if (!hasBypassPermission(event.getEntity())) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void disableElytraFireworkBoosting(final PlayerElytraBoostEvent event) {
if (this.disableFireworkBoosting && !hasBypassPermission(event.getPlayer())) {
event.setCancelled(true);
}
}
}
+23 -5
View File
@@ -92,11 +92,6 @@ hacks:
announcements:
- "[\"\",{\"text\":\"Buy \"},{\"text\":\"Dogecoin\",\"color\":\"dark_red\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"https://www.coindesk.com/price/dogecoin\"}},{\"text\":\"!\"}]"
- "[\"\",{\"text\":\"Very \"},{\"text\":\"Wow!\",\"italic\":true,\"hoverEvent\":{\"action\":\"show_text\",\"contents\":\"Wow!\"}}]"
ElytraFeatures:
enabled: true
disableFlight: false
disableFireworkBoosting: false
disableFlightInCombat: false
EventDebugHack:
enabled: true
EventHandlerList:
@@ -242,6 +237,29 @@ hacks:
# Note: You can also just state "ALL" for all spawn circumstances
VILLAGER: ALL
ENDERMITE: [DISPENSE_EGG, EGG, SPAWNER_EGG]
ElytraFeatures:
enabled: true
# Whether Elytra flight should be outright disabled
disableFlight: false
# Whether Elytra flight should be disabled in combat
disableFlightInCombat: false
# Whether firework boosting should be outright disabled
disableFireworkBoosting: false
# Whether firework boosting should be disabled in combat
disableFireworkBoostingInCombat: false
# Whether to restrict firework boosting to explosive fireworks
disableSafeFireworkBoosting: false
# This regulates player damage when Elytra flying above world height.
heightDamage:
# The amount of damage (in half-hearts) the flier should take.
# NOTE: Setting to 0 will disable the damage.
damage: 1
# The damage is multiplied by the number of blocks above world height multiplied by this number.
scales: 1.0
# The amount of blocks above height limit where damage is not applied.
buffer: 5
# The interval (in milliseconds) between damage ticks.
interval: 1000
Experimental:
enabled: true
combatspy: false