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 depthThe y position relative to the current position
- * @param distanceThe distance away from the previous location to the new location
- * @param modXx modifier. Defines movement along the x-axis. 0 for no movement
- * @param modY - * @param modZz 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 rightThe amount of right steps from the top-left origin
+ * @param depthThe amount of downward steps from the top-left origin
+ * @param distanceThe distance outward from the top-left origin
+ * @param modXX modifier. If modX = -1, X will increase as right increases
+ * @param modYY modifier. modY = 1 for Y decreasing as depth increases
+ * @param modZZ 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) { HashMapTrue 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 playerThe player to teleport
+ * @param originThe portal the player teleports from
+ * @param eventThe 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 vehicleThe 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, ListThe entity to teleport (used to determine distance from portal to avoid suffocation)
+ * @param travellerThe location of the entity travelling
+ * @returnThe 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 + * @returnTrue 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 + * @returnThe 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 + * @returnThe 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 + * @returnTrue 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 + * @returnTrue 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 + * @returnTrue 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 playerThe player to activate the portal for
+ * @returnTrue 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 vectorThe relative block vector
+ * @returnThe 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 entrancePortalThe portal the user is entering from
* @param playerThe player who wants to see destinations
* @param networkThe network to get destinations from
* @returnAll destinations the player can go to
*/ - public static ArrayListThe portal to un-register
* @param removeAllWhether 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 portalThe 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 rightThe x coordinate in the gate description
- * @param depthThe y coordinate in the gate description
- * @param distance + * @param rightThe distance to the right relative to the origin
+ * @param depthThe distance downward relative to the origin
+ * @param distanceThe 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 playerThe player to check
+ * @param entrancePortalThe portal the user wants to enter
+ * @param destinationThe portal the user wants to exit
+ * @returnTrue 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 senderThe 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 pluginA 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 pluginA 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 ListThe 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 isThe passengers inside the vehicle
+ * @param entrancePortalThe portal the vehicle is entering
+ * @param vehicleThe vehicle passing through
+ */ + public static void teleportVehicle(ListThe passengers inside the vehicle
+ * @param entrancePortalThe portal the vehicle is entering
+ * @param vehicleThe vehicle passing through
+ * @param skipOpenCheckSkips the check for whether the portal is open for the player
+ */ + public static void teleportVehicle(ListThe portal the minecart entered
* @param vehicleThe vehicle to teleport
* @param passengersAny entities sitting in the minecart
*/ - private void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List