Skip to content

Commit

Permalink
Prevents exiting border at speed.
Browse files Browse the repository at this point in the history
  • Loading branch information
tastybento committed Jan 11, 2021
1 parent ae0dd59 commit f0a1a7b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
22 changes: 20 additions & 2 deletions src/main/java/world/bentobox/border/Border.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package world.bentobox.border;

import java.util.ArrayList;
import java.util.List;

import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;

import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.configuration.Config;
import world.bentobox.bentobox.util.Util;
import world.bentobox.border.commands.IslandBorderCommand;
import world.bentobox.border.listeners.PlayerBorder;
import world.bentobox.border.listeners.PlayerListener;
Expand All @@ -16,6 +24,8 @@ public final class Border extends Addon {

private Config<Settings> config = new Config<>(this, Settings.class);

private @NonNull List<GameModeAddon> gameModes = new ArrayList<>();

@Override
public void onLoad() {
// Save default config.yml
Expand All @@ -26,13 +36,14 @@ public void onLoad() {

@Override
public void onEnable() {
gameModes.clear();
// Register commands
getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> {

if (!this.settings.getDisabledGameModes().contains(
gameModeAddon.getDescription().getName())) {
if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName())) {

hooked = true;
gameModes.add(gameModeAddon);

log("Border hooking into " + gameModeAddon.getDescription().getName());
gameModeAddon.getPlayerCommand().ifPresent(c -> new IslandBorderCommand(this, c, "border"));
Expand Down Expand Up @@ -78,4 +89,11 @@ public Settings getSettings() {
return this.settings;
}

/**
* @param world
* @return true if world is being handled by Border
*/
public boolean inGameWorld(World world) {
return gameModes.stream().anyMatch(gm -> gm.inWorld(Util.getWorld(world)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public void showBarrier(Player player, Island island) {
if (!User.getInstance(player).getMetaData(BORDER_STATE_META_DATA).map(MetaDataValue::asBoolean).orElse(addon.getSettings().isShowByDefault())) {
return;
}

// Get the locations to show
Location loc = player.getLocation();
int xMin = island.getMinProtectedX();
Expand Down Expand Up @@ -156,6 +157,8 @@ private void teleportPlayer(Player p) {
Vector unitVector = i.getCenter().toVector().subtract(p.getLocation().toVector()).normalize()
.multiply(new Vector(1,0,1));
p.setVelocity(new Vector (0,0,0));
// Get distance from border

Location to = p.getLocation().toVector().add(unitVector).toLocation(p.getWorld());
to.setPitch(p.getLocation().getPitch());
to.setYaw(p.getLocation().getYaw());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package world.bentobox.border.listeners;

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

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;

import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
Expand All @@ -23,10 +30,13 @@
*/
public class PlayerListener implements Listener {

private static final Vector XZ = new Vector(1,0,1);
private final Border addon;
private Set<UUID> inTeleport;

public PlayerListener(Border addon) {
this.addon = addon;
inTeleport = new HashSet<>();
}

@EventHandler(priority = EventPriority.NORMAL)
Expand All @@ -35,7 +45,7 @@ public void onPlayerJoin(PlayerJoinEvent e) {
addon.getIslands().getProtectedIslandAt(e.getPlayer().getLocation()).ifPresent(i ->
addon.getPlayerBorder().showBarrier(e.getPlayer(), i));
}

@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerQuit(PlayerQuitEvent e) {
addon.getPlayerBorder().clearUser(User.getInstance(e.getPlayer()));
Expand All @@ -56,6 +66,52 @@ public void onPlayerTeleport(PlayerTeleportEvent e) {
addon.getPlayerBorder().showBarrier(e.getPlayer(), i)));
}

@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerLeaveIsland(PlayerMoveEvent e) {
Player p = e.getPlayer();
Location from = e.getFrom();
if (!outsideCheck(e.getPlayer(), from, e.getTo())) {
return;
}
// Move the player back inside the border
if (addon.getIslands().getProtectedIslandAt(from).isPresent()) {
e.setCancelled(true);
inTeleport.add(p.getUniqueId());
Util.teleportAsync(p, from).thenRun(() -> inTeleport.remove(p.getUniqueId()));
return;
}
// Backtrack
addon.getIslands().getIslandAt(p.getLocation()).ifPresent(i -> {
Vector unitVector = i.getCenter().toVector().subtract(p.getLocation().toVector()).normalize()
.multiply(new Vector(1,0,1));
RayTraceResult r = i.getProtectionBoundingBox().rayTrace(p.getLocation().toVector(), unitVector, i.getRange());
if (r != null) {
inTeleport.add(p.getUniqueId());
Util.teleportAsync(p, r.getHitPosition().toLocation(p.getWorld(), p.getLocation().getYaw(), p.getLocation().getPitch()))
.thenRun(() -> {
addon.getPlugin().logDebug("Teleport done");
inTeleport.remove(p.getUniqueId());
});
}
});


}

private boolean outsideCheck(Player player, Location from, Location to) {
User user = User.getInstance(player);
// Only process if there is a change in X or Z coords
if ((from.getWorld() != null && from.getWorld().equals(to.getWorld())
&& from.toVector().multiply(XZ).equals(to.toVector().multiply(XZ)))
|| !addon.getSettings().isUseBarrierBlocks()
|| !addon.inGameWorld(player.getWorld())
|| !addon.getIslands().getIslandAt(to).filter(i -> addon.getIslands().locationIsOnIsland(player, i.getCenter())).isPresent()
|| !user.getMetaData(PlayerBorder.BORDER_STATE_META_DATA).map(md -> md.asBoolean()).orElse(addon.getSettings().isShowByDefault())) {
return false;
}
return addon.getIslands().getIslandAt(to).filter(i -> !i.onIsland(to)).isPresent();
}

/**
* Teleports a player back home if they use a vehicle to glitch out of the world border
* @param event - event
Expand Down

0 comments on commit f0a1a7b

Please sign in to comment.