Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.thenextlvl.portals.action;

import net.thenextlvl.binder.StaticBinder;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Unmodifiable;

Expand All @@ -11,7 +13,8 @@
*
* @since 0.1.0
*/
public sealed interface ActionTypeRegistry permits SimpleActionTypeRegistry {
@ApiStatus.NonExtendable
public interface ActionTypeRegistry {
/**
* Gets the action type registry.
*
Expand All @@ -20,7 +23,7 @@ public sealed interface ActionTypeRegistry permits SimpleActionTypeRegistry {
*/
@Contract(pure = true)
static ActionTypeRegistry registry() {
return SimpleActionTypeRegistry.INSTANCE;
return StaticBinder.getInstance(ActionTypeRegistry.class.getClassLoader()).find(ActionTypeRegistry.class);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package net.thenextlvl.portals.action;

import net.thenextlvl.binder.StaticBinder;
import net.thenextlvl.portals.PortalLike;
import net.thenextlvl.portals.model.Bounds;
import org.bukkit.Location;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;

import java.net.InetSocketAddress;
Expand All @@ -12,7 +14,8 @@
*
* @since 0.1.0
*/
public sealed interface ActionTypes permits SimpleActionTypes {
@ApiStatus.NonExtendable
public interface ActionTypes {
/**
* Gets the action type registry.
*
Expand All @@ -21,7 +24,7 @@ public sealed interface ActionTypes permits SimpleActionTypes {
*/
@Contract(pure = true)
static ActionTypes types() {
return SimpleActionTypes.INSTANCE;
return StaticBinder.getInstance(ActionTypes.class.getClassLoader()).find(ActionTypes.class);
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/net/thenextlvl/portals/PortalsPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
import net.kyori.adventure.key.Key;
import net.thenextlvl.binder.StaticBinder;
import net.thenextlvl.nbt.serialization.NBT;
import net.thenextlvl.portals.action.ActionTypeRegistry;
import net.thenextlvl.portals.action.ActionTypes;
import net.thenextlvl.portals.action.EntryAction;
import net.thenextlvl.portals.action.SimpleActionTypeRegistry;
import net.thenextlvl.portals.action.SimpleActionTypes;
import net.thenextlvl.portals.adapter.BoundingBoxAdapter;
import net.thenextlvl.portals.adapter.EntryActionAdapter;
import net.thenextlvl.portals.adapter.KeyAdapter;
Expand Down Expand Up @@ -53,6 +57,8 @@ public final class PortalsPlugin extends JavaPlugin {
.build();

public PortalsPlugin() {
StaticBinder.getInstance(ActionTypes.class.getClassLoader()).bind(ActionTypes.class, SimpleActionTypes.INSTANCE);
StaticBinder.getInstance(ActionTypeRegistry.class.getClassLoader()).bind(ActionTypeRegistry.class, SimpleActionTypeRegistry.INSTANCE);
StaticBinder.getInstance(PortalConfig.class.getClassLoader()).bind(PortalConfig.class, portalConfig);
StaticBinder.getInstance(PortalProvider.class.getClassLoader()).bind(PortalProvider.class, portalProvider);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package net.thenextlvl.portals.action;

import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

final class SimpleActionTypeRegistry implements ActionTypeRegistry {
public static final ActionTypeRegistry INSTANCE = new SimpleActionTypeRegistry();
@NullMarked
public final class SimpleActionTypeRegistry implements ActionTypeRegistry {
public static final SimpleActionTypeRegistry INSTANCE = new SimpleActionTypeRegistry();

private final Set<ActionType<?>> actionTypes = new HashSet<>(Set.of(
ActionTypes.types().connect(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import core.paper.messenger.PluginMessenger;
import io.papermc.paper.entity.TeleportFlag;
import net.thenextlvl.portals.PortalLike;
import net.thenextlvl.portals.listener.PortalListener;
import net.thenextlvl.portals.model.Bounds;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.jspecify.annotations.NullMarked;

import java.net.InetSocketAddress;
import java.util.concurrent.ThreadLocalRandom;

final class SimpleActionTypes implements ActionTypes {
@NullMarked
public final class SimpleActionTypes implements ActionTypes {
public static final SimpleActionTypes INSTANCE = new SimpleActionTypes();

private final PluginMessenger messenger = new PluginMessenger(JavaPlugin.getProvidingPlugin(SimpleActionTypes.class));
Expand Down Expand Up @@ -103,7 +106,9 @@ final class SimpleActionTypes implements ActionTypes {
dest[tW] = tMin[tW] + fw * tSize[tW];

var destination = new Location(targetPortal.getWorld(), dest[0], dest[1], dest[2]).setRotation(from.getRotation());
entity.teleportAsync(destination, PlayerTeleportEvent.TeleportCause.PLUGIN, TeleportFlag.Relative.values());
entity.teleportAsync(destination, PlayerTeleportEvent.TeleportCause.PLUGIN, TeleportFlag.Relative.values()).thenAccept(success -> {
if (success) PortalListener.setLastPortal(entity, targetPortal);
});
return true;

}).orElse(false);
Expand Down
75 changes: 30 additions & 45 deletions src/main/java/net/thenextlvl/portals/listener/PortalListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.jspecify.annotations.NullMarked;

Expand All @@ -25,26 +23,15 @@

@NullMarked
public final class PortalListener implements Listener {
private static final Map<Portal, Map<UUID, Instant>> lastEntry = new HashMap<>();
private static final Map<UUID, Portal> lastPortal = new HashMap<>();

private final PortalsPlugin plugin;
private final Map<Portal, Map<UUID, Instant>> lastEntry = new HashMap<>();
private final Map<UUID, Portal> lastPortal = new HashMap<>();

public PortalListener(PortalsPlugin plugin) {
this.plugin = plugin;
}

private boolean hasCooldown(Portal portal, Entity entity) {
var entries = this.lastEntry.get(portal);
if (entries == null) return false;
var lastEntry = entries.get(entity.getUniqueId());
return lastEntry != null && Instant.now().isBefore(lastEntry.plus(portal.getCooldown()));
}

private void setLastEntry(Portal portal, Entity entity) {
lastEntry.computeIfAbsent(portal, ignored -> new HashMap<>())
.put(entity.getUniqueId(), Instant.now());
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEntityMove(EntityMoveEvent event) {
if (!event.hasChangedPosition()) return;
Expand All @@ -62,24 +49,6 @@ public void onPlayerMove(PlayerMoveEvent event) {
event.setCancelled(true);
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
processTeleport(event.getPlayer(), event.getTo());
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onEntityTeleport(EntityTeleportEvent event) {
var to = event.getTo() != null ? event.getTo() : event.getEntity().getLocation();
processTeleport(event.getEntity(), to);
}

private void processTeleport(Entity entity, Location to) {
var boundingBox = translate(entity.getBoundingBox(), to);
plugin.portalProvider().getPortals(to.getWorld())
.filter(portal -> portal.getBoundingBox().overlaps(boundingBox))
.findAny().ifPresent(portal -> lastPortal.put(entity.getUniqueId(), portal));
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
if (event.isSneaking()) return;
Expand Down Expand Up @@ -110,7 +79,7 @@ private boolean processMovement(Entity entity, Location to) {
if (!new EntityPortalEnterEvent(portal, entity).callEvent()) return false;

if (portal.getCooldown().isPositive()) setLastEntry(portal, entity);
lastPortal.put(entity.getUniqueId(), portal);
setLastPortal(entity, portal);

return portal.getEntryAction().map(action -> action.onEntry(entity, portal)).orElse(true);
}).orElseGet(() -> {
Expand All @@ -120,16 +89,6 @@ private boolean processMovement(Entity entity, Location to) {
});
}

private org.bukkit.util.BoundingBox translate(org.bukkit.util.BoundingBox boundingBox, Location location) {
var widthX = boundingBox.getWidthX() / 2;
var widthZ = boundingBox.getWidthZ() / 2;

return new org.bukkit.util.BoundingBox(
location.getX() - widthX, location.getY(), location.getZ() - widthZ,
location.getX() + widthX, location.getY() + boundingBox.getHeight(), location.getZ() + widthZ
);
}

private void pushAway(Entity entity, Location to) {
if (!plugin.config().pushBackOnEntryDenied()) return;
entity.getScheduler().run(plugin, task -> {
Expand All @@ -143,4 +102,30 @@ private boolean withdrawEntryCost(Portal portal, Entity entity) {
if (!(entity instanceof Player player)) return true;
return plugin.economyProvider().withdraw(player, portal.getEntryCost());
}

public static void setLastPortal(Entity entity, Portal portal) {
lastPortal.put(entity.getUniqueId(), portal);
}

private static org.bukkit.util.BoundingBox translate(org.bukkit.util.BoundingBox boundingBox, Location location) {
var widthX = boundingBox.getWidthX() / 2;
var widthZ = boundingBox.getWidthZ() / 2;

return new org.bukkit.util.BoundingBox(
location.getX() - widthX, location.getY(), location.getZ() - widthZ,
location.getX() + widthX, location.getY() + boundingBox.getHeight(), location.getZ() + widthZ
);
}

private static boolean hasCooldown(Portal portal, Entity entity) {
var entries = lastEntry.get(portal);
if (entries == null) return false;
var lastEntry = entries.get(entity.getUniqueId());
return lastEntry != null && Instant.now().isBefore(lastEntry.plus(portal.getCooldown()));
}

private static void setLastEntry(Portal portal, Entity entity) {
lastEntry.computeIfAbsent(portal, ignored -> new HashMap<>())
.put(entity.getUniqueId(), Instant.now());
}
}