diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index 59d6c62..f289738 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -77,13 +77,17 @@ public class BlockLocation extends Location { } /** - * Makes a block location relative to the current location according to given parameters - * @param right

- * @param depth

The y position relative to the current position

- * @param distance

The distance away from the previous location to the new location

- * @param modX

x modifier. Defines movement along the x-axis. 0 for no movement

- * @param modY

- * @param modZ

z modifier. Defines movement along the z-axis. 0 for no movement

+ * Makes a block location relative to the current origin according to given parameters + * + *

See {@link RelativeBlockVector} to understand better. modX or modZ should always be 0 while the other is 1 + * or -1.

+ * + * @param right

The amount of right steps from the top-left origin

+ * @param depth

The amount of downward steps from the top-left origin

+ * @param distance

The distance outward from the top-left origin

+ * @param modX

X modifier. If modX = -1, X will increase as right increases

+ * @param modY

Y modifier. modY = 1 for Y decreasing as depth increases

+ * @param modZ

Z modifier. If modZ = 1, X will increase as distance increases

* @return A new location relative to this block location */ public BlockLocation modRelative(int right, int depth, int distance, int modX, int modY, int modZ) { diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index a499453..6a64aed 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -232,23 +232,27 @@ public class Gate { return toOwner; } - public boolean matches(BlockLocation topleft, int modX, int modZ) { - return matches(topleft, modX, modZ, false); + public boolean matches(BlockLocation topLeft, int modX, int modZ) { + return matches(topLeft, modX, modZ, false); } - public boolean matches(BlockLocation topleft, int modX, int modZ, boolean onCreate) { + public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) { HashMap portalTypes = new HashMap<>(types); for (int y = 0; y < layout.length; y++) { for (int x = 0; x < layout[y].length; x++) { Character key = layout[y][x]; if (key.equals(ENTRANCE) || key.equals(EXIT)) { - if (Stargate.ignoreEntrance) continue; + if (Stargate.ignoreEntrance) { + continue; + } - Material type = topleft.modRelative(x, y, 0, modX, 1, modZ).getType(); + Material type = topLeft.modRelative(x, y, 0, modX, 1, modZ).getType(); // Ignore entrance if it's air and we're creating a new gate - if (onCreate && type == Material.AIR) continue; + if (onCreate && type == Material.AIR) { + continue; + } if (type != portalBlockClosed && type != portalBlockOpen) { Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); @@ -257,9 +261,9 @@ public class Gate { } else if (!key.equals(ANYTHING)) { Material id = portalTypes.get(key); if (id == null) { - portalTypes.put(key, topleft.modRelative(x, y, 0, modX, 1, modZ).getType()); - } else if (topleft.modRelative(x, y, 0, modX, 1, modZ).getType() != id) { - Stargate.debug("Gate::Matches", "Block Type Mismatch: " + topleft.modRelative(x, y, 0, modX, 1, modZ).getType() + " != " + id); + portalTypes.put(key, topLeft.modRelative(x, y, 0, modX, 1, modZ).getType()); + } else if (topLeft.modRelative(x, y, 0, modX, 1, modZ).getType() != id) { + Stargate.debug("Gate::Matches", "Block Type Mismatch: " + topLeft.modRelative(x, y, 0, modX, 1, modZ).getType() + " != " + id); return false; } } diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index 4b9db19..f46f100 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -15,16 +15,16 @@ import org.bukkit.block.Sign; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Powerable; +import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; -import org.bukkit.entity.minecart.StorageMinecart; +import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Random; import java.util.UUID; @@ -287,7 +287,7 @@ public class Portal { public Portal getDestination(Player player) { if (isRandom()) { - destinations = PortalHandler.getDestinations(player, getNetwork()); + destinations = PortalHandler.getDestinations(this, player, getNetwork()); if (destinations.size() == 0) { return null; } @@ -464,6 +464,10 @@ public class Portal { return (player != null) && (player.getName().equalsIgnoreCase(this.player.getName())); } + /** + * Gets whether this portal points to a fixed exit portal + * @return

True if this portal points to a fixed exit portal

+ */ public boolean isFixed() { return fixed; } @@ -482,27 +486,34 @@ public class Portal { return false; } + /** + * Teleports a player to this portal + * @param player

The player to teleport

+ * @param origin

The portal the player teleports from

+ * @param event

The player move event triggering the event

+ */ public void teleport(Player player, Portal origin, PlayerMoveEvent event) { Location traveller = player.getLocation(); - Location exit = getExit(traveller); + Location exit = getExit(player, traveller); - // Handle backwards gates + //Rotate the player to face out from the portal int adjust = 180; - if (isBackwards() != origin.isBackwards()) + if (isBackwards() != origin.isBackwards()) { adjust = 0; + } exit.setYaw(traveller.getYaw() - origin.getRotation() + this.getRotation() + adjust); // Call the StargatePortalEvent to allow plugins to change destination if (!origin.equals(this)) { - StargatePortalEvent pEvent = new StargatePortalEvent(player, origin, this, exit); - Stargate.server.getPluginManager().callEvent(pEvent); + StargatePortalEvent stargatePortalEvent = new StargatePortalEvent(player, origin, this, exit); + Stargate.server.getPluginManager().callEvent(stargatePortalEvent); // Teleport is cancelled - if (pEvent.isCancelled()) { + if (stargatePortalEvent.isCancelled()) { origin.teleport(player, origin, event); return; } // Update exit if needed - exit = pEvent.getExit(); + exit = stargatePortalEvent.getExit(); } // If no event is passed in, assume it's a teleport, and act as such @@ -515,10 +526,15 @@ public class Portal { } } + /** + * Teleports a vehicle to this portal + * @param vehicle

The vehicle to teleport

+ */ public void teleport(final Vehicle vehicle) { Location traveller = new Location(this.world, vehicle.getLocation().getX(), vehicle.getLocation().getY(), vehicle.getLocation().getZ()); - Location exit = getExit(traveller); + Stargate.log.info(Stargate.getString("prefix") + "Location of vehicle is " + traveller); + Location exit = getExit(vehicle, traveller); double velocity = vehicle.getVelocity().length(); @@ -535,62 +551,95 @@ public class Portal { Stargate.log.warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); return; } - Vehicle mineCart = vehicleWorld.spawn(exit, vehicle.getClass()); if (!passengers.isEmpty()) { - final Entity passenger = passengers.get(0); - vehicle.eject(); - vehicle.remove(); - passenger.eject(); - passenger.teleport(exit); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> { - mineCart.addPassenger(passenger); - mineCart.setVelocity(newVelocity); - }, 1); - } else { - if (mineCart instanceof StorageMinecart) { - StorageMinecart storageMinecart = (StorageMinecart) mineCart; - storageMinecart.getInventory().setContents(((StorageMinecart) vehicle).getInventory().getContents()); + if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { + putPlayerInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); + return; } - Stargate.log.info(Stargate.getString("prefix") + "Teleported minecart to " + mineCart.getLocation()); - vehicle.remove(); + vehicle.eject(); + handleVehiclePassengers(vehicle, passengers, vehicle, exit); + vehicle.teleport(exit); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.setVelocity(newVelocity), 3); + } else { + Stargate.log.info(Stargate.getString("prefix") + "Teleported vehicle to " + exit); + vehicle.teleport(exit); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> { - mineCart.setVelocity(newVelocity); + vehicle.setVelocity(newVelocity); }, 1); } } - public Location getExit(Location traveller) { - Location loc = null; + private void putPlayerInNewVehicle(Vehicle vehicle, List passengers, World vehicleWorld, Location exit, Vector newVelocity) { + Vehicle newVehicle = vehicleWorld.spawn(exit, vehicle.getClass()); + vehicle.eject(); + vehicle.remove(); + handleVehiclePassengers(vehicle, passengers, newVehicle, exit); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); + } + + private void handleVehiclePassengers(Vehicle sourceVehicle, List passengers, Vehicle targetVehicle, Location exit) { + for (Entity passenger : passengers) { + passenger.eject(); + Stargate.log.info("Teleporting passenger" + passenger + " to " + exit); + if (!passenger.teleport(exit)) { + Stargate.log.info("Failed to teleport passenger"); + } + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> targetVehicle.addPassenger(passenger), 1); + } + } + + /** + * Gets the exit location for a given entity and current location + * @param entity

The entity to teleport (used to determine distance from portal to avoid suffocation)

+ * @param traveller

The location of the entity travelling

+ * @return

The location the entity should be teleported to.

+ */ + public Location getExit(Entity entity, Location traveller) { + Location exitLocation = null; // Check if the gate has an exit block if (gate.getExit() != null) { BlockLocation exit = getBlockAt(gate.getExit()); int back = (isBackwards()) ? -1 : 1; - loc = exit.modRelativeLoc(0D, 0D, 1D, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); + double entitySize = Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ())); + exitLocation = exit.modRelativeLoc(0D, 0D, entitySize, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); } else { Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); } - if (loc != null) { - BlockData bd = getWorld().getBlockAt(loc).getBlockData(); - if (bd instanceof Bisected && ((Bisected) bd).getHalf() == Bisected.Half.BOTTOM) { - loc.add(0, 0.5, 0); + if (exitLocation != null) { + //Prevent traveller from spawning inside a slab + BlockData blockData = getWorld().getBlockAt(exitLocation).getBlockData(); + if (blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) { + exitLocation.add(0, 0.5, 0); } - loc.setPitch(traveller.getPitch()); - return loc; + exitLocation.setPitch(traveller.getPitch()); + return exitLocation; + } else { + Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Unable to generate exit location"); } return traveller; } + /** + * Checks whether the chunk the portal is located at is loaded + * @return

True if the chunk containing the portal is loaded

+ */ public boolean isChunkLoaded() { + //TODO: Improve this in the case where the portal sits between two chunks return getWorld().isChunkLoaded(topLeft.getBlock().getChunk()); } + /** + * Gets the identity (sign) location of the portal + * @return

The identity location of the portal

+ */ public BlockLocation getId() { return this.id; } + public int getModX() { return this.modX; } @@ -603,10 +652,18 @@ public class Portal { return this.rotX; } + /** + * Gets the location of the top-left block of the portal + * @return

The location of the top-left portal block

+ */ public BlockLocation getTopLeft() { return this.topLeft; } + /** + * Verifies that all control blocks in this portal follows its gate template + * @return

True if all control blocks were verified

+ */ public boolean isVerified() { verified = true; if (!Stargate.verifyPortals) { @@ -618,6 +675,10 @@ public class Portal { return verified; } + /** + * Gets the result of the last portal verification + * @return

True if this portal was verified

+ */ public boolean wasVerified() { if (!Stargate.verifyPortals) { return true; @@ -625,6 +686,10 @@ public class Portal { return verified; } + /** + * Checks if all blocks in a gate matches the gate template + * @return

True if all blocks match the gate template

+ */ public boolean checkIntegrity() { if (!Stargate.verifyPortals) { return true; @@ -632,13 +697,18 @@ public class Portal { return gate.matches(topLeft, modX, modZ); } + /** + * Activates this portal for the given player + * @param player

The player to activate the portal for

+ * @return

True if the portal was activated

+ */ public boolean activate(Player player) { destinations.clear(); destination = ""; Stargate.activeList.add(this); activePlayer = player; String network = getNetwork(); - destinations = PortalHandler.getDestinations(player, network); + destinations = PortalHandler.getDestinations(this, player, network); if (Stargate.sortLists) { Collections.sort(destinations); } @@ -658,10 +728,15 @@ public class Portal { return true; } + /** + * Deactivates this portal + */ public void deactivate() { StargateDeactivateEvent event = new StargateDeactivateEvent(this); Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) { + return; + } Stargate.activeList.remove(this); if (isFixed()) { @@ -810,6 +885,11 @@ public class Portal { sign.update(); } + /** + * Gets the block at a relative block vector location + * @param vector

The relative block vector

+ * @return

The block at the given relative position

+ */ BlockLocation getBlockAt(RelativeBlockVector vector) { return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); } diff --git a/src/main/java/net/knarcraft/stargate/PortalHandler.java b/src/main/java/net/knarcraft/stargate/PortalHandler.java index d20aaa3..e3a5e11 100644 --- a/src/main/java/net/knarcraft/stargate/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/PortalHandler.java @@ -44,30 +44,44 @@ public class PortalHandler { /** * Gets all destinations in the network viewable by the given player + * @param entrancePortal

The portal the user is entering from

* @param player

The player who wants to see destinations

* @param network

The network to get destinations from

* @return

All destinations the player can go to

*/ - public static ArrayList getDestinations(Player player, String network) { + public static ArrayList getDestinations(Portal entrancePortal, Player player, String network) { ArrayList destinations = new ArrayList<>(); - for (String dest : allPortalsNet.get(network.toLowerCase())) { - Portal portal = getByName(dest, network); - if (portal == null) continue; - // Check if dest is a random gate - if (portal.isRandom()) continue; - // Check if dest is always open (Don't show if so) - if (portal.isAlwaysOn() && !portal.isShown()) continue; - // Check if dest is this portal - if (dest.equalsIgnoreCase(portal.getName())) continue; - // Check if dest is a fixed gate not pointing to this gate - if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(portal.getName())) continue; + for (String destination : allPortalsNet.get(network.toLowerCase())) { + Portal portal = getByName(destination, network); + if (portal == null) { + continue; + } + // Check if destination is a random gate + if (portal.isRandom()) { + continue; + } + // Check if destination is always open (Don't show if so) + if (portal.isAlwaysOn() && !portal.isShown()) { + continue; + } + // Check if destination is this portal + if (destination.equalsIgnoreCase(entrancePortal.getName())) { + continue; + } + // Check if destination is a fixed gate not pointing to this gate + if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(entrancePortal.getName())) { + continue; + } // Allow random use by non-players (Minecarts) if (player == null) { destinations.add(portal.getName()); continue; } // Check if this player can access the dest world - if (!Stargate.canAccessWorld(player, portal.getWorld().getName())) continue; + if (!Stargate.canAccessWorld(player, portal.getWorld().getName())) { + Stargate.log.info("cannot access world"); + continue; + } // Visible to this player. if (Stargate.canSee(player, portal)) { destinations.add(portal.getName()); @@ -81,7 +95,7 @@ public class PortalHandler { * @param portal

The portal to un-register

* @param removeAll

Whether to remove the portal from the list of all portals

*/ - public static void unregister(Portal portal, boolean removeAll) { + public static void unregisterPortal(Portal portal, boolean removeAll) { Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); portal.close(true); @@ -136,7 +150,7 @@ public class PortalHandler { * Registers a portal * @param portal

The portal to register

*/ - static void register(Portal portal) { + private static void registerPortal(Portal portal) { portal.setFixed(portal.getDestinationName().length() > 0 || portal.isRandom() || portal.isBungee()); // Bungee gates are stored in their own list @@ -200,15 +214,15 @@ public class PortalHandler { } BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); - BlockLocation topleft = null; + BlockLocation topLeft = null; String name = filterName(event.getLine(0)); - String destName = filterName(event.getLine(1)); + String destinationName = filterName(event.getLine(1)); String network = filterName(event.getLine(2)); String options = filterName(event.getLine(3)).toLowerCase(); boolean hidden = (options.indexOf('h') != -1); boolean alwaysOn = (options.indexOf('a') != -1); - boolean priv = (options.indexOf('p') != -1); + boolean isPrivate = (options.indexOf('p') != -1); boolean free = (options.indexOf('f') != -1); boolean backwards = (options.indexOf('b') != -1); boolean show = (options.indexOf('s') != -1); @@ -223,8 +237,8 @@ public class PortalHandler { if (alwaysOn && !Stargate.canOption(player, "alwayson")) { alwaysOn = false; } - if (priv && !Stargate.canOption(player, "private")) { - priv = false; + if (isPrivate && !Stargate.canOption(player, "private")) { + isPrivate = false; } if (free && !Stargate.canOption(player, "free")) { free = false; @@ -243,7 +257,7 @@ public class PortalHandler { } // Can not create a non-fixed always-on gate. - if (alwaysOn && destName.length() == 0) { + if (alwaysOn && destinationName.length() == 0) { alwaysOn = false; } @@ -268,24 +282,24 @@ public class PortalHandler { int modX = 0; int modZ = 0; float rotX = 0f; - BlockFace buttonfacing = BlockFace.DOWN; + BlockFace buttonFacing = BlockFace.DOWN; if (idParent.getX() > id.getBlock().getX()) { modZ -= 1; rotX = 90f; - buttonfacing = BlockFace.WEST; + buttonFacing = BlockFace.WEST; } else if (idParent.getX() < id.getBlock().getX()) { modZ += 1; rotX = 270f; - buttonfacing = BlockFace.EAST; + buttonFacing = BlockFace.EAST; } else if (idParent.getZ() > id.getBlock().getZ()) { modX += 1; rotX = 180f; - buttonfacing = BlockFace.NORTH; + buttonFacing = BlockFace.NORTH; } else if (idParent.getZ() < id.getBlock().getZ()) { modX -= 1; rotX = 0f; - buttonfacing = BlockFace.SOUTH; + buttonFacing = BlockFace.SOUTH; } Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); @@ -305,7 +319,7 @@ public class PortalHandler { if (gate == null) { if (possibility.matches(tl, modX, modZ, true)) { gate = possibility; - topleft = tl; + topLeft = tl; if (otherControl != null) { buttonVector = otherControl; @@ -333,14 +347,14 @@ public class PortalHandler { } else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); return null; - } else if (destName.isEmpty() || network.isEmpty()) { + } else if (destinationName.isEmpty() || network.isEmpty()) { Stargate.sendMessage(player, Stargate.getString("bungeeEmpty")); return null; } } // Debug - Stargate.debug("createPortal", "h = " + hidden + " a = " + alwaysOn + " p = " + priv + " f = " + free + " b = " + backwards + " s = " + show + " n = " + noNetwork + " r = " + random + " u = " + bungee); + Stargate.debug("createPortal", "h = " + hidden + " a = " + alwaysOn + " p = " + isPrivate + " f = " + free + " b = " + backwards + " s = " + show + " n = " + noNetwork + " r = " + random + " u = " + bungee); if (!bungee && (network.length() < 1 || network.length() > 11)) { network = Stargate.getDefaultNetwork(); @@ -375,8 +389,8 @@ public class PortalHandler { } // Check if the user can create gates to this world. - if (!bungee && !deny && destName.length() > 0) { - Portal p = getByName(destName, network); + if (!bungee && !deny && destinationName.length() > 0) { + Portal p = getByName(destinationName, network); if (p != null) { String world = p.getWorld().getName(); if (!Stargate.canAccessWorld(player, world)) { @@ -389,7 +403,7 @@ public class PortalHandler { // Bleh, gotta check to make sure none of this gate belongs to another gate. Boo slow. for (RelativeBlockVector v : gate.getBorder()) { - BlockLocation b = topleft.modRelative(v.getRight(), v.getDepth(), v.getDistance(), modX, 1, modZ); + BlockLocation b = topLeft.modRelative(v.getRight(), v.getDepth(), v.getDistance(), modX, 1, modZ); if (getByBlock(b.getBlock()) != null) { Stargate.debug("createPortal", "Gate conflicts with existing gate"); Stargate.sendMessage(player, Stargate.getString("createConflict")); @@ -399,7 +413,7 @@ public class PortalHandler { BlockLocation button = null; Portal portal; - portal = new Portal(topleft, modX, modZ, rotX, id, button, destName, name, false, network, gate, player.getUniqueId(), player.getName(), hidden, alwaysOn, priv, free, backwards, show, noNetwork, random, bungee); + portal = new Portal(topLeft, modX, modZ, rotX, id, button, destinationName, name, false, network, gate, player.getUniqueId(), player.getName(), hidden, alwaysOn, isPrivate, free, backwards, show, noNetwork, random, bungee); int cost = Stargate.getCreateCost(player, gate); @@ -456,20 +470,20 @@ public class PortalHandler { // No button on an always-open gate. if (!alwaysOn) { - button = topleft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); + button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); Directional buttondata = (Directional) Bukkit.createBlockData(gate.getButton()); - buttondata.setFacing(buttonfacing); + buttondata.setFacing(buttonFacing); button.getBlock().setBlockData(buttondata); portal.setButton(button); } - register(portal); + registerPortal(portal); portal.drawSign(); // Open always on gate if (portal.isRandom() || portal.isBungee()) { portal.open(true); } else if (portal.isAlwaysOn()) { - Portal dest = getByName(destName, portal.getNetwork()); + Portal dest = getByName(destinationName, portal.getNetwork()); if (dest != null) { portal.open(true); dest.drawSign(); @@ -757,7 +771,7 @@ public class PortalHandler { gate, ownerUUID, ownerName); loadPortalOptions(portal, portalData); - register(portal); + registerPortal(portal); portal.close(true); } scanner.close(); @@ -835,7 +849,7 @@ public class PortalHandler { Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); } } - PortalHandler.unregister(portal, false); + PortalHandler.unregisterPortal(portal, false); Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal.toString()); } diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index 3078f2e..edfd6b0 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -1,9 +1,12 @@ package net.knarcraft.stargate; /** - * This stores a block location as a vector in an alternate coordinate system + * This stores a block location as a vector relative to a position * - *

+ *

A relative block vector stores a vector relative to some origin. The origin in this plugin is usually the + * top-left block of a gate. The right is therefore the distance from the top-left corner towards the top-right corner. + * Depth is the distance from the top-left corner to the bottom-left corner. Distance is the distance outward from the + * gate.

*/ public class RelativeBlockVector { @@ -13,9 +16,9 @@ public class RelativeBlockVector { /** * Instantiates a new relative block vector - * @param right

The x coordinate in the gate description

- * @param depth

The y coordinate in the gate description

- * @param distance

+ * @param right

The distance to the right relative to the origin

+ * @param depth

The distance downward relative to the origin

+ * @param distance

The distance outward relative to the origin

*/ public RelativeBlockVector(int right, int depth, int distance) { this.right = right; @@ -23,14 +26,26 @@ public class RelativeBlockVector { this.distance = distance; } + /** + * Gets the distance to the right relative to the origin + * @return The distance to the right relative to the origin + */ public int getRight() { return right; } + /** + * Gets the distance downward relative to the origin + * @return The distance downward relative to the origin + */ public int getDepth() { return depth; } + /** + * Gets the distance outward relative to the origin + * @return The distance outward relative to the origin + */ public int getDistance() { return distance; } diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 6f1b808..157bfa4 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -1,5 +1,7 @@ package net.knarcraft.stargate; +import net.knarcraft.stargate.command.CommandStarGate; +import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; @@ -15,8 +17,8 @@ import org.bukkit.ChatColor; import org.bukkit.Server; import org.bukkit.World; import org.bukkit.block.Sign; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -24,7 +26,6 @@ import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.HashMap; @@ -45,7 +46,9 @@ public class Stargate extends JavaPlugin { private PluginManager pm; public static Server server; public static Stargate stargate; - private static LanguageLoader languageLoader; + public static LanguageLoader languageLoader; + + private static String pluginVersion; private static String portalFolder; private static String gateFolder; @@ -109,7 +112,7 @@ public class Stargate extends JavaPlugin { @Override public void onEnable() { - PluginDescriptionFile pdfFile = this.getDescription(); + PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pm = getServer().getPluginManager(); newConfig = this.getConfig(); log = Logger.getLogger("Minecraft"); @@ -122,7 +125,9 @@ public class Stargate extends JavaPlugin { gateFolder = dataFolderPath + "/gates/"; langFolder = dataFolderPath + "/lang/"; - log.info(pdfFile.getName() + " v." + pdfFile.getVersion() + " is enabled."); + pluginVersion = pluginDescriptionFile.getVersion(); + + log.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); // Register events before loading gates to stop weird things happening. pm.registerEvents(new PlayerEventsListener(), this); @@ -159,6 +164,20 @@ public class Stargate extends JavaPlugin { getServer().getScheduler().scheduleSyncRepeatingTask(this, new StarGateThread(), 0L, 100L); getServer().getScheduler().scheduleSyncRepeatingTask(this, new BlockPopulatorThread(), 0L, 1L); + + this.registerCommands(); + } + + private void registerCommands() { + PluginCommand stargateCommand = this.getCommand("stargate"); + if (stargateCommand != null) { + stargateCommand.setExecutor(new CommandStarGate(this)); + stargateCommand.setTabCompleter(new StarGateTabCompleter()); + } + } + + public static String getPluginVersion() { + return pluginVersion; } public static boolean destroyedByExplosion() { @@ -421,6 +440,26 @@ public class Stargate extends JavaPlugin { return !event.getDeny(); } + /** + * Checks whether a given user can travel between two portals + * @param player

The player to check

+ * @param entrancePortal

The portal the user wants to enter

+ * @param destination

The portal the user wants to exit

+ * @return

True if the user is allowed to access the portal

+ */ + public static boolean canAccessPortal(Player player, Portal entrancePortal, Portal destination) { + boolean deny = false; + // Check if player has access to this server for Bungee gates + if (entrancePortal.isBungee() && !Stargate.canAccessServer(player, entrancePortal.getNetwork())) { + deny = true; + } else if (!Stargate.canAccessNetwork(player, entrancePortal.getNetwork())) { + deny = true; + } else if (!Stargate.canAccessWorld(player, destination.getWorld().getName())) { + deny = true; + } + return Stargate.canAccessPortal(player, entrancePortal, deny); + } + /* * Return true if the portal is free for the player */ @@ -634,80 +673,60 @@ public class Stargate extends JavaPlugin { return input.replace(search, value); } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - String cmd = command.getName(); - if (cmd.equalsIgnoreCase("sg")) { - if (args.length != 1) return false; - if (args[0].equalsIgnoreCase("about")) { - sender.sendMessage("stargate Plugin created by Drakia"); - if (!languageLoader.getString("author").isEmpty()) - sender.sendMessage("Language created by " + languageLoader.getString("author")); - return true; - } - if (sender instanceof Player) { - Player p = (Player) sender; - if (!hasPerm(p, "stargate.admin") && !hasPerm(p, "stargate.admin.reload")) { - sendMessage(sender, "Permission Denied"); - return true; - } - } - if (args[0].equalsIgnoreCase("reload")) { - // Deactivate portals - for (Portal p : activeList) { - p.deactivate(); - } - // Close portals - closeAllPortals(); - // Clear all lists - activeList.clear(); - openList.clear(); - managedWorlds.clear(); - PortalHandler.clearGates(); - Gate.clearGates(); - - // Store the old Bungee enabled value - boolean oldEnableBungee = enableBungee; - // Reload data - loadConfig(); - loadGates(); - loadAllPortals(); - languageLoader.setChosenLanguage(langName); - languageLoader.reload(); - - // Load Economy support if enabled/clear if disabled - if (EconomyHandler.economyEnabled && EconomyHandler.economy == null) { - if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) { - String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); - log.info(Stargate.getString("prefix") + Stargate.replaceVars( - Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); - } - } - } - if (!EconomyHandler.economyEnabled) { - EconomyHandler.vault = null; - EconomyHandler.economy = null; - } - - // Enable the required channels for Bungee support - if (oldEnableBungee != enableBungee) { - if (enableBungee) { - Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); - } else { - Bukkit.getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord"); - } - } - - sendMessage(sender, "stargate reloaded"); - return true; - } - return false; + /** + * Reloads all portals and files + * @param sender

The sender of the reload request

+ */ + public void reload(CommandSender sender) { + // Deactivate portals + for (Portal p : activeList) { + p.deactivate(); } - return false; + // Close portals + closeAllPortals(); + // Clear all lists + activeList.clear(); + openList.clear(); + managedWorlds.clear(); + PortalHandler.clearGates(); + Gate.clearGates(); + + // Store the old Bungee enabled value + boolean oldEnableBungee = enableBungee; + // Reload data + loadConfig(); + loadGates(); + loadAllPortals(); + languageLoader.setChosenLanguage(langName); + languageLoader.reload(); + + // Load Economy support if enabled/clear if disabled + if (EconomyHandler.economyEnabled && EconomyHandler.economy == null) { + if (EconomyHandler.setupEconomy(pm)) { + if (EconomyHandler.economy != null) { + String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + log.info(Stargate.getString("prefix") + Stargate.replaceVars( + Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + } + } + } + if (!EconomyHandler.economyEnabled) { + EconomyHandler.vault = null; + EconomyHandler.economy = null; + } + + // Enable the required channels for Bungee support + if (oldEnableBungee != enableBungee) { + if (enableBungee) { + Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); + } else { + Bukkit.getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord"); + Bukkit.getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord"); + } + } + + sendMessage(sender, "stargate reloaded"); } } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java new file mode 100644 index 0000000..03312f8 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -0,0 +1,26 @@ +package net.knarcraft.stargate.command; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * This command represents the plugin's about command + */ +public class CommandAbout implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] strings) { + + commandSender.sendMessage(ChatColor.GOLD + "Stargate Plugin created by " + ChatColor.GREEN + "Drakia"); + String author = Stargate.languageLoader.getString("author"); + if (!author.isEmpty()) + commandSender.sendMessage(ChatColor.GOLD + "Language created by " + ChatColor.GREEN + author); + return true; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java new file mode 100644 index 0000000..a81dfc7 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -0,0 +1,39 @@ +package net.knarcraft.stargate.command; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +/** + * This command represents the plugin's reload command + */ +public class CommandReload implements CommandExecutor { + + private Stargate plugin; + + /** + * Instantiates the reload command + * @param plugin

A reference to the calling plugin object

+ */ + public CommandReload(Stargate plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] strings) { + if (commandSender instanceof Player) { + Player player = (Player) commandSender; + if (!player.hasPermission("stargate.reload")) { + Stargate.sendMessage(commandSender, "Permission Denied"); + return true; + } + } + plugin.reload(commandSender); + return true; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java new file mode 100644 index 0000000..63687d7 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -0,0 +1,43 @@ +package net.knarcraft.stargate.command; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * This command represents any command which starts with stargate + * + *

This prefix command should only be used for commands which are certain to collide with others and which relate to + * the plugin itself, not commands for functions of the plugin.

+ */ +public class CommandStarGate implements CommandExecutor { + + private Stargate plugin; + + /** + * Instantiates the stargate command + * @param plugin

A reference to the calling plugin object

+ */ + public CommandStarGate(Stargate plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] strings) { + if (strings.length > 0) { + if (strings[0].equalsIgnoreCase("about")) { + return new CommandAbout().onCommand(commandSender, command, s, strings); + } else if (strings[0].equalsIgnoreCase("reload")) { + return new CommandReload(plugin).onCommand(commandSender, command, s, strings); + } + return false; + } else { + commandSender.sendMessage(ChatColor.GOLD + "Stargate version " + ChatColor.GREEN + Stargate.getPluginVersion()); + return true; + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java new file mode 100644 index 0000000..5370beb --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -0,0 +1,23 @@ +package net.knarcraft.stargate.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class StarGateTabCompleter implements TabCompleter { + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, + @NotNull String s, @NotNull String[] strings) { + List commands = new ArrayList<>(); + commands.add("about"); + commands.add("reload"); + return commands; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 2bbe2cd..5b58fd4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -107,7 +107,7 @@ public class BlockEventListener implements Listener { return; } - PortalHandler.unregister(portal, true); + PortalHandler.unregisterPortal(portal, true); Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); } diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index bab95f6..f8272e5 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -20,8 +20,12 @@ public class EntityEventListener implements Listener { * This event handler prevents sending entities to the normal nether instead of the stargate target * @param event

The event to check and possibly cancel

*/ - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.LOWEST) public void onPortalEvent(EntityPortalEvent event) { + if (event.isCancelled()) { + return; + } + Portal portal = PortalHandler.getByAdjacentEntrance(event.getFrom()); if (portal != null) { event.setCancelled(true); @@ -47,7 +51,7 @@ public class EntityEventListener implements Listener { continue; } if (Stargate.destroyedByExplosion()) { - PortalHandler.unregister(portal, true); + PortalHandler.unregisterPortal(portal, true); } else { event.setCancelled(true); break; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 6d7e3c4..511a7f9 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -9,7 +9,9 @@ import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.entity.Vehicle; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -22,6 +24,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Objects; public class PlayerEventsListener implements Listener { @@ -52,12 +55,25 @@ public class PlayerEventsListener implements Listener { public void onPlayerTeleport(PlayerTeleportEvent event) { // cancel portal and endgateway teleportation if it's from a stargate entrance PlayerTeleportEvent.TeleportCause cause = event.getCause(); - if (!event.isCancelled() - && (cause == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL - || cause == PlayerTeleportEvent.TeleportCause.END_GATEWAY && World.Environment.THE_END == event.getFrom().getWorld().getEnvironment()) + if (!event.isCancelled() && (cause == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL + || cause == PlayerTeleportEvent.TeleportCause.END_GATEWAY && World.Environment.THE_END == + Objects.requireNonNull(event.getFrom().getWorld()).getEnvironment()) && PortalHandler.getByAdjacentEntrance(event.getFrom()) != null) { event.setCancelled(true); } + if (event.isCancelled()) { + return; + } + + Entity playerVehicle = event.getPlayer().getVehicle(); + Portal portal = PortalHandler.getByEntrance(event.getFrom()); + if (playerVehicle != null && PortalHandler.getByEntrance(event.getFrom()) != null) { + Portal destinationPortal = portal.getDestination(); + if (destinationPortal != null) { + VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer()); + Stargate.log.info("Player was driving " + playerVehicle.getName()); + } + } } @EventHandler @@ -65,53 +81,40 @@ public class PlayerEventsListener implements Listener { if (event.isCancelled()) return; // Check to see if the player actually moved - if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { + if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == + event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { return; } Player player = event.getPlayer(); - Portal entracePortal = PortalHandler.getByEntrance(event.getTo()); + Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); // No portal or not open - if (entracePortal == null || !entracePortal.isOpen()) return; + if (entrancePortal == null || !entrancePortal.isOpen()) { + return; + } // Not open for this player - if (!entracePortal.isOpenFor(player)) { + if (!entrancePortal.isOpenFor(player)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); - entracePortal.teleport(player, entracePortal, event); + entrancePortal.teleport(player, entrancePortal, event); return; } - Portal destination = entracePortal.getDestination(player); - if (!entracePortal.isBungee() && destination == null) return; - - boolean deny = false; - // Check if player has access to this server for Bungee gates - if (entracePortal.isBungee()) { - if (!Stargate.canAccessServer(player, entracePortal.getNetwork())) { - deny = true; - } - } else { - // Check if player has access to this network - if (!Stargate.canAccessNetwork(player, entracePortal.getNetwork())) { - deny = true; - } - - // Check if player has access to destination world - if (!Stargate.canAccessWorld(player, destination.getWorld().getName())) { - deny = true; - } - } - - if (!Stargate.canAccessPortal(player, entracePortal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - entracePortal.teleport(player, entracePortal, event); - entracePortal.close(false); + Portal destination = entrancePortal.getDestination(player); + if (!entrancePortal.isBungee() && destination == null) { return; } - int cost = Stargate.getUseCost(player, entracePortal, destination); + if (!Stargate.canAccessPortal(player, entrancePortal, destination)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + entrancePortal.teleport(player, entrancePortal, event); + entrancePortal.close(false); + return; + } + + int cost = Stargate.getUseCost(player, entrancePortal, destination); if (cost > 0) { - if (!EconomyHelper.payTeleportFee(entracePortal, player, cost)) { + if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { return; } } @@ -119,25 +122,25 @@ public class PlayerEventsListener implements Listener { Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); // BungeeCord Support - if (entracePortal.isBungee()) { + if (entrancePortal.isBungee()) { if (!Stargate.enableBungee) { player.sendMessage(Stargate.getString("bungeeDisabled")); - entracePortal.close(false); + entrancePortal.close(false); return; } // Teleport the player back to this gate, for sanity's sake - entracePortal.teleport(player, entracePortal, event); + entrancePortal.teleport(player, entrancePortal, event); // Send the SGBungee packet first, it will be queued by BC if required try { // Build the message, format is #@# - String msg = event.getPlayer().getName() + "#@#" + entracePortal.getDestinationName(); + String msg = event.getPlayer().getName() + "#@#" + entrancePortal.getDestinationName(); // Build the message data, sent over the SGBungee bungeecord channel ByteArrayOutputStream bao = new ByteArrayOutputStream(); DataOutputStream msgData = new DataOutputStream(bao); msgData.writeUTF("Forward"); - msgData.writeUTF(entracePortal.getNetwork()); // Server + msgData.writeUTF(entrancePortal.getNetwork()); // Server msgData.writeUTF("SGBungee"); // Channel msgData.writeShort(msg.length()); // Data Length msgData.writeBytes(msg); // Data @@ -153,7 +156,7 @@ public class PlayerEventsListener implements Listener { ByteArrayOutputStream bao = new ByteArrayOutputStream(); DataOutputStream msgData = new DataOutputStream(bao); msgData.writeUTF("Connect"); - msgData.writeUTF(entracePortal.getNetwork()); + msgData.writeUTF(entrancePortal.getNetwork()); player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray()); bao.reset(); @@ -164,12 +167,12 @@ public class PlayerEventsListener implements Listener { } // Close portal if required (Should never be) - entracePortal.close(false); + entrancePortal.close(false); return; } - destination.teleport(player, entracePortal, event); - entracePortal.close(false); + destination.teleport(player, entrancePortal, event); + entrancePortal.close(false); } @EventHandler diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 31fd75a..95114c3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -35,11 +35,39 @@ public class VehicleEventListener implements Listener { return; } + //TODO: As there are a lot of vehicles in the game now, a lot needs to be accounted for to make this work as expected + + teleportVehicle(passengers, entrancePortal, vehicle); + } + + public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player) { + destinationPortal.teleport(vehicle); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6); + } + + /** + * Teleports a vehicle through a stargate + * @param passengers

The passengers inside the vehicle

+ * @param entrancePortal

The portal the vehicle is entering

+ * @param vehicle

The vehicle passing through

+ */ + public static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { + teleportVehicle(passengers, entrancePortal, vehicle, false); + } + + /** + * Teleports a vehicle through a stargate + * @param passengers

The passengers inside the vehicle

+ * @param entrancePortal

The portal the vehicle is entering

+ * @param vehicle

The vehicle passing through

+ * @param skipOpenCheck

Skips the check for whether the portal is open for the player

+ */ + public static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle, boolean skipOpenCheck) { if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - Stargate.log.info(Stargate.getString("prefox") + "Found passenger minecart"); - teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); + Stargate.log.info(Stargate.getString("prefox") + "Found passenger vehicle"); + teleportPlayerAndVehicle(entrancePortal, vehicle, passengers, skipOpenCheck); } else { - Stargate.log.info(Stargate.getString("prefox") + "Found empty minecart"); + Stargate.log.info(Stargate.getString("prefox") + "Found empty vehicle"); Portal destinationPortal = entrancePortal.getDestination(); if (destinationPortal == null) { Stargate.log.warning(Stargate.getString("prefox") + "Unable to find portal destination"); @@ -50,14 +78,15 @@ public class VehicleEventListener implements Listener { } /** - * Teleports a player and the minecart the player sits in + * Teleports a player and the vehicle the player sits in * @param entrancePortal

The portal the minecart entered

* @param vehicle

The vehicle to teleport

* @param passengers

Any entities sitting in the minecart

*/ - private void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { + private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers, + boolean skipOpenCheck) { Player player = (Player) passengers.get(0); - if (!entrancePortal.isOpenFor(player)) { + if (!skipOpenCheck && !entrancePortal.isOpenFor(player)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); return; } @@ -66,23 +95,15 @@ public class VehicleEventListener implements Listener { if (destinationPortal == null) { return; } - boolean deny = false; - // Check if player has access to this network - if (!Stargate.canAccessNetwork(player, entrancePortal.getNetwork())) { - deny = true; - } - // Check if player has access to destination world - if (!Stargate.canAccessWorld(player, destinationPortal.getWorld().getName())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, entrancePortal, deny)) { + //Make sure the user can access the portal + if (!Stargate.canAccessPortal(player, entrancePortal, destinationPortal)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); entrancePortal.close(false); return; } + //Transfer payment if necessary int cost = Stargate.getUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 252dbe3..9609b1a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -1,6 +1,5 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.World; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 106637f..0d3bb20 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,10 +8,26 @@ website: https://knarcraft.net api-version: 1.16 softdepend: [Vault] commands: - sg: - description: Used to reload the plugin. Console use only. - usage: / reload - Used to reload the plugin. Console use only. + stargate: + aliases: + - sg + description: Used to see stargate info + usage: / - Used to see stargate info or reload the plugin permissions: + stargate.*: + description: Wildcard permission + default: op + children: + stargate.use: true + stargate.create: true + stargate.destroy: true + stargate.free: true + stargate.option: true + stargate.admin: true + stargate.reload: true + stargate.reload: + description: Allows reloading the plugin + default: false stargate.use: description: Allow use of all gates linking to any world in any network default: true @@ -29,4 +45,6 @@ permissions: default: op stargate.admin: description: Allow all admin features (Hidden/Private only so far) - default: op \ No newline at end of file + default: op + children: + stargate.reload: true \ No newline at end of file diff --git a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java index 72b64c9..60a6e89 100644 --- a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java +++ b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java @@ -81,4 +81,13 @@ public class BlockLocationTest { assertEquals("56,87,34", location.toString()); } + @Test + public void modRelativeTest() { + BlockLocation location = new BlockLocation(mockWorld, 5, 5, 5); + BlockLocation relativeLocation = location.modRelative(4, 2, 1, -1, 1, 0); + assertEquals(9, relativeLocation.getBlockX()); + assertEquals(3, relativeLocation.getBlockY()); + assertEquals(6, relativeLocation.getBlockZ()); + } + } diff --git a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java new file mode 100644 index 0000000..293e9fd --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java @@ -0,0 +1,17 @@ +package net.knarcraft.stargate; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RelativeBlockVectorTest { + + @Test + public void getTest() { + RelativeBlockVector relativeBlockVector = new RelativeBlockVector(56, 44, 23); + assertEquals(56, relativeBlockVector.getRight()); + assertEquals(44, relativeBlockVector.getDepth()); + assertEquals(23, relativeBlockVector.getDistance()); + } + +}