Skip to content

Commit

Permalink
fix NPE spam
Browse files Browse the repository at this point in the history
  • Loading branch information
xGinko committed Jan 27, 2024
1 parent f51bb20 commit 2c10c64
Show file tree
Hide file tree
Showing 18 changed files with 359 additions and 486 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import me.moomoo.anarchyexploitfixes.modules.combat.*;
import me.moomoo.anarchyexploitfixes.modules.dupepreventions.*;
import me.moomoo.anarchyexploitfixes.modules.elytra.*;
import me.moomoo.anarchyexploitfixes.modules.elytra.helper.ElytraHelper;
import me.moomoo.anarchyexploitfixes.modules.elytra.ElytraHelper;
import me.moomoo.anarchyexploitfixes.modules.illegals.items.RemoveSpecificItemNames;
import me.moomoo.anarchyexploitfixes.modules.illegals.items.RevertOverstacked;
import me.moomoo.anarchyexploitfixes.modules.illegals.items.RevertUnbreakables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import me.moomoo.anarchyexploitfixes.config.Config;
import me.moomoo.anarchyexploitfixes.config.LanguageCache;
import me.moomoo.anarchyexploitfixes.modules.AnarchyExploitFixesModule;
import me.moomoo.anarchyexploitfixes.modules.elytra.helper.ElytraHelper;
import me.moomoo.anarchyexploitfixes.utils.LocationUtil;
import me.moomoo.anarchyexploitfixes.utils.MaterialUtil;
import net.kyori.adventure.text.Component;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import me.moomoo.anarchyexploitfixes.config.Config;
import me.moomoo.anarchyexploitfixes.config.LanguageCache;
import me.moomoo.anarchyexploitfixes.modules.AnarchyExploitFixesModule;
import me.moomoo.anarchyexploitfixes.modules.elytra.helper.ElytraHelper;
import me.moomoo.anarchyexploitfixes.utils.LocationUtil;
import me.moomoo.anarchyexploitfixes.utils.MaterialUtil;
import net.kyori.adventure.text.Component;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package me.moomoo.anarchyexploitfixes.modules.elytra;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import me.moomoo.anarchyexploitfixes.AnarchyExploitFixes;
import me.moomoo.anarchyexploitfixes.config.Config;
import me.moomoo.anarchyexploitfixes.modules.AnarchyExploitFixesModule;
import me.moomoo.anarchyexploitfixes.utils.LocationUtil;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityToggleGlideEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.util.NumberConversions;

import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

public class ElytraHelper implements AnarchyExploitFixesModule, Listener {
private static ElytraHelper instance;
public static final double SPEED_TOLERANCE = 0.02;

private final AnarchyExploitFixes plugin;
private final boolean calculate3D;

private final Set<UUID> PLAYERS_GLIDING;
private final Set<UUID> PLAYERS_NEAR_NEW_CHUNKS;
private ScheduledTask scheduledSpeedCheck;
private final Cache<UUID, Double> PLAYER_SPEEDS;
private final Cache<UUID, Location> LAST_GLIDE_POS;
private final int checkIntervalTicks;
private final boolean doIntervalCheck;

public ElytraHelper() {
instance = this;
this.plugin = AnarchyExploitFixes.getInstance();
this.calculate3D = AnarchyExploitFixes.getConfiguration().elytra_calculate_3D;
this.PLAYERS_GLIDING = plugin.getServer().getOnlinePlayers().stream()
.filter(LivingEntity::isGliding)
.map(Player::getUniqueId)
.collect(Collectors.toCollection(HashSet::new));
this.PLAYERS_NEAR_NEW_CHUNKS = new HashSet<>(plugin.getServer().getOnlinePlayers().size());
Config config = AnarchyExploitFixes.getConfiguration();
this.doIntervalCheck = config.getBoolean("elytra.patch-generic-speedhacks.enable", true,
"Patches speed-limit bypass using generic speedhacks (Timer) by additionally checking player position every x ticks");
final int tickInterval = config.getInt("elytra.patch-generic-speedhacks.check-interval-in-ticks", 10,
"Lower value means more accuracy but also more overhead.");
this.checkIntervalTicks = Math.max(tickInterval, 1);
final Duration cacheTime = Duration.ofMillis(Math.max(1000, (tickInterval * 50L) + 100L));
this.PLAYER_SPEEDS = Caffeine.newBuilder().expireAfterWrite(cacheTime).build();
this.LAST_GLIDE_POS = Caffeine.newBuilder().expireAfterWrite(cacheTime).build();
}

public static ElytraHelper getInstance() {
return instance;
}

@Override
public String name() {
return "elytra-helper";
}

@Override
public String category() {
return "elytra";
}

@Override
public void enable() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.scheduledSpeedCheck = plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin,
scheduleChecks -> this.run(), checkIntervalTicks, checkIntervalTicks);
}

@Override
public boolean shouldEnable() {
Config config = AnarchyExploitFixes.getConfiguration();
return config.elytra_enable_at_spawn || config.elytra_enable_global || config.elytra_enable_netherceiling;
}

@Override
public void disable() {
HandlerList.unregisterAll(this);
if (scheduledSpeedCheck != null) scheduledSpeedCheck.cancel();
}

public Location getFrom(PlayerMoveEvent event) {
final Location lastGlidePos = LAST_GLIDE_POS.getIfPresent(event.getPlayer().getUniqueId());
return lastGlidePos != null ? lastGlidePos : event.getFrom();
}

public double getBlocksPerTick(PlayerMoveEvent event) {
double eventSpeed = calculate3D ? LocationUtil.getRelDistance3D(event.getTo(), event.getFrom()) : LocationUtil.getRelDistance2D(event.getTo(), event.getFrom());
if (doIntervalCheck) {
Double speedInterval = PLAYER_SPEEDS.getIfPresent(event.getPlayer().getUniqueId());
if (speedInterval != null) return Math.max(speedInterval, eventSpeed);
}
return eventSpeed;
}

public boolean isInNewChunks(UUID playerUniqueId) {
return PLAYERS_NEAR_NEW_CHUNKS.contains(playerUniqueId);
}

public boolean isGliding(Player player) {
return PLAYERS_GLIDING.contains(player.getUniqueId()) || player.isGliding();
}

private void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
player.getScheduler().run(plugin, checkFlight -> {
if (isGliding(player)) {
Location currentLocation = player.getLocation().clone();
Location lastLocation = this.LAST_GLIDE_POS.getIfPresent(player.getUniqueId());
if (lastLocation != null) this.PLAYER_SPEEDS.put(
player.getUniqueId(),
calculate3D ? LocationUtil.getRelDistance3D(lastLocation, currentLocation) : LocationUtil.getRelDistance2D(lastLocation, currentLocation) / checkIntervalTicks
);
this.LAST_GLIDE_POS.put(player.getUniqueId(), currentLocation);
}
}, null);
}
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
private void onGlideToggle(EntityToggleGlideEvent event) {
if (event.getEntityType() == EntityType.PLAYER) {
if (event.isGliding()) {
this.PLAYERS_GLIDING.add(event.getEntity().getUniqueId());
} else {
this.PLAYERS_GLIDING.remove(event.getEntity().getUniqueId());
}
}
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
private void onQuit(PlayerQuitEvent event) {
this.PLAYERS_GLIDING.remove(event.getPlayer().getUniqueId());
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
private void onJoin(PlayerJoinEvent event) {
if (event.getPlayer().isGliding()) {
this.PLAYERS_GLIDING.add(event.getPlayer().getUniqueId());
} else {
this.PLAYERS_GLIDING.remove(event.getPlayer().getUniqueId());
}
}

@EventHandler(priority = EventPriority.LOWEST)
private void onChunkLoad(ChunkLoadEvent event) {
for (Player player : event.getWorld().getPlayers()) {
if (this.getChunkDistanceSquared(event.getChunk(), player.getLocation().clone()) < NumberConversions.square(player.getViewDistance())) {
if (event.isNewChunk()) {
this.PLAYERS_NEAR_NEW_CHUNKS.add(player.getUniqueId());
} else {
this.PLAYERS_NEAR_NEW_CHUNKS.remove(player.getUniqueId());
}
}
}
}

/**
* Since the distance here is only used to see whether a chunk is loaded roughly within the player's view distance,
* we can resort to comparing squared distances.
* This saves cpu usage as we don't have to use {@link Math#sqrt(double)} to get the accurate distance in chunks.
*/
private double getChunkDistanceSquared(Chunk chunk, Location location) {
return NumberConversions.square(chunk.getX() - location.getBlockX() >> 4) + NumberConversions.square(chunk.getZ() - location.getBlockZ() >> 4);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import me.moomoo.anarchyexploitfixes.config.Config;
import me.moomoo.anarchyexploitfixes.config.LanguageCache;
import me.moomoo.anarchyexploitfixes.modules.AnarchyExploitFixesModule;
import me.moomoo.anarchyexploitfixes.modules.elytra.helper.ElytraHelper;
import me.moomoo.anarchyexploitfixes.utils.LocationUtil;
import me.moomoo.anarchyexploitfixes.utils.MaterialUtil;
import net.kyori.adventure.text.Component;
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 2c10c64

Please sign in to comment.