-
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
494 additions
and
489 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 153 additions & 0 deletions
153
...itFixesFolia/src/main/java/me/moomoo/anarchyexploitfixes/modules/elytra/ElytraHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package me.moomoo.anarchyexploitfixes.modules.elytra; | ||
|
||
import com.github.benmanes.caffeine.cache.Cache; | ||
import com.github.benmanes.caffeine.cache.Caffeine; | ||
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.apache.commons.math3.util.FastMath; | ||
import org.bukkit.Chunk; | ||
import org.bukkit.Location; | ||
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.player.PlayerJoinEvent; | ||
import org.bukkit.event.player.PlayerMoveEvent; | ||
import org.bukkit.event.world.ChunkLoadEvent; | ||
|
||
import java.time.Duration; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
|
||
public class ElytraHelper implements AnarchyExploitFixesModule, Listener { | ||
private static ElytraHelper instance; | ||
private final AnarchyExploitFixes plugin; | ||
private final Set<UUID> PLAYERS_NEAR_NEW_CHUNKS; | ||
private final Cache<UUID, Double> PLAYER_SPEEDS_MOVE_EVENT; | ||
private final Cache<UUID, Double> PLAYER_SPEEDS_INTERVAL; | ||
private final Cache<UUID, Location> LAST_GLIDE_POS; | ||
public static final double SPEED_TOLERANCE = 0.02; | ||
private final int checkIntervalTicks; | ||
private final boolean doIntervalCheck; | ||
|
||
public ElytraHelper() { | ||
instance = this; | ||
this.plugin = AnarchyExploitFixes.getInstance(); | ||
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 = tickInterval > 0 ? tickInterval : 1; | ||
final Duration cacheTime = Duration.ofMillis(FastMath.max(1000, tickInterval * 50L)); | ||
this.PLAYER_SPEEDS_MOVE_EVENT = Caffeine.newBuilder().expireAfterWrite(cacheTime).build(); | ||
this.PLAYER_SPEEDS_INTERVAL = 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); | ||
} | ||
|
||
@Override | ||
public boolean shouldEnable() { | ||
Config config = AnarchyExploitFixes.getConfiguration(); | ||
return config.getBoolean("elytra.elytra-speed.Global-Settings.enable", true) | ||
|| config.getBoolean("elytra.elytra-speed.At-Spawn.enable", false) | ||
|| config.getBoolean("elytra.elytra-speed.Nether-Ceiling.enable", true); | ||
} | ||
|
||
@Override | ||
public void disable() { | ||
HandlerList.unregisterAll(this); | ||
} | ||
|
||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) | ||
private void onPlayerJoin(PlayerJoinEvent event) { | ||
if (!doIntervalCheck) return; | ||
|
||
Player player = event.getPlayer(); | ||
player.getScheduler().runAtFixedRate(plugin, watchSpeed -> { | ||
if (player.isGliding()) { | ||
Location currentLocation = player.getLocation(); | ||
Location lastLocation = LAST_GLIDE_POS.getIfPresent(player.getUniqueId()); | ||
if (lastLocation == null) | ||
lastLocation = currentLocation; | ||
PLAYER_SPEEDS_INTERVAL.put(player.getUniqueId(), LocationUtil.getFlatDistance(lastLocation, currentLocation) / checkIntervalTicks); | ||
LAST_GLIDE_POS.put(player.getUniqueId(), currentLocation); | ||
} | ||
}, null, checkIntervalTicks, checkIntervalTicks); | ||
} | ||
|
||
@EventHandler(priority = EventPriority.LOW) | ||
private void onPlayerMove(PlayerMoveEvent event) { | ||
if (event.getPlayer().isGliding()) { | ||
PLAYER_SPEEDS_MOVE_EVENT.put(event.getPlayer().getUniqueId(), LocationUtil.getFlatDistance(event.getFrom(), event.getTo())); | ||
} | ||
} | ||
|
||
private double getFlatDistanceInChunks(Chunk chunk, Location location) { | ||
return FastMath.hypot(chunk.getX() - location.getBlockX() >> 4, chunk.getZ() - location.getBlockZ() >> 4); | ||
} | ||
|
||
@EventHandler(priority = EventPriority.LOW) | ||
private void onChunkLoad(ChunkLoadEvent event) { | ||
for (Player player : event.getWorld().getPlayers()) { | ||
if (this.getFlatDistanceInChunks(event.getChunk(), player.getLocation()) < player.getViewDistance()) { | ||
if (event.isNewChunk()) { | ||
PLAYERS_NEAR_NEW_CHUNKS.add(player.getUniqueId()); | ||
} else { | ||
PLAYERS_NEAR_NEW_CHUNKS.remove(player.getUniqueId()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
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) { | ||
final Double speedInterval = PLAYER_SPEEDS_INTERVAL.getIfPresent(event.getPlayer().getUniqueId()); | ||
final Double speedMoveEvent = PLAYER_SPEEDS_MOVE_EVENT.getIfPresent(event.getPlayer().getUniqueId()); | ||
|
||
if (speedInterval != null) { | ||
if (speedMoveEvent != null) { | ||
return FastMath.max(speedInterval, speedMoveEvent); | ||
} else { | ||
return speedInterval; | ||
} | ||
} else { | ||
if (speedMoveEvent != null) { | ||
return speedMoveEvent; | ||
} else { | ||
return LocationUtil.getFlatDistance(event.getFrom(), event.getTo()); | ||
} | ||
} | ||
} | ||
|
||
public boolean isInNewChunks(UUID playerUniqueId) { | ||
return PLAYERS_NEAR_NEW_CHUNKS.contains(playerUniqueId); | ||
} | ||
} |
Oops, something went wrong.