Skip to content

Commit

Permalink
add portalgodmode, closing #157
Browse files Browse the repository at this point in the history
  • Loading branch information
xGinko committed Aug 10, 2024
1 parent ba25088 commit 85851bf
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package me.xginko.aef.modules.combat;

import com.cryptomorin.xseries.XEntityType;
import com.cryptomorin.xseries.XMaterial;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import me.xginko.aef.modules.AEFModule;
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.EntityPortalEnterEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.time.Duration;
import java.util.UUID;

public class PortalGodMode extends AEFModule implements Listener {

private final Cache<UUID, ScheduledTask> playersWaitingForPortalTeleport;
private final long delayTicks;

public PortalGodMode() {
super("combat.portal-god-mode-patch");
config.addComment(configPath + ".enable", """
Patches an exploit that allows players to stand in portals and not take\s
damage indefinitely by just never sending a TeleportAccept packet to the\s
server.\s
A similar method is used for the chorus tp exploit, which is not covered\s
by this module.""");
this.delayTicks = config.getInt(".destroy-portal-delay-ticks", 100, """
If the player stays inside the nether portal for this time without teleporting,\s
the portal will be broken.""");
this.playersWaitingForPortalTeleport = Caffeine.newBuilder()
.expireAfterWrite(Duration.ofMillis((delayTicks * 50L) + 1000L)).build();
}

@Override
public void enable() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}

@Override
public boolean shouldEnable() {
return config.getBoolean(configPath + ".enable", false);
}

@Override
public void disable() {
HandlerList.unregisterAll(this);
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onEntityPortalEnter(EntityPortalEnterEvent event) {
if (event.getEntityType() != XEntityType.PLAYER.get()) return;

if (playersWaitingForPortalTeleport.getIfPresent(event.getEntity().getUniqueId()) != null) return;

playersWaitingForPortalTeleport.put(event.getEntity().getUniqueId(),
plugin.getServer().getRegionScheduler().runDelayed(plugin, event.getLocation(), breakPortal -> {
event.getLocation().getBlock().setType(XMaterial.AIR.parseMaterial(), true);
playersWaitingForPortalTeleport.invalidate(event.getEntity().getUniqueId());
}, delayTicks));
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.getCause() != PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) return;

@Nullable ScheduledTask breakPortalTask = playersWaitingForPortalTeleport.getIfPresent(event.getPlayer().getUniqueId());

if (breakPortalTask != null) {
breakPortalTask.cancel();
playersWaitingForPortalTeleport.invalidate(event.getPlayer().getUniqueId());
}
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onPlayerMove(PlayerMoveEvent event) {
@Nullable ScheduledTask breakPortalTask = playersWaitingForPortalTeleport.getIfPresent(event.getPlayer().getUniqueId());
if (breakPortalTask == null) return;

if (event.getTo().getBlock().getType() != XMaterial.NETHER_PORTAL.parseMaterial()) {
breakPortalTask.cancel();
playersWaitingForPortalTeleport.invalidate(event.getPlayer().getUniqueId());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUpdateSign;
import me.xginko.aef.AnarchyExploitFixes;
import me.xginko.aef.utils.models.ExpiringSet;

import java.time.Duration;
Expand Down Expand Up @@ -35,7 +34,7 @@ public SignLag() {

@Override
public boolean shouldEnable() {
return AnarchyExploitFixes.config().getBoolean(configPath + ".enable", true);
return config.getBoolean(configPath + ".enable", true);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package me.xginko.aef.modules.combat;

import com.cryptomorin.xseries.XEntityType;
import com.cryptomorin.xseries.XMaterial;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import me.xginko.aef.modules.AEFModule;
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.EntityPortalEnterEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.scheduler.BukkitTask;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.time.Duration;
import java.util.UUID;

public class PortalGodMode extends AEFModule implements Listener {

private final Cache<UUID, BukkitTask> playersWaitingForPortalTeleport;
private final long delayTicks;

public PortalGodMode() {
super("combat.portal-god-mode-patch");
config.addComment(configPath + ".enable",
"Patches an exploit that allows players to stand in portals and not take \n" +
"damage indefinitely by just never sending a TeleportAccept packet to the \n" +
"server. \n" +
"A similar method is used for the chorus tp exploit, which is not covered \n" +
"by this module.");
this.delayTicks = config.getInt(".destroy-portal-delay-ticks", 100,
"If the player stays inside the nether portal for this time without teleporting, \n" +
"the portal will be broken.");
this.playersWaitingForPortalTeleport = Caffeine.newBuilder()
.expireAfterWrite(Duration.ofMillis((delayTicks * 50L) + 1000L)).build();
}

@Override
public void enable() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}

@Override
public boolean shouldEnable() {
return config.getBoolean(configPath + ".enable", false);
}

@Override
public void disable() {
HandlerList.unregisterAll(this);
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onEntityPortalEnter(EntityPortalEnterEvent event) {
if (event.getEntityType() != XEntityType.PLAYER.get()) return;

if (playersWaitingForPortalTeleport.getIfPresent(event.getEntity().getUniqueId()) != null) return;

playersWaitingForPortalTeleport.put(event.getEntity().getUniqueId(),
plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
event.getLocation().getBlock().setType(XMaterial.AIR.parseMaterial(), true);
playersWaitingForPortalTeleport.invalidate(event.getEntity().getUniqueId());
}, delayTicks));
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.getCause() != PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) return;

@Nullable BukkitTask breakPortalTask = playersWaitingForPortalTeleport.getIfPresent(event.getPlayer().getUniqueId());

if (breakPortalTask != null) {
breakPortalTask.cancel();
playersWaitingForPortalTeleport.invalidate(event.getPlayer().getUniqueId());
}
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onPlayerMove(PlayerMoveEvent event) {
@Nullable BukkitTask breakPortalTask = playersWaitingForPortalTeleport.getIfPresent(event.getPlayer().getUniqueId());
if (breakPortalTask == null) return;

if (event.getTo().getBlock().getType() != XMaterial.NETHER_PORTAL.parseMaterial()) {
breakPortalTask.cancel();
playersWaitingForPortalTeleport.invalidate(event.getPlayer().getUniqueId());
}
}
}

0 comments on commit 85851bf

Please sign in to comment.