From 6ff998ac3b479f0c4550c184784e985eb1b6213d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Feb 2021 03:37:25 +0100 Subject: [PATCH 001/378] Restructures the plugin and starts work on cleaning and commenting the code --- README.md | 14 +- pom.xml | 37 +- .../net/knarcraft/stargate/BlockLocation.java | 199 +++ .../net/knarcraft/stargate/BloxPopulator.java | 48 + .../stargate/BungeeCoordListener.java | 58 + .../knarcraft/stargate/CommonFunctions.java | 43 + .../knarcraft/stargate/EconomyHandler.java | 106 ++ .../java/net/knarcraft/stargate/Gate.java | 516 ++++++ .../knarcraft/stargate/LanguageLoader.java | 311 ++++ .../java/net/knarcraft/stargate/Portal.java | 1503 +++++++++++++++++ .../stargate}/RelativeBlockVector.java | 93 +- .../knarcraft/stargate/StarGateThread.java | 34 + .../java/net/knarcraft/stargate/Stargate.java | 1280 ++++++++++++++ .../stargate}/event/StargateAccessEvent.java | 130 +- .../stargate/event/StargateActivateEvent.java | 72 + .../stargate}/event/StargateCloseEvent.java | 103 +- .../stargate/event/StargateCreateEvent.java | 85 + .../event/StargateDeactivateEvent.java | 80 +- .../stargate/event/StargateDestroyEvent.java | 79 + .../stargate}/event/StargateEvent.java | 102 +- .../stargate/event/StargateOpenEvent.java | 65 + .../stargate/event/StargatePortalEvent.java | 85 + src/{ => main/resources}/config.yml | 106 +- .../resources => main/resources/lang}/de.txt | 54 +- .../resources => main/resources/lang}/en.txt | 64 +- .../resources => main/resources/lang}/es.txt | 0 .../resources => main/resources/lang}/fr.txt | 0 .../resources => main/resources/lang}/hu.txt | 0 .../resources => main/resources/lang}/it.txt | 0 .../resources => main/resources/lang}/nl.txt | 2 +- .../resources/lang}/pt-br.txt | 0 .../resources => main/resources/lang}/ru.txt | 0 src/{ => main/resources}/plugin.yml | 58 +- src/net/TheDgtl/Stargate/Blox.java | 173 -- src/net/TheDgtl/Stargate/BloxPopulator.java | 47 - src/net/TheDgtl/Stargate/EconomyHandler.java | 106 -- src/net/TheDgtl/Stargate/Gate.java | 513 ------ src/net/TheDgtl/Stargate/LangLoader.java | 226 --- src/net/TheDgtl/Stargate/Portal.java | 1495 ---------------- src/net/TheDgtl/Stargate/Stargate.java | 1294 -------------- .../Stargate/event/StargateActivateEvent.java | 69 - .../Stargate/event/StargateCreateEvent.java | 83 - .../Stargate/event/StargateDestroyEvent.java | 77 - .../Stargate/event/StargateOpenEvent.java | 61 - .../Stargate/event/StargatePortalEvent.java | 80 - src/net/TheDgtl/Stargate/pmListener.java | 57 - 46 files changed, 4918 insertions(+), 4690 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/BlockLocation.java create mode 100644 src/main/java/net/knarcraft/stargate/BloxPopulator.java create mode 100644 src/main/java/net/knarcraft/stargate/BungeeCoordListener.java create mode 100644 src/main/java/net/knarcraft/stargate/CommonFunctions.java create mode 100644 src/main/java/net/knarcraft/stargate/EconomyHandler.java create mode 100644 src/main/java/net/knarcraft/stargate/Gate.java create mode 100644 src/main/java/net/knarcraft/stargate/LanguageLoader.java create mode 100644 src/main/java/net/knarcraft/stargate/Portal.java rename src/{net/TheDgtl/Stargate => main/java/net/knarcraft/stargate}/RelativeBlockVector.java (60%) create mode 100644 src/main/java/net/knarcraft/stargate/StarGateThread.java create mode 100644 src/main/java/net/knarcraft/stargate/Stargate.java rename src/{net/TheDgtl/Stargate => main/java/net/knarcraft/stargate}/event/StargateAccessEvent.java (76%) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java rename src/{net/TheDgtl/Stargate => main/java/net/knarcraft/stargate}/event/StargateCloseEvent.java (54%) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java rename src/{net/TheDgtl/Stargate => main/java/net/knarcraft/stargate}/event/StargateDeactivateEvent.java (62%) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java rename src/{net/TheDgtl/Stargate => main/java/net/knarcraft/stargate}/event/StargateEvent.java (55%) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java create mode 100644 src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java rename src/{ => main/resources}/config.yml (90%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/de.txt (92%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/en.txt (96%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/es.txt (100%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/fr.txt (100%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/hu.txt (100%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/it.txt (100%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/nl.txt (94%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/pt-br.txt (100%) rename src/{net/TheDgtl/Stargate/resources => main/resources/lang}/ru.txt (100%) rename src/{ => main/resources}/plugin.yml (84%) delete mode 100644 src/net/TheDgtl/Stargate/Blox.java delete mode 100644 src/net/TheDgtl/Stargate/BloxPopulator.java delete mode 100644 src/net/TheDgtl/Stargate/EconomyHandler.java delete mode 100644 src/net/TheDgtl/Stargate/Gate.java delete mode 100644 src/net/TheDgtl/Stargate/LangLoader.java delete mode 100644 src/net/TheDgtl/Stargate/Portal.java delete mode 100644 src/net/TheDgtl/Stargate/Stargate.java delete mode 100644 src/net/TheDgtl/Stargate/event/StargateActivateEvent.java delete mode 100644 src/net/TheDgtl/Stargate/event/StargateCreateEvent.java delete mode 100644 src/net/TheDgtl/Stargate/event/StargateDestroyEvent.java delete mode 100644 src/net/TheDgtl/Stargate/event/StargateOpenEvent.java delete mode 100644 src/net/TheDgtl/Stargate/event/StargatePortalEvent.java delete mode 100644 src/net/TheDgtl/Stargate/pmListener.java diff --git a/README.md b/README.md index 19ed669..0d68aad 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ chargefreedestination - Enable to allow free travel from any gate to a free gate freegatesgreen - Enable to make gates that won't cost the player money show up as green toowner - Whether the money from gate-use goes to the owner or nobody maxgates - If non-zero, will define the maximum amount of gates allowed on any network. -lang - The language to use (Included languages: en, de) +chosenLanguage - The language to use (Included languages: en, de) destMemory - Whether to set the first destination as the last used destination for all gates ignoreEntrance - Set this option to true to not check the entrance of a gate on startup. This is a workaround for snowmen breaking gates. handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. @@ -170,7 +170,7 @@ permdebug: Whether to show massive permission debug output ``` # Message Customization -It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/lang/en.txt. +It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/chosenLanguage/en.txt. If a string is removed, or left blank, it will not be shown when the user does the action associated with it. There are three special cases when it comes to messages, these are: @@ -211,7 +211,7 @@ createConflict=Gate conflicts with existing gate - Add custom buttons #### [Version 0.8.0.2] PseudoKnight fork - Fix player relative yaw when exiting portal - - Add color code support in lang files + - Add color code support in chosenLanguage files #### [Version 0.8.0.1] PseudoKnight fork - Fix slab check for portal exits - Improve material checks for gate configuration @@ -377,14 +377,14 @@ createConflict=Gate conflicts with existing gate #### [Version 0.6.10] - Added Register support as opposed to iConomy #### [Version 0.6.9] - - Added UTF8 support for lang files (With or without BOM) + - Added UTF8 support for chosenLanguage files (With or without BOM) #### [Version 0.6.8] - Fixed unmanned carts losing velocity through gates - /sg reload now properly switches languages #### [Version 0.6.7] - - Added lang option + - Added chosenLanguage option - Removed language debug output - - Added German language (lang=de) -- Thanks EduardBaer + - Added German language (chosenLanguage=de) -- Thanks EduardBaer #### [Version 0.6.6] - Added %cost% and %portal% to all eco* messages - Fixed an issue when creating a gate on a network you don't have access to @@ -560,6 +560,6 @@ createConflict=Gate conflicts with existing gate #### [Version 0.04] - Updated to multi-world Bukkit #### [Version 0.03] - - Changed package to net.TheDgtl.* + - Changed package to net.knarcraft.* - Everything now uses Blox instead of Block objects - Started on vehicle code, but it's still buggy diff --git a/pom.xml b/pom.xml index 7d02c5f..36dff1a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,23 @@ 4.0.0 - org.TheDgtl + + net.knarcraft Stargate - 0.8.0.3 + 0.8.0.0 + + + + GNU Lesser General Public License + https://www.gnu.org/licenses/lgpl-3.0.en.html + + + UTF-8 + 1.8 + 1.8 + spigot-repo @@ -16,11 +28,12 @@ http://nexus.hc.to/content/repositories/pub_releases + org.spigotmc spigot-api - 1.16.2-R0.1-SNAPSHOT + 1.16.5-R0.1-SNAPSHOT net.milkbowl.vault @@ -28,23 +41,9 @@ 1.7 + - src - - - net/TheDgtl/Stargate/resources - src/net/TheDgtl/Stargate/resources - - *.txt - - - - src - - *.yml - - - + src/main/java org.apache.maven.plugins diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java new file mode 100644 index 0000000..f607666 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -0,0 +1,199 @@ +package net.knarcraft.stargate; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Sign; +import org.bukkit.block.data.type.WallSign; + +/* + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011 Shaun (sturmeh) + * Copyright (C) 2011 Dinnerbone + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * This class represents a block location + */ +public class BlockLocation { + + private final int x; + private final int y; + private final int z; + private final World world; + private BlockLocation parent = null; + + /** + * Creates a new block + * @param world

The world the block exists in

+ * @param x

The x coordinate of the block

+ * @param y

The y coordinate of the block

+ * @param z

The z coordinate of the block

+ */ + public BlockLocation(World world, int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + this.world = world; + } + + /** + * Copies a craftbukkit block + * @param block

The block to

+ */ + public BlockLocation(Block block) { + this.x = block.getX(); + this.y = block.getY(); + this.z = block.getZ(); + this.world = block.getWorld(); + } + + /** + * Creates a new block from a location + * @param location

The location the block exists in

+ */ + public BlockLocation(Location location) { + this.x = location.getBlockX(); + this.y = location.getBlockY(); + this.z = location.getBlockZ(); + this.world = location.getWorld(); + } + + /** + * Gets a block from a string + * @param world

The world the block exists in

+ * @param string

A comma separated list of z, y and z coordinates as integers

+ */ + public BlockLocation(World world, String string) { + String[] split = string.split(","); + this.x = Integer.parseInt(split[0]); + this.y = Integer.parseInt(split[1]); + this.z = Integer.parseInt(split[2]); + this.world = world; + } + + /** + * Makes a new block in a relative position to this block + * @param x

The x position relative to this block's position

+ * @param y

The y position relative to this block's position

+ * @param z

The z position relative to this block's position

+ * @return

A new block

+ */ + public BlockLocation makeRelative(int x, int y, int z) { + return new BlockLocation(this.world, this.x + x, this.y + y, this.z + z); + } + + public Location makeRelativeLoc(double x, double y, double z, float rotX, float rotY) { + return new Location(this.world, (double) this.x + x, (double) this.y + y, (double) this.z + z, rotX, rotY); + } + + public BlockLocation modRelative(int right, int depth, int distance, int modX, int modY, int modZ) { + return makeRelative(-right * modX + distance * modZ, -depth * modY, -right * modZ + -distance * modX); + } + + public Location modRelativeLoc(double right, double depth, double distance, float rotX, float rotY, int modX, int modY, int modZ) { + return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); + } + + public void setType(Material type) { + world.getBlockAt(x, y, z).setType(type); + } + + public Material getType() { + return world.getBlockAt(x, y, z).getType(); + } + + public Block getBlock() { + return world.getBlockAt(x, y, z); + } + + public Location getLocation() { + return new Location(world, x, y, z); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + + public World getWorld() { + return world; + } + + public Block getParent() { + if (parent == null) findParent(); + if (parent == null) return null; + return parent.getBlock(); + } + + private void findParent() { + int offsetX = 0; + int offsetY = 0; + int offsetZ = 0; + + BlockData blk = getBlock().getBlockData(); + if (blk instanceof WallSign) { + BlockFace facing = ((WallSign) blk).getFacing().getOppositeFace(); + offsetX = facing.getModX(); + offsetZ = facing.getModZ(); + } else if (blk instanceof Sign) { + offsetY = -1; + } else { + return; + } + parent = new BlockLocation(world, getX() + offsetX, getY() + offsetY, getZ() + offsetZ); + } + + @Override + public String toString() { + return String.valueOf(x) + ',' + y + ',' + z; + } + + @Override + public int hashCode() { + int result = 18; + + result = result * 27 + x; + result = result * 27 + y; + result = result * 27 + z; + result = result * 27 + world.getName().hashCode(); + + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + BlockLocation blockLocation = (BlockLocation) obj; + return (x == blockLocation.x) && (y == blockLocation.y) && (z == blockLocation.z) && (world.getName().equals(blockLocation.world.getName())); + } + +} \ No newline at end of file diff --git a/src/main/java/net/knarcraft/stargate/BloxPopulator.java b/src/main/java/net/knarcraft/stargate/BloxPopulator.java new file mode 100644 index 0000000..87bedb8 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/BloxPopulator.java @@ -0,0 +1,48 @@ +package net.knarcraft.stargate; + +import org.bukkit.Axis; +import org.bukkit.Material; + +public class BloxPopulator { + + private BlockLocation blockLocation; + private Material nextMat; + private Axis nextAxis; + + public BloxPopulator(BlockLocation b, Material m) { + blockLocation = b; + nextMat = m; + nextAxis = null; + } + + public BloxPopulator(BlockLocation b, Material m, Axis a) { + blockLocation = b; + nextMat = m; + nextAxis = a; + } + + public void setBlockLocation(BlockLocation b) { + blockLocation = b; + } + + public void setMat(Material m) { + nextMat = m; + } + + public void setAxis(Axis a) { + nextAxis = a; + } + + public BlockLocation getBlockLocation() { + return blockLocation; + } + + public Material getMat() { + return nextMat; + } + + public Axis getAxis() { + return nextAxis; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/BungeeCoordListener.java b/src/main/java/net/knarcraft/stargate/BungeeCoordListener.java new file mode 100644 index 0000000..57fe488 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/BungeeCoordListener.java @@ -0,0 +1,58 @@ +package net.knarcraft.stargate; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; + +public class BungeeCoordListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(String channel, Player unused, byte[] message) { + if (!Stargate.enableBungee || !channel.equals("BungeeCord")) return; + + // Get data from message + String inChannel; + byte[] data; + try { + DataInputStream in = new DataInputStream(new ByteArrayInputStream(message)); + inChannel = in.readUTF(); + short len = in.readShort(); + data = new byte[len]; + in.readFully(data); + } catch (IOException ex) { + Stargate.log.severe("[stargate] Error receiving BungeeCord message"); + ex.printStackTrace(); + return; + } + + // Verify that it's an SGBungee packet + if (!inChannel.equals("SGBungee")) { + return; + } + + // Data should be player name, and destination gate name + String msg = new String(data); + String[] parts = msg.split("#@#"); + + String playerName = parts[0]; + String destination = parts[1]; + + // Check if the player is online, if so, teleport, otherwise, queue + Player player = Stargate.server.getPlayer(playerName); + if (player == null) { + Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); + } else { + Portal dest = Portal.getBungeeGate(destination); + // Specified an invalid gate. For now we'll just let them connect at their current location + if (dest == null) { + Stargate.log.info("[stargate] Bungee gate " + destination + " does not exist"); + return; + } + dest.teleport(player, dest, null); + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/CommonFunctions.java b/src/main/java/net/knarcraft/stargate/CommonFunctions.java new file mode 100644 index 0000000..7c374fe --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/CommonFunctions.java @@ -0,0 +1,43 @@ +package net.knarcraft.stargate; + +import java.io.InputStream; + +/* + * stargate - A portal plugin for Bukkit + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * A holding class for methods shared between classes + * + * @author Kristian Knarvik + */ +public final class CommonFunctions { + + private CommonFunctions() {} + + /** + * Gets a resource as an InputStream + * + * @param resourceName

The name of the resource you want to readFromServer

+ * @return

An input stream which can be used to access the resource

+ */ + public static InputStream getResourceAsStream(String resourceName) { + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + return classloader.getResourceAsStream(resourceName); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/EconomyHandler.java new file mode 100644 index 0000000..0d4c94f --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/EconomyHandler.java @@ -0,0 +1,106 @@ +package net.knarcraft.stargate; + +import net.milkbowl.vault.economy.Economy; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.RegisteredServiceProvider; + +import java.util.UUID; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class EconomyHandler { + public static boolean economyEnabled = false; + public static Economy economy = null; + public static Plugin vault = null; + + public static int useCost = 0; + public static int createCost = 0; + public static int destroyCost = 0; + public static boolean toOwner = false; + public static boolean chargeFreeDestination = true; + public static boolean freeGatesGreen = false; + + public static double getBalance(Player player) { + if (!economyEnabled) return 0; + return economy.getBalance(player); + } + + public static boolean chargePlayer(Player player, String target, double amount) { + if (!economyEnabled) return true; + if (player.getName().equals(target)) return true; + if (economy != null) { + if (!economy.has(player, amount)) return false; + economy.withdrawPlayer(player, amount); + economy.depositPlayer(target, amount); + } + return true; + } + + public static boolean chargePlayer(Player player, UUID target, double amount) { + if (!economyEnabled) return true; + if (player.getUniqueId().compareTo(target) == 0) return true; + if (economy != null) { + if (!economy.has(player, amount)) return false; + economy.withdrawPlayer(player, amount); + economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); + } + return true; + } + + public static boolean chargePlayer(Player player, double amount) { + if (!economyEnabled) return true; + if (economy != null) { + if (!economy.has(player, amount)) return false; + economy.withdrawPlayer(player, amount); + } + return true; + } + + public static String format(int amt) { + if (economyEnabled) { + return economy.format(amt); + } + return ""; + } + + public static boolean setupEconomy(PluginManager pm) { + if (!economyEnabled) return false; + // Check for Vault + Plugin p = pm.getPlugin("Vault"); + if (p != null && p.isEnabled()) { + RegisteredServiceProvider economyProvider = Stargate.server.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); + if (economyProvider != null) { + economy = economyProvider.getProvider(); + vault = p; + return true; + } + } + economyEnabled = false; + return false; + } + + public static boolean useEconomy() { + return economyEnabled && economy != null; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java new file mode 100644 index 0000000..30b4812 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -0,0 +1,516 @@ +package net.knarcraft.stargate; + +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Scanner; +import java.util.logging.Level; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011 Shaun (sturmeh) + * Copyright (C) 2011 Dinnerbone + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class Gate { + + private static final Character ANYTHING = ' '; + private static final Character ENTRANCE = '.'; + private static final Character EXIT = '*'; + private static final HashMap gates = new HashMap<>(); + private static final HashMap> controlBlocks = new HashMap<>(); + private static final HashSet frameBlocks = new HashSet<>(); + + private final String filename; + private final Character[][] layout; + private final HashMap types; + private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; + private RelativeBlockVector[] border = new RelativeBlockVector[0]; + private RelativeBlockVector[] controls = new RelativeBlockVector[0]; + private RelativeBlockVector exitBlock = null; + private final HashMap exits = new HashMap<>(); + private Material portalBlockOpen = Material.NETHER_PORTAL; + private Material portalBlockClosed = Material.AIR; + private Material button = Material.STONE_BUTTON; + + // Economy information + private int useCost = -1; + private int createCost = -1; + private int destroyCost = -1; + private boolean toOwner = false; + + public Gate(String filename, Character[][] layout, HashMap types) { + this.filename = filename; + this.layout = layout; + this.types = types; + + populateCoordinates(); + } + + private void populateCoordinates() { + ArrayList entranceList = new ArrayList<>(); + ArrayList borderList = new ArrayList<>(); + ArrayList controlList = new ArrayList<>(); + RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; + int[] exitDepths = new int[layout[0].length]; + RelativeBlockVector lastExit = null; + + 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('-')) { + controlList.add(new RelativeBlockVector(x, y, 0)); + } + + if (key.equals(ENTRANCE) || key.equals(EXIT)) { + entranceList.add(new RelativeBlockVector(x, y, 0)); + exitDepths[x] = y; + if (key.equals(EXIT)) { + this.exitBlock = new RelativeBlockVector(x, y, 0); + } + } else if (!key.equals(ANYTHING)) { + borderList.add(new RelativeBlockVector(x, y, 0)); + } + } + } + + for (int x = 0; x < exitDepths.length; x++) { + relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0); + } + + for (int x = relativeExits.length - 1; x >= 0; x--) { + if (relativeExits[x] != null) { + lastExit = relativeExits[x]; + } else { + relativeExits[x] = lastExit; + } + + if (exitDepths[x] > 0) this.exits.put(relativeExits[x], x); + } + + this.entrances = entranceList.toArray(this.entrances); + this.border = borderList.toArray(this.border); + this.controls = controlList.toArray(this.controls); + } + + public void save(String gateFolder) { + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(gateFolder + filename)); + + writeConfig(bw, "portal-open", portalBlockOpen.name()); + writeConfig(bw, "portal-closed", portalBlockClosed.name()); + writeConfig(bw, "button", button.name()); + if (useCost != -1) + writeConfig(bw, "usecost", useCost); + if (createCost != -1) + writeConfig(bw, "createcost", createCost); + if (destroyCost != -1) + writeConfig(bw, "destroycost", destroyCost); + writeConfig(bw, "toowner", toOwner); + + for (Map.Entry entry : types.entrySet()) { + Character type = entry.getKey(); + Material value = entry.getValue(); + // Skip control values + if (type.equals(ANYTHING) || type.equals(ENTRANCE) || type.equals(EXIT)) { + continue; + } + + bw.append(type); + bw.append('='); + if (value != null) { + bw.append(value.toString()); + } + bw.newLine(); + } + + bw.newLine(); + + for (Character[] aLayout : layout) { + for (Character symbol : aLayout) { + bw.append(symbol); + } + bw.newLine(); + } + + bw.close(); + } catch (IOException ex) { + Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); + } + } + + private void writeConfig(BufferedWriter bw, String key, int value) throws IOException { + bw.append(String.format("%s=%d", key, value)); + bw.newLine(); + } + + private void writeConfig(BufferedWriter bw, String key, boolean value) throws IOException { + bw.append(String.format("%s=%b", key, value)); + bw.newLine(); + } + + private void writeConfig(BufferedWriter bw, String key, String value) throws IOException { + bw.append(String.format("%s=%s", key, value)); + bw.newLine(); + } + + public Character[][] getLayout() { + return layout; + } + + public HashMap getTypes() { + return types; + } + + public RelativeBlockVector[] getEntrances() { + return entrances; + } + + public RelativeBlockVector[] getBorder() { + return border; + } + + public RelativeBlockVector[] getControls() { + return controls; + } + + public HashMap getExits() { + return exits; + } + + public RelativeBlockVector getExit() { + return exitBlock; + } + + public Material getControlBlock() { + return types.get('-'); + } + + public String getFilename() { + return filename; + } + + public Material getPortalBlockOpen() { + return portalBlockOpen; + } + + public void setPortalBlockOpen(Material type) { + portalBlockOpen = type; + } + + public Material getPortalBlockClosed() { + return portalBlockClosed; + } + + public void setPortalBlockClosed(Material type) { + portalBlockClosed = type; + } + + public Material getButton() { + return button; + } + + public int getUseCost() { + if (useCost < 0) return EconomyHandler.useCost; + return useCost; + } + + public Integer getCreateCost() { + if (createCost < 0) return EconomyHandler.createCost; + return createCost; + } + + public Integer getDestroyCost() { + if (destroyCost < 0) return EconomyHandler.destroyCost; + return destroyCost; + } + + public Boolean getToOwner() { + 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, 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; + + 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 (type != portalBlockClosed && type != portalBlockOpen) { + Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); + return false; + } + } 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); + return false; + } + } + } + } + + return true; + } + + public static void registerGate(Gate gate) { + gates.put(gate.getFilename(), gate); + + Material blockID = gate.getControlBlock(); + + if (!controlBlocks.containsKey(blockID)) { + controlBlocks.put(blockID, new ArrayList<>()); + } + + controlBlocks.get(blockID).add(gate); + } + + public static Gate loadGate(File file) { + Scanner scanner = null; + boolean designing = false; + ArrayList> design = new ArrayList<>(); + HashMap types = new HashMap<>(); + HashMap config = new HashMap<>(); + HashSet frameTypes = new HashSet<>(); + int cols = 0; + + // Init types map + types.put(ENTRANCE, Material.AIR); + types.put(EXIT, Material.AIR); + types.put(ANYTHING, Material.AIR); + + try { + scanner = new Scanner(file); + + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + + if (designing) { + ArrayList row = new ArrayList<>(); + + if (line.length() > cols) { + cols = line.length(); + } + + for (Character symbol : line.toCharArray()) { + if ((symbol.equals('?')) || (!types.containsKey(symbol))) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Unknown symbol '" + symbol + "' in diagram"); + return null; + } + row.add(symbol); + } + + design.add(row); + } else { + if ((line.isEmpty()) || (!line.contains("="))) { + designing = true; + } else { + String[] split = line.split("="); + String key = split[0].trim(); + String value = split[1].trim(); + + if (key.length() == 1) { + Character symbol = key.charAt(0); + Material id = Material.getMaterial(value); + if (id == null) { + throw new Exception("Invalid material in line: " + line); + } + types.put(symbol, id); + frameTypes.add(id); + } else { + config.put(key, value); + } + } + } + } + } catch (Exception ex) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + return null; + } finally { + if (scanner != null) scanner.close(); + } + + Character[][] layout = new Character[design.size()][cols]; + + for (int y = 0; y < design.size(); y++) { + ArrayList row = design.get(y); + Character[] result = new Character[cols]; + + for (int x = 0; x < cols; x++) { + if (x < row.size()) { + result[x] = row.get(x); + } else { + result[x] = ' '; + } + } + + layout[y] = result; + } + + Gate gate = new Gate(file.getName(), layout, types); + + gate.portalBlockOpen = readConfig(config, gate, file, "portal-open", gate.portalBlockOpen); + gate.portalBlockClosed = readConfig(config, gate, file, "portal-closed", gate.portalBlockClosed); + gate.button = readConfig(config, gate, file, "button", gate.button); + gate.useCost = readConfig(config, gate, file, "usecost", -1); + gate.destroyCost = readConfig(config, gate, file, "destroycost", -1); + gate.createCost = readConfig(config, gate, file, "createcost", -1); + gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); + + if (gate.getControls().length != 2) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gates must have exactly 2 control points."); + return null; + } + + if (!Tag.BUTTONS.isTagged(gate.button)) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gate button must be a type of button."); + return null; + } + + // Merge frame types, add open mat to list + frameBlocks.addAll(frameTypes); + + gate.save(file.getParent() + "/"); // Updates format for version changes + return gate; + } + + private static int readConfig(HashMap config, Gate gate, File file, String key, int def) { + if (config.containsKey(key)) { + try { + return Integer.parseInt(config.get(key)); + } catch (NumberFormatException ex) { + Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), file, key)); + } + } + + return def; + } + + private static Material readConfig(HashMap config, Gate gate, File file, String key, Material def) { + if (config.containsKey(key)) { + Material mat = Material.getMaterial(config.get(key)); + if (mat != null) { + return mat; + } + Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", file, key)); + } + return def; + } + + public static void loadGates(String gateFolder) { + File dir = new File(gateFolder); + File[] files; + + if (dir.exists()) { + files = dir.listFiles(new StargateFilenameFilter()); + } else { + files = new File[0]; + } + + if (files == null || files.length == 0) { + if (dir.mkdir()) { + populateDefaults(gateFolder); + } + } else { + for (File file : files) { + Gate gate = loadGate(file); + if (gate != null) registerGate(gate); + } + } + } + + public static void populateDefaults(String gateFolder) { + Character[][] layout = new Character[][]{ + {' ', 'X', 'X', ' '}, + {'X', '.', '.', 'X'}, + {'-', '.', '.', '-'}, + {'X', '*', '.', 'X'}, + {' ', 'X', 'X', ' '}, + }; + HashMap types = new HashMap<>(); + types.put(ENTRANCE, Material.AIR); + types.put(EXIT, Material.AIR); + types.put(ANYTHING, Material.AIR); + types.put('X', Material.OBSIDIAN); + types.put('-', Material.OBSIDIAN); + + Gate gate = new Gate("nethergate.gate", layout, types); + gate.save(gateFolder); + registerGate(gate); + } + + public static Gate[] getGatesByControlBlock(Block block) { + return getGatesByControlBlock(block.getType()); + } + + public static Gate[] getGatesByControlBlock(Material type) { + Gate[] result = new Gate[0]; + ArrayList lookup = controlBlocks.get(type); + + if (lookup != null) result = lookup.toArray(result); + + return result; + } + + public static Gate getGateByName(String name) { + return gates.get(name); + } + + public static int getGateCount() { + return gates.size(); + } + + public static boolean isGateBlock(Material type) { + return frameBlocks.contains(type); + } + + static class StargateFilenameFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return name.endsWith(".gate"); + } + } + + public static void clearGates() { + gates.clear(); + controlBlocks.clear(); + frameBlocks.clear(); + } +} diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java new file mode 100644 index 0000000..326ca3a --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -0,0 +1,311 @@ +package net.knarcraft.stargate; + +import org.bukkit.ChatColor; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/* + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * This class is responsible for loading all strings which are translated into several languages + */ +public class LanguageLoader { + + // Variables + private final String languageFolder; + private String chosenLanguage; + private Map loadedStringTranslations; + private final Map loadedBackupStrings; + + /** + * Instantiates a new language loader + * @param languageFolder

The folder containing the language files

+ * @param chosenLanguage

The chosen plugin language

+ */ + public LanguageLoader(String languageFolder, String chosenLanguage) { + this.chosenLanguage = chosenLanguage; + this.languageFolder = languageFolder; + + File tmp = new File(languageFolder, chosenLanguage + ".txt"); + if (!tmp.exists()) { + tmp.getParentFile().mkdirs(); + } + updateLanguage(chosenLanguage); + + loadedStringTranslations = load(chosenLanguage); + // We have a default hashMap used for when new text is added. + InputStream inputStream = getClass().getResourceAsStream("/lang/" + chosenLanguage + ".txt"); + if (inputStream != null) { + loadedBackupStrings = load("en", inputStream); + } else { + loadedBackupStrings = null; + Stargate.log.severe("[stargate] Error loading backup language. There may be missing text in-game"); + } + } + + /** + * Reloads languages from the files on disk + */ + public void reload() { + // This extracts/updates the language as needed + updateLanguage(chosenLanguage); + loadedStringTranslations = load(chosenLanguage); + } + + /** + * Gets the string to display given its name/key + * @param name

The name/key of the string to display

+ * @return

The string in the user's preferred language

+ */ + public String getString(String name) { + String val = loadedStringTranslations.get(name); + if (val == null && loadedBackupStrings != null) val = loadedBackupStrings.get(name); + if (val == null) return ""; + return val; + } + + /** + * Sets the chosen plugin language + * @param chosenLanguage

The new plugin language

+ */ + public void setChosenLanguage(String chosenLanguage) { + this.chosenLanguage = chosenLanguage; + } + + /** + * Updates files in the plugin directory with contents from the compiled .jar + * @param language

The language to update

+ */ + private void updateLanguage(String language) { + // Load the current language file + ArrayList keyList = new ArrayList<>(); + ArrayList valueList = new ArrayList<>(); + + Map currentLanguageValues = load(language); + + InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); + if (inputStream == null) return; + + boolean updated = false; + FileOutputStream fileOutputStream = null; + try { + if (readChangedLanguageStrings(inputStream, keyList, valueList, currentLanguageValues)) { + updated = true; + } + + // Save file + fileOutputStream = new FileOutputStream(languageFolder + language + ".txt"); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8); + BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter); + + // Output normal Language data + for (int i = 0; i < keyList.size(); i++) { + bufferedWriter.write(keyList.get(i) + valueList.get(i)); + bufferedWriter.newLine(); + } + bufferedWriter.newLine(); + // Output any custom language strings the user had + if (currentLanguageValues != null) { + for (String key : currentLanguageValues.keySet()) { + bufferedWriter.write(key + "=" + currentLanguageValues.get(key)); + bufferedWriter.newLine(); + } + } + + bufferedWriter.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + if (fileOutputStream != null) { + try { + fileOutputStream.close(); + } catch (Exception e) { + //Ignored + } + } + } + if (updated) { + Stargate.log.info("[stargate] Your language file (" + language + ".txt) has been updated"); + } + } + + /** + * Reads language strings + * @param inputStream

The input stream to read from

+ * @param keyList

The key list to add keys to

+ * @param valueList

The value list to add values to

+ * @param currentLanguageValues

The current values of the loaded/processed language

+ * @return

True if at least one line was updated

+ * @throws IOException

if unable to read a language file

+ */ + private boolean readChangedLanguageStrings(InputStream inputStream, List keyList, List valueList, + Map currentLanguageValues) throws IOException { + boolean updated = false; + // Input stuff + InputStreamReader inputStreamReader = new InputStreamReader(inputStream); + BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + + String line = bufferedReader.readLine(); + boolean firstLine = true; + while (line != null) { + // Strip UTF BOM + if (firstLine) { + line = removeUTF8BOM(line); + firstLine = false; + } + // Split at first "=" + int equalSignIndex = line.indexOf('='); + if (equalSignIndex == -1) { + keyList.add(""); + valueList.add(""); + line = bufferedReader.readLine(); + continue; + } + String key = line.substring(0, equalSignIndex); + String value = line.substring(equalSignIndex); + + if (currentLanguageValues == null || currentLanguageValues.get(key) == null) { + keyList.add(key); + valueList.add(value); + updated = true; + } else { + keyList.add(key); + valueList.add("=" + currentLanguageValues.get(key).replace('\u00A7', '&')); + currentLanguageValues.remove(key); + } + line = bufferedReader.readLine(); + } + bufferedReader.close(); + return updated; + } + + /** + * Loads the given language + * @param lang

The language to load

+ * @return

A mapping between loaded string indexes and the strings to display

+ */ + private Map load(String lang) { + return load(lang, null); + } + + /** + * Loads the given language + * @param lang

The language to load

+ * @param inputStream

An optional input stream to use. Defaults to using a file input stream

+ * @return

A mapping between loaded string indexes and the strings to display

+ */ + private Map load(String lang, InputStream inputStream) { + Map strings = new HashMap<>(); + FileInputStream fileInputStream = null; + InputStreamReader inputStreamReader; + try { + if (inputStream == null) { + fileInputStream = new FileInputStream(languageFolder + lang + ".txt"); + inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8); + } else { + inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + } + readLanguageFile(inputStreamReader, strings); + } catch (Exception e) { + return null; + } finally { + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) { + //Ignored + } + } + } + return strings; + } + + /** + * Reads a language file given its input stream + * @param inputStreamReader

The input stream reader to read from

+ * @param strings

The loaded string pairs

+ * @throws IOException

If unable to read the file

+ */ + private void readLanguageFile(InputStreamReader inputStreamReader, Map strings) throws IOException { + BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + String line = bufferedReader.readLine(); + boolean firstLine = true; + while (line != null) { + // Strip UTF BOM + if (firstLine) { + line = removeUTF8BOM(line); + firstLine = false; + } + // Split at first "=" + int equalSignIndex = line.indexOf('='); + if (equalSignIndex == -1) { + line = bufferedReader.readLine(); + continue; + } + String key = line.substring(0, equalSignIndex); + String val = ChatColor.translateAlternateColorCodes('&', line.substring(equalSignIndex + 1)); + strings.put(key, val); + line = bufferedReader.readLine(); + } + } + + /** + * Prints debug output to the console for checking of loading language strings/translations + */ + public void debug() { + Set keys = loadedStringTranslations.keySet(); + for (String key : keys) { + Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + loadedStringTranslations.get(key)); + } + if (loadedBackupStrings == null) return; + keys = loadedBackupStrings.keySet(); + for (String key : keys) { + Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " + loadedBackupStrings.get(key)); + } + } + + /** + * Removes the UTF-8 Byte Order Mark if present + * @param string

The string to remove the BOM from

+ * @return

A string guaranteed without a BOM

+ */ + private String removeUTF8BOM(String string) { + String UTF8_BOM = "\uFEFF"; + if (string.startsWith(UTF8_BOM)) { + string = string.substring(1); + } + return string; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java new file mode 100644 index 0000000..dca3bd0 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -0,0 +1,1503 @@ +package net.knarcraft.stargate; + +import net.knarcraft.stargate.event.StargateActivateEvent; +import net.knarcraft.stargate.event.StargateCloseEvent; +import net.knarcraft.stargate.event.StargateCreateEvent; +import net.knarcraft.stargate.event.StargateDeactivateEvent; +import net.knarcraft.stargate.event.StargateOpenEvent; +import net.knarcraft.stargate.event.StargatePortalEvent; +import org.bukkit.Axis; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Powerable; +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.entity.minecart.StorageMinecart; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Scanner; +import java.util.UUID; +import java.util.logging.Level; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011 Shaun (sturmeh) + * Copyright (C) 2011 Dinnerbone + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class Portal { + + // Static variables used to store portal lists + private static final HashMap lookupBlocks = new HashMap<>(); + private static final HashMap lookupEntrances = new HashMap<>(); + private static final HashMap lookupControls = new HashMap<>(); + private static final ArrayList allPortals = new ArrayList<>(); + private static final HashMap> allPortalsNet = new HashMap<>(); + private static final HashMap> lookupNamesNet = new HashMap<>(); + + // A list of Bungee gates + private static final HashMap bungeePortals = new HashMap<>(); + + // Gate location block info + private final BlockLocation topLeft; + private final int modX; + private final int modZ; + private final float rotX; + private final Axis rot; + + // Block references + private final BlockLocation id; + private BlockLocation button; + private BlockLocation[] frame; + private BlockLocation[] entrances; + + // Gate information + private String name; + private String destination; + private String lastDest = ""; + private String network; + private final Gate gate; + private String ownerName = ""; + private UUID ownerUUID = null; + private final World world; + private boolean verified; + private boolean fixed; + + // Options + private boolean hidden = false; + private boolean alwaysOn = false; + private boolean priv = false; + private boolean free = false; + private boolean backwards = false; + private boolean show = false; + private boolean noNetwork = false; + private boolean random = false; + private boolean bungee = false; + + // In-use information + private Player player; + private Player activePlayer; + private ArrayList destinations = new ArrayList<>(); + private boolean isOpen = false; + private long openTime; + + private Portal(BlockLocation topLeft, int modX, int modZ, + float rotX, BlockLocation id, BlockLocation button, + String dest, String name, + boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, + boolean hidden, boolean alwaysOn, boolean priv, boolean free, boolean backwards, boolean show, boolean noNetwork, boolean random, boolean bungee) { + this.topLeft = topLeft; + this.modX = modX; + this.modZ = modZ; + this.rotX = rotX; + this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; + this.id = id; + this.destination = dest; + this.button = button; + this.verified = verified; + this.network = network; + this.name = name; + this.gate = gate; + this.ownerUUID = ownerUUID; + this.ownerName = ownerName; + this.hidden = hidden; + this.alwaysOn = alwaysOn; + this.priv = priv; + this.free = free; + this.backwards = backwards; + this.show = show; + this.noNetwork = noNetwork; + this.random = random; + this.bungee = bungee; + this.world = topLeft.getWorld(); + this.fixed = dest.length() > 0 || this.random || this.bungee; + + if (this.isAlwaysOn() && !this.isFixed()) { + this.alwaysOn = false; + Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); + } + + if (this.random && !this.isAlwaysOn()) { + this.alwaysOn = true; + Stargate.debug("Portal", "Gate marked as random, set to always-on"); + } + + if (verified) { + this.drawSign(); + } + } + + /** + * Option Check Functions + */ + public boolean isOpen() { + return isOpen || isAlwaysOn(); + } + + public boolean isAlwaysOn() { + return alwaysOn; + } + + public boolean isHidden() { + return hidden; + } + + public boolean isPrivate() { + return priv; + } + + public boolean isFree() { + return free; + } + + public boolean isBackwards() { + return backwards; + } + + public boolean isShown() { + return show; + } + + public boolean isNoNetwork() { + return noNetwork; + } + + public boolean isRandom() { + return random; + } + + public boolean isBungee() { + return bungee; + } + + public void setAlwaysOn(boolean alwaysOn) { + this.alwaysOn = alwaysOn; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public void setPrivate(boolean priv) { + this.priv = priv; + } + + public void setFree(boolean free) { + this.free = free; + } + + public void setBackwards(boolean backwards) { + this.backwards = backwards; + } + + public void setShown(boolean show) { + this.show = show; + } + + public void setNoNetwork(boolean noNetwork) { + this.noNetwork = noNetwork; + } + + public void setRandom(boolean random) { + this.random = random; + } + + /** + * Getters and Setters + */ + + public float getRotation() { + return rotX; + } + + public Axis getAxis() { + return rot; + } + + public Player getActivePlayer() { + return activePlayer; + } + + public String getNetwork() { + return network; + } + + public void setNetwork(String network) { + this.network = network; + } + + public long getOpenTime() { + return openTime; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = filterName(name); + drawSign(); + } + + public Portal getDestination(Player player) { + if (isRandom()) { + destinations = getDestinations(player, getNetwork()); + if (destinations.size() == 0) { + return null; + } + String dest = destinations.get((new Random()).nextInt(destinations.size())); + destinations.clear(); + return Portal.getByName(dest, getNetwork()); + } + return Portal.getByName(destination, getNetwork()); + } + + public Portal getDestination() { + return getDestination(null); + } + + public void setDestination(Portal destination) { + setDestination(destination.getName()); + } + + public void setDestination(String destination) { + this.destination = destination; + } + + public String getDestinationName() { + return destination; + } + + public Gate getGate() { + return gate; + } + + public String getOwnerName() { + return ownerName; + } + + public UUID getOwnerUUID() { + return ownerUUID; + } + + public void setOwner(UUID owner) { + this.ownerUUID = owner; + } + + public boolean isOwner(Player player) { + if (this.ownerUUID != null) { + return player.getUniqueId().compareTo(this.ownerUUID) == 0; + } else { + return player.getName().equalsIgnoreCase(this.ownerName); + } + } + + public BlockLocation[] getEntrances() { + if (entrances == null) { + RelativeBlockVector[] space = gate.getEntrances(); + entrances = new BlockLocation[space.length]; + int i = 0; + + for (RelativeBlockVector vector : space) { + entrances[i++] = getBlockAt(vector); + } + } + return entrances; + } + + public BlockLocation[] getFrame() { + if (frame == null) { + RelativeBlockVector[] border = gate.getBorder(); + frame = new BlockLocation[border.length]; + int i = 0; + + for (RelativeBlockVector vector : border) { + frame[i++] = getBlockAt(vector); + } + } + + return frame; + } + + public BlockLocation getSign() { + return id; + } + + public World getWorld() { + return world; + } + + public BlockLocation getButton() { + return button; + } + + public void setButton(BlockLocation button) { + this.button = button; + } + + public static ArrayList getNetwork(String network) { + return allPortalsNet.get(network.toLowerCase()); + } + + public boolean open(boolean force) { + return open(null, force); + } + + public boolean open(Player openFor, boolean force) { + // Call the StargateOpenEvent + StargateOpenEvent event = new StargateOpenEvent(openFor, this, force); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) return false; + force = event.getForce(); + + if (isOpen() && !force) return false; + + Material openType = gate.getPortalBlockOpen(); + Axis ax = openType == Material.NETHER_PORTAL ? rot : null; + for (BlockLocation inside : getEntrances()) { + Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, ax)); + } + + isOpen = true; + openTime = System.currentTimeMillis() / 1000; + Stargate.openList.add(this); + Stargate.activeList.remove(this); + + // Open remote gate + if (!isAlwaysOn()) { + player = openFor; + + Portal end = getDestination(); + // Only open dest if it's not-fixed or points at this gate + if (!random && end != null && (!end.isFixed() || end.getDestinationName().equalsIgnoreCase(getName())) && !end.isOpen()) { + end.open(openFor, false); + end.setDestination(this); + if (end.isVerified()) end.drawSign(); + } + } + + return true; + } + + public void close(boolean force) { + if (!isOpen) return; + // Call the StargateCloseEvent + StargateCloseEvent event = new StargateCloseEvent(this, force); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) return; + force = event.getForce(); + + if (isAlwaysOn() && !force) return; // Only close always-open if forced + + // Close this gate, then the dest gate. + Material closedType = gate.getPortalBlockClosed(); + for (BlockLocation inside : getEntrances()) { + Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType)); + } + + player = null; + isOpen = false; + Stargate.openList.remove(this); + Stargate.activeList.remove(this); + + if (!isAlwaysOn()) { + Portal end = getDestination(); + + if (end != null && end.isOpen()) { + end.deactivate(); // Clear it's destination first. + end.close(false); + } + } + + deactivate(); + } + + public boolean isOpenFor(Player player) { + if (!isOpen) { + return false; + } + if ((isAlwaysOn()) || (this.player == null)) { + return true; + } + return (player != null) && (player.getName().equalsIgnoreCase(this.player.getName())); + } + + public boolean isFixed() { + return fixed; + } + + public boolean isPowered() { + RelativeBlockVector[] controls = gate.getControls(); + + for (RelativeBlockVector vector : controls) { + BlockData data = getBlockAt(vector).getBlock().getBlockData(); + + if (data instanceof Powerable && ((Powerable) data).isPowered()) { + return true; + } + } + + return false; + } + + public void teleport(Player player, Portal origin, PlayerMoveEvent event) { + Location traveller = player.getLocation(); + Location exit = getExit(traveller); + + // Handle backwards gates + int adjust = 180; + 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); + // Teleport is cancelled + if (pEvent.isCancelled()) { + origin.teleport(player, origin, event); + return; + } + // Update exit if needed + exit = pEvent.getExit(); + } + + // If no event is passed in, assume it's a teleport, and act as such + if (event == null) { + exit.setYaw(this.getRotation()); + player.teleport(exit); + } else { + // The new method to teleport in a move event is set the "to" field. + event.setTo(exit); + } + } + + 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); + + double velocity = vehicle.getVelocity().length(); + + // Stop and teleport + vehicle.setVelocity(new Vector()); + + // Get new velocity + final Vector newVelocity = new Vector(modX, 0.0F, modZ); + newVelocity.multiply(velocity); + + List passengers = vehicle.getPassengers(); + if (!passengers.isEmpty()) { + final Vehicle v = exit.getWorld().spawn(exit, vehicle.getClass()); + final Entity passenger = passengers.get(0); + vehicle.eject(); + vehicle.remove(); + passenger.eject(); + passenger.teleport(exit); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> { + v.addPassenger(passenger); + v.setVelocity(newVelocity); + }, 1); + } else { + Vehicle mc = exit.getWorld().spawn(exit, vehicle.getClass()); + if (mc instanceof StorageMinecart) { + StorageMinecart smc = (StorageMinecart) mc; + smc.getInventory().setContents(((StorageMinecart) vehicle).getInventory().getContents()); + } + mc.setVelocity(newVelocity); + vehicle.remove(); + } + } + + public Location getExit(Location traveller) { + Location loc = 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); + } else { + Stargate.log.log(Level.WARNING, "[stargate] 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); + } + + loc.setPitch(traveller.getPitch()); + return loc; + } + return traveller; + } + + public boolean isChunkLoaded() { + return getWorld().isChunkLoaded(topLeft.getBlock().getChunk()); + } + + public boolean isVerified() { + verified = true; + if (!Stargate.verifyPortals) { + return true; + } + for (RelativeBlockVector control : gate.getControls()) { + verified = verified && getBlockAt(control).getBlock().getType().equals(gate.getControlBlock()); + } + return verified; + } + + public boolean wasVerified() { + if (!Stargate.verifyPortals) { + return true; + } + return verified; + } + + public boolean checkIntegrity() { + if (!Stargate.verifyPortals) { + return true; + } + return gate.matches(topLeft, modX, modZ); + } + + public ArrayList getDestinations(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(getName())) continue; + // Check if dest is a fixed gate not pointing to this gate + if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(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; + // Visible to this player. + if (Stargate.canSee(player, portal)) { + destinations.add(portal.getName()); + } + } + return destinations; + } + + public boolean activate(Player player) { + destinations.clear(); + destination = ""; + Stargate.activeList.add(this); + activePlayer = player; + String network = getNetwork(); + destinations = getDestinations(player, network); + if (Stargate.sortLists) { + Collections.sort(destinations); + } + if (Stargate.destMemory && !lastDest.isEmpty() && destinations.contains(lastDest)) { + destination = lastDest; + } + + StargateActivateEvent event = new StargateActivateEvent(this, player, destinations, destination); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + Stargate.activeList.remove(this); + return false; + } + destination = event.getDestination(); + destinations = event.getDestinations(); + drawSign(); + return true; + } + + public void deactivate() { + StargateDeactivateEvent event = new StargateDeactivateEvent(this); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) return; + + Stargate.activeList.remove(this); + if (isFixed()) { + return; + } + destinations.clear(); + destination = ""; + activePlayer = null; + drawSign(); + } + + public boolean isActive() { + return isFixed() || (destinations.size() > 0); + } + + public void cycleDestination(Player player) { + cycleDestination(player, 1); + } + + public void cycleDestination(Player player, int dir) { + boolean activate = false; + if (!isActive() || getActivePlayer() != player) { + // If the event is cancelled, return + if (!activate(player)) { + return; + } + Stargate.debug("cycleDestination", "Network Size: " + allPortalsNet.get(network.toLowerCase()).size()); + Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); + activate = true; + } + + if (destinations.size() == 0) { + Stargate.sendMessage(player, Stargate.getString("destEmpty")); + return; + } + + if (!Stargate.destMemory || !activate || lastDest.isEmpty()) { + int index = destinations.indexOf(destination); + index += dir; + if (index >= destinations.size()) + index = 0; + else if (index < 0) + index = destinations.size() - 1; + destination = destinations.get(index); + lastDest = destination; + } + openTime = System.currentTimeMillis() / 1000; + drawSign(); + } + + public final void drawSign() { + BlockState state = id.getBlock().getState(); + if (!(state instanceof Sign)) { + Stargate.log.warning("[stargate] Sign block is not a Sign object"); + Stargate.debug("Portal::drawSign", "Block: " + id.getBlock().getType() + " @ " + id.getBlock().getLocation()); + return; + } + Sign sign = (Sign) state; + Stargate.setLine(sign, 0, "-" + name + "-"); + int max = destinations.size() - 1; + int done = 0; + + if (!isActive()) { + Stargate.setLine(sign, ++done, Stargate.getString("signRightClick")); + Stargate.setLine(sign, ++done, Stargate.getString("signToUse")); + if (!noNetwork) { + Stargate.setLine(sign, ++done, "(" + network + ")"); + } + } else { + // Awesome new logic for Bungee gates + if (isBungee()) { + Stargate.setLine(sign, ++done, Stargate.getString("bungeeSign")); + Stargate.setLine(sign, ++done, ">" + destination + "<"); + Stargate.setLine(sign, ++done, "[" + network + "]"); + } else if (isFixed()) { + if (isRandom()) { + Stargate.setLine(sign, ++done, "> " + Stargate.getString("signRandom") + " <"); + } else { + Stargate.setLine(sign, ++done, ">" + destination + "<"); + } + if (noNetwork) { + Stargate.setLine(sign, ++done, ""); + } else { + Stargate.setLine(sign, ++done, "(" + network + ")"); + } + Portal dest = Portal.getByName(destination, network); + if (dest == null && !isRandom()) { + Stargate.setLine(sign, ++done, Stargate.getString("signDisconnected")); + } else { + Stargate.setLine(sign, ++done, ""); + } + } else { + int index = destinations.indexOf(destination); + if ((index == max) && (max > 1) && (++done <= 3)) { + if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { + Portal dest = Portal.getByName(destinations.get(index - 2), network); + boolean green = Stargate.isFree(activePlayer, this, dest); + Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 2)); + } else { + Stargate.setLine(sign, done, destinations.get(index - 2)); + } + } + if ((index > 0) && (++done <= 3)) { + if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { + Portal dest = Portal.getByName(destinations.get(index - 1), network); + boolean green = Stargate.isFree(activePlayer, this, dest); + Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 1)); + } else { + Stargate.setLine(sign, done, destinations.get(index - 1)); + } + } + if (++done <= 3) { + if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { + Portal dest = Portal.getByName(destination, network); + boolean green = Stargate.isFree(activePlayer, this, dest); + Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + ">" + destination + "<"); + } else { + Stargate.setLine(sign, done, " >" + destination + "< "); + } + } + if ((max >= index + 1) && (++done <= 3)) { + if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { + Portal dest = Portal.getByName(destinations.get(index + 1), network); + boolean green = Stargate.isFree(activePlayer, this, dest); + Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 1)); + } else { + Stargate.setLine(sign, done, destinations.get(index + 1)); + } + } + if ((max >= index + 2) && (++done <= 3)) { + if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { + Portal dest = Portal.getByName(destinations.get(index + 2), network); + boolean green = Stargate.isFree(activePlayer, this, dest); + Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 2)); + } else { + Stargate.setLine(sign, done, destinations.get(index + 2)); + } + } + } + } + + for (done++; done <= 3; done++) { + sign.setLine(done, ""); + } + + sign.update(); + } + + public void unregister(boolean removeAll) { + Stargate.debug("Unregister", "Unregistering gate " + getName()); + close(true); + + for (BlockLocation block : getFrame()) { + lookupBlocks.remove(block); + } + // Include the sign and button + lookupBlocks.remove(id); + if (button != null) { + lookupBlocks.remove(button); + } + + lookupControls.remove(id); + if (button != null) + lookupControls.remove(button); + + for (BlockLocation entrance : getEntrances()) { + lookupEntrances.remove(entrance); + } + + if (removeAll) + allPortals.remove(this); + + if (bungee) { + bungeePortals.remove(getName().toLowerCase()); + } else { + lookupNamesNet.get(getNetwork().toLowerCase()).remove(getName().toLowerCase()); + allPortalsNet.get(getNetwork().toLowerCase()).remove(getName().toLowerCase()); + + for (String originName : allPortalsNet.get(getNetwork().toLowerCase())) { + Portal origin = Portal.getByName(originName, getNetwork()); + if (origin == null) continue; + if (!origin.getDestinationName().equalsIgnoreCase(getName())) continue; + if (!origin.isVerified()) continue; + if (origin.isFixed()) origin.drawSign(); + if (origin.isAlwaysOn()) origin.close(true); + } + } + + if (id.getBlock().getBlockData() instanceof WallSign) { + Sign sign = (Sign) id.getBlock().getState(); + sign.setLine(0, getName()); + sign.setLine(1, ""); + sign.setLine(2, ""); + sign.setLine(3, ""); + sign.update(); + } + + saveAllGates(getWorld()); + } + + private BlockLocation getBlockAt(RelativeBlockVector vector) { + return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); + } + + private void register() { + fixed = destination.length() > 0 || random || bungee; + + // Bungee gates are stored in their own list + if (isBungee()) { + bungeePortals.put(getName().toLowerCase(), this); + } else { + // Check if network exists in our network list + if (!lookupNamesNet.containsKey(getNetwork().toLowerCase())) { + Stargate.debug("register", "Network " + getNetwork() + " not in lookupNamesNet, adding"); + lookupNamesNet.put(getNetwork().toLowerCase(), new HashMap<>()); + } + lookupNamesNet.get(getNetwork().toLowerCase()).put(getName().toLowerCase(), this); + + // Check if this network exists + if (!allPortalsNet.containsKey(getNetwork().toLowerCase())) { + Stargate.debug("register", "Network " + getNetwork() + " not in allPortalsNet, adding"); + allPortalsNet.put(getNetwork().toLowerCase(), new ArrayList<>()); + } + allPortalsNet.get(getNetwork().toLowerCase()).add(getName().toLowerCase()); + } + + for (BlockLocation block : getFrame()) { + lookupBlocks.put(block, this); + } + // Include the sign and button + lookupBlocks.put(id, this); + if (button != null) { + lookupBlocks.put(button, this); + } + + lookupControls.put(id, this); + if (button != null) + lookupControls.put(button, this); + + for (BlockLocation entrance : getEntrances()) { + lookupEntrances.put(entrance, this); + } + + allPortals.add(this); + } + + public static Portal createPortal(SignChangeEvent event, Player player) { + BlockLocation id = new BlockLocation(event.getBlock()); + Block idParent = id.getParent(); + if (idParent == null) { + return null; + } + + if (Gate.getGatesByControlBlock(idParent).length == 0) return null; + + if (Portal.getByBlock(idParent) != null) { + Stargate.debug("createPortal", "idParent belongs to existing gate"); + return null; + } + + BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); + BlockLocation topleft = null; + String name = filterName(event.getLine(0)); + String destName = 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 free = (options.indexOf('f') != -1); + boolean backwards = (options.indexOf('b') != -1); + boolean show = (options.indexOf('s') != -1); + boolean noNetwork = (options.indexOf('n') != -1); + boolean random = (options.indexOf('r') != -1); + boolean bungee = (options.indexOf('u') != -1); + + // Check permissions for options. + if (hidden && !Stargate.canOption(player, "hidden")) hidden = false; + if (alwaysOn && !Stargate.canOption(player, "alwayson")) alwaysOn = false; + if (priv && !Stargate.canOption(player, "private")) priv = false; + if (free && !Stargate.canOption(player, "free")) free = false; + if (backwards && !Stargate.canOption(player, "backwards")) backwards = false; + if (show && !Stargate.canOption(player, "show")) show = false; + if (noNetwork && !Stargate.canOption(player, "nonetwork")) noNetwork = false; + if (random && !Stargate.canOption(player, "random")) random = false; + + // Can not create a non-fixed always-on gate. + if (alwaysOn && destName.length() == 0) { + alwaysOn = false; + } + + // Show isn't useful if A is false + if (show && !alwaysOn) { + show = false; + } + + // Random gates are always on and can't be shown + if (random) { + alwaysOn = true; + show = false; + } + + // Bungee gates are always on and don't support Random + if (bungee) { + alwaysOn = true; + random = false; + } + + // Moved the layout check so as to avoid invalid messages when not making a gate + int modX = 0; + int modZ = 0; + float rotX = 0f; + BlockFace buttonfacing = BlockFace.DOWN; + + if (idParent.getX() > id.getBlock().getX()) { + modZ -= 1; + rotX = 90f; + buttonfacing = BlockFace.WEST; + } else if (idParent.getX() < id.getBlock().getX()) { + modZ += 1; + rotX = 270f; + buttonfacing = BlockFace.EAST; + } else if (idParent.getZ() > id.getBlock().getZ()) { + modX += 1; + rotX = 180f; + buttonfacing = BlockFace.NORTH; + } else if (idParent.getZ() < id.getBlock().getZ()) { + modX -= 1; + rotX = 0f; + buttonfacing = BlockFace.SOUTH; + } + + Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); + Gate gate = null; + RelativeBlockVector buttonVector = null; + + for (Gate possibility : possibleGates) { + if ((gate == null) && (buttonVector == null)) { + RelativeBlockVector[] vectors = possibility.getControls(); + RelativeBlockVector otherControl = null; + + for (RelativeBlockVector vector : vectors) { + BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); + + if (gate == null) { + if (possibility.matches(tl, modX, modZ, true)) { + gate = possibility; + topleft = tl; + + if (otherControl != null) { + buttonVector = otherControl; + } + } + } else if (otherControl != null) { + buttonVector = vector; + } + + otherControl = vector; + } + } + } + + if ((gate == null) || (buttonVector == null)) { + Stargate.debug("createPortal", "Could not find matching gate layout"); + return null; + } + + // If the player is trying to create a Bungee gate without permissions, drop out here + // Do this after the gate layout check, in the least + if (bungee) { + if (!Stargate.enableBungee) { + Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); + return null; + } else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { + Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); + return null; + } else if (destName.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); + + if (!bungee && (network.length() < 1 || network.length() > 11)) { + network = Stargate.getDefaultNetwork(); + } + + boolean deny = false; + String denyMsg = ""; + + // Check if the player can create gates on this network + if (!bungee && !Stargate.canCreate(player, network)) { + Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); + if (Stargate.canCreatePersonal(player)) { + network = player.getName(); + if (network.length() > 11) network = network.substring(0, 11); + Stargate.debug("createPortal", "Creating personal portal"); + Stargate.sendMessage(player, Stargate.getString("createPersonal")); + } else { + Stargate.debug("createPortal", "Player does not have access to network"); + deny = true; + denyMsg = Stargate.getString("createNetDeny"); + //return null; + } + } + + // Check if the player can create this gate layout + String gateName = gate.getFilename(); + gateName = gateName.substring(0, gateName.indexOf('.')); + if (!deny && !Stargate.canCreateGate(player, gateName)) { + Stargate.debug("createPortal", "Player does not have access to gate layout"); + deny = true; + denyMsg = Stargate.getString("createGateDeny"); + } + + // Check if the user can create gates to this world. + if (!bungee && !deny && destName.length() > 0) { + Portal p = Portal.getByName(destName, network); + if (p != null) { + String world = p.getWorld().getName(); + if (!Stargate.canAccessWorld(player, world)) { + Stargate.debug("canCreate", "Player does not have access to destination world"); + deny = true; + denyMsg = Stargate.getString("createWorldDeny"); + } + } + } + + // 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); + if (Portal.getByBlock(b.getBlock()) != null) { + Stargate.debug("createPortal", "Gate conflicts with existing gate"); + Stargate.sendMessage(player, Stargate.getString("createConflict")); + return null; + } + } + + 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); + + int cost = Stargate.getCreateCost(player, gate); + + // Call StargateCreateEvent + StargateCreateEvent cEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); + Stargate.server.getPluginManager().callEvent(cEvent); + if (cEvent.isCancelled()) { + return null; + } + if (cEvent.getDeny()) { + Stargate.sendMessage(player, cEvent.getDenyReason()); + return null; + } + + cost = cEvent.getCost(); + + // Name & Network can be changed in the event, so do these checks here. + if (portal.getName().length() < 1 || portal.getName().length() > 11) { + Stargate.debug("createPortal", "Name length error"); + Stargate.sendMessage(player, Stargate.getString("createNameLength")); + return null; + } + + // Don't do network checks for bungee gates + if (portal.isBungee()) { + if (bungeePortals.get(portal.getName().toLowerCase()) != null) { + Stargate.debug("createPortal::Bungee", "Gate Exists"); + Stargate.sendMessage(player, Stargate.getString("createExists")); + return null; + } + } else { + if (getByName(portal.getName(), portal.getNetwork()) != null) { + Stargate.debug("createPortal", "Name Error"); + Stargate.sendMessage(player, Stargate.getString("createExists")); + return null; + } + + // Check if there are too many gates in this network + ArrayList netList = allPortalsNet.get(portal.getNetwork().toLowerCase()); + if (Stargate.maxGates > 0 && netList != null && netList.size() >= Stargate.maxGates) { + Stargate.sendMessage(player, Stargate.getString("createFull")); + return null; + } + } + + if (cost > 0) { + if (!Stargate.chargePlayer(player, cost)) { + String inFundMsg = Stargate.getString("ecoInFunds"); + inFundMsg = Stargate.replaceVars(inFundMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), name}); + Stargate.sendMessage(player, inFundMsg); + Stargate.debug("createPortal", "Insufficient Funds"); + return null; + } + String deductMsg = Stargate.getString("ecoDeduct"); + deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), name}); + Stargate.sendMessage(player, deductMsg, false); + } + + // No button on an always-open gate. + if (!alwaysOn) { + button = topleft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); + Directional buttondata = (Directional) Bukkit.createBlockData(gate.getButton()); + buttondata.setFacing(buttonfacing); + button.getBlock().setBlockData(buttondata); + portal.setButton(button); + } + + portal.register(); + portal.drawSign(); + // Open always on gate + if (portal.isRandom() || portal.isBungee()) { + portal.open(true); + } else if (portal.isAlwaysOn()) { + Portal dest = Portal.getByName(destName, portal.getNetwork()); + if (dest != null) { + portal.open(true); + dest.drawSign(); + } + // Set the inside of the gate to its closed material + } else { + for (BlockLocation inside : portal.getEntrances()) { + inside.setType(portal.getGate().getPortalBlockClosed()); + } + } + + // Don't do network stuff for bungee gates + if (!portal.isBungee()) { + // Open any always on gate pointing at this gate + for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { + Portal origin = Portal.getByName(originName, portal.getNetwork()); + if (origin == null) continue; + if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; + if (!origin.isVerified()) continue; + if (origin.isFixed()) origin.drawSign(); + if (origin.isAlwaysOn()) origin.open(true); + } + } + + saveAllGates(portal.getWorld()); + + return portal; + } + + public static Portal getByName(String name, String network) { + if (!lookupNamesNet.containsKey(network.toLowerCase())) return null; + return lookupNamesNet.get(network.toLowerCase()).get(name.toLowerCase()); + + } + + public static Portal getByEntrance(Location location) { + return lookupEntrances.get(new BlockLocation(location)); + } + + public static Portal getByEntrance(Block block) { + return lookupEntrances.get(new BlockLocation(block)); + } + + public static Portal getByAdjacentEntrance(Location loc) { + int centerX = loc.getBlockX(); + int centerY = loc.getBlockY(); + int centerZ = loc.getBlockZ(); + World world = loc.getWorld(); + Portal portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX + 1, centerY, centerZ)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX - 1, centerY, centerZ)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ + 1)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ - 1)); + if (portal != null) { + return portal; + } + return null; + } + + public static Portal getByControl(Block block) { + return lookupControls.get(new BlockLocation(block)); + } + + public static Portal getByBlock(Block block) { + return lookupBlocks.get(new BlockLocation(block)); + } + + public static Portal getBungeeGate(String name) { + return bungeePortals.get(name.toLowerCase()); + } + + public static void saveAllGates(World world) { + Stargate.managedWorlds.add(world.getName()); + String loc = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; + + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(loc, false)); + + for (Portal portal : allPortals) { + String wName = portal.world.getName(); + if (!wName.equalsIgnoreCase(world.getName())) continue; + StringBuilder builder = new StringBuilder(); + BlockLocation sign = portal.id; + BlockLocation button = portal.button; + + builder.append(portal.name); + builder.append(':'); + builder.append(sign.toString()); + builder.append(':'); + builder.append((button != null) ? button.toString() : ""); + builder.append(':'); + builder.append(portal.modX); + builder.append(':'); + builder.append(portal.modZ); + builder.append(':'); + builder.append(portal.rotX); + builder.append(':'); + builder.append(portal.topLeft.toString()); + builder.append(':'); + builder.append(portal.gate.getFilename()); + builder.append(':'); + builder.append(portal.isFixed() ? portal.getDestinationName() : ""); + builder.append(':'); + builder.append(portal.getNetwork()); + builder.append(':'); + UUID owner = portal.getOwnerUUID(); + if (owner != null) { + builder.append(portal.getOwnerUUID().toString()); + } else { + builder.append(portal.getOwnerName()); + } + builder.append(':'); + builder.append(portal.isHidden()); + builder.append(':'); + builder.append(portal.isAlwaysOn()); + builder.append(':'); + builder.append(portal.isPrivate()); + builder.append(':'); + builder.append(portal.world.getName()); + builder.append(':'); + builder.append(portal.isFree()); + builder.append(':'); + builder.append(portal.isBackwards()); + builder.append(':'); + builder.append(portal.isShown()); + builder.append(':'); + builder.append(portal.isNoNetwork()); + builder.append(':'); + builder.append(portal.isRandom()); + builder.append(':'); + builder.append(portal.isBungee()); + + bw.append(builder.toString()); + bw.newLine(); + } + + bw.close(); + } catch (Exception e) { + Stargate.log.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); + } + } + + public static void clearGates() { + lookupBlocks.clear(); + lookupNamesNet.clear(); + lookupEntrances.clear(); + lookupControls.clear(); + allPortals.clear(); + allPortalsNet.clear(); + } + + public static boolean loadAllGates(World world) { + String location = Stargate.getSaveLocation(); + + File db = new File(location, world.getName() + ".db"); + + if (db.exists()) { + int l = 0; + int portalCount = 0; + try { + Scanner scanner = new Scanner(db); + while (scanner.hasNextLine()) { + l++; + String line = scanner.nextLine().trim(); + if (line.startsWith("#") || line.isEmpty()) { + continue; + } + String[] split = line.split(":"); + if (split.length < 8) { + Stargate.log.info("[stargate] Invalid line - " + l); + continue; + } + String name = split[0]; + BlockLocation sign = new BlockLocation(world, split[1]); + BlockLocation button = (split[2].length() > 0) ? new BlockLocation(world, split[2]) : null; + int modX = Integer.parseInt(split[3]); + int modZ = Integer.parseInt(split[4]); + float rotX = Float.parseFloat(split[5]); + BlockLocation topLeft = new BlockLocation(world, split[6]); + Gate gate = Gate.getGateByName(split[7]); + if (gate == null) { + Stargate.log.info("[stargate] Gate layout on line " + l + " does not exist [" + split[7] + "]"); + continue; + } + + String dest = (split.length > 8) ? split[8] : ""; + String network = (split.length > 9) ? split[9] : Stargate.getDefaultNetwork(); + if (network.isEmpty()) network = Stargate.getDefaultNetwork(); + String ownerString = (split.length > 10) ? split[10] : ""; + boolean hidden = (split.length > 11) && split[11].equalsIgnoreCase("true"); + boolean alwaysOn = (split.length > 12) && split[12].equalsIgnoreCase("true"); + boolean priv = (split.length > 13) && split[13].equalsIgnoreCase("true"); + boolean free = (split.length > 15) && split[15].equalsIgnoreCase("true"); + boolean backwards = (split.length > 16) && split[16].equalsIgnoreCase("true"); + boolean show = (split.length > 17) && split[17].equalsIgnoreCase("true"); + boolean noNetwork = (split.length > 18) && split[18].equalsIgnoreCase("true"); + boolean random = (split.length > 19) && split[19].equalsIgnoreCase("true"); + boolean bungee = (split.length > 20) && split[20].equalsIgnoreCase("true"); + + // Attempt to get owner as UUID + UUID ownerUUID = null; + String ownerName; + if (ownerString.length() > 16) { + try { + ownerUUID = UUID.fromString(ownerString); + OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); + ownerName = offlineOwner.getName(); + } catch (IllegalArgumentException ex) { + // neither name nor UUID, so keep it as-is + ownerName = ownerString; + Stargate.debug("loadAllGates", "Invalid stargate owner string: " + ownerString); + } + } else { + ownerName = ownerString; + } + + Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, dest, name, false, network, gate, ownerUUID, ownerName, hidden, alwaysOn, priv, free, backwards, show, noNetwork, random, bungee); + portal.register(); + portal.close(true); + } + scanner.close(); + + // Open any always-on gates. Do this here as it should be more efficient than in the loop. + int OpenCount = 0; + for (Iterator iter = allPortals.iterator(); iter.hasNext(); ) { + Portal portal = iter.next(); + if (portal == null) continue; + + // Verify portal integrity/register portal + if (!portal.wasVerified()) { + if (!portal.isVerified() || !portal.checkIntegrity()) { + // DEBUG + for (RelativeBlockVector control : portal.getGate().getControls()) { + if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { + Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); + } + } + portal.unregister(false); + iter.remove(); + Stargate.log.info("[stargate] Destroying stargate at " + portal.toString()); + continue; + } + } + portalCount++; + + if (portal.isFixed() && (Stargate.enableBungee && portal.isBungee() + || portal.getDestination() != null && portal.isAlwaysOn())) { + portal.open(true); + OpenCount++; + } + } + Stargate.log.info("[stargate] {" + world.getName() + "} Loaded " + portalCount + " stargates with " + OpenCount + " set as always-on"); + return true; + } catch (Exception e) { + Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + db.getName() + ": " + l); + e.printStackTrace(); + } + } else { + Stargate.log.info("[stargate] {" + world.getName() + "} No stargates for world "); + } + return false; + } + + public static void closeAllGates() { + Stargate.log.info("Closing all stargates."); + for (Portal p : allPortals) { + if (p == null) continue; + p.close(true); + } + } + + public static String filterName(String input) { + if (input == null) { + return ""; + } + return input.replaceAll("[\\|:#]", "").trim(); + } + + @Override + public String toString() { + return String.format("Portal [id=%s, network=%s name=%s, type=%s]", id, network, name, gate.getFilename()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((network == null) ? 0 : network.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Portal other = (Portal) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equalsIgnoreCase(other.name)) + return false; + if (network == null) { + if (other.network != null) + return false; + } else if (!network.equalsIgnoreCase(other.network)) + return false; + return true; + } +} diff --git a/src/net/TheDgtl/Stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java similarity index 60% rename from src/net/TheDgtl/Stargate/RelativeBlockVector.java rename to src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index 60876a5..c3e40f3 100644 --- a/src/net/TheDgtl/Stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -1,45 +1,48 @@ -package net.TheDgtl.Stargate; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class RelativeBlockVector { - private int right = 0; - private int depth = 0; - private int distance = 0; - - public RelativeBlockVector(int right, int depth, int distance) { - this.right = right; - this.depth = depth; - this.distance = distance; - } - - public int getRight() { - return right; - } - - public int getDepth() { - return depth; - } - - public int getDistance() { - return distance; - } -} +package net.knarcraft.stargate; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011 Shaun (sturmeh) + * Copyright (C) 2011 Dinnerbone + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class RelativeBlockVector { + + private int right = 0; + private int depth = 0; + private int distance = 0; + + public RelativeBlockVector(int right, int depth, int distance) { + this.right = right; + this.depth = depth; + this.distance = distance; + } + + public int getRight() { + return right; + } + + public int getDepth() { + return depth; + } + + public int getDistance() { + return distance; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/StarGateThread.java b/src/main/java/net/knarcraft/stargate/StarGateThread.java new file mode 100644 index 0000000..516b326 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/StarGateThread.java @@ -0,0 +1,34 @@ +package net.knarcraft.stargate; + +import java.util.Iterator; + +/** + * This class contains the function used to close servers which should no longer be open/active + */ +public class StarGateThread implements Runnable { + + public void run() { + long time = System.currentTimeMillis() / 1000; + // Close open portals + for (Iterator iterator = Stargate.openList.iterator(); iterator.hasNext(); ) { + Portal p = iterator.next(); + // Skip always open gates + if (p.isAlwaysOn()) continue; + if (!p.isOpen()) continue; + if (time > p.getOpenTime() + Stargate.getOpenTime()) { + p.close(false); + iterator.remove(); + } + } + // Deactivate active portals + for (Iterator iterator = Stargate.activeList.iterator(); iterator.hasNext(); ) { + Portal p = iterator.next(); + if (!p.isActive()) continue; + if (time > p.getOpenTime() + Stargate.getActiveTime()) { + p.deactivate(); + iterator.remove(); + } + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java new file mode 100644 index 0000000..269e541 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -0,0 +1,1280 @@ +package net.knarcraft.stargate; + +import net.knarcraft.stargate.event.StargateAccessEvent; +import net.knarcraft.stargate.event.StargateDestroyEvent; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.Tag; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.EndGateway; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Orientable; +import org.bukkit.block.data.type.WallSign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.event.vehicle.VehicleMoveEvent; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011 Shaun (sturmeh) + * Copyright (C) 2011 Dinnerbone + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +@SuppressWarnings("unused") +public class Stargate extends JavaPlugin { + + public static Logger log; + private FileConfiguration newConfig; + private PluginManager pm; + public static Server server; + public static Stargate stargate; + private static LanguageLoader languageLoader; + + private static String portalFolder; + private static String gateFolder; + private static String langFolder; + private static String defNetwork = "central"; + private static boolean destroyExplosion = false; + public static int maxGates = 0; + private static String langName = "en"; + private static final int activeTime = 10; + private static final int openTime = 10; + public static boolean destMemory = false; + public static boolean handleVehicles = true; + public static boolean sortLists = false; + public static boolean protectEntrance = false; + public static boolean enableBungee = true; + public static boolean verifyPortals = true; + public static ChatColor signColor; + + // Temp workaround for snowmen, don't check gate entrance + public static boolean ignoreEntrance = false; + + // Used for debug + public static boolean debug = false; + public static boolean permDebug = false; + + public static ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); + public static ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); + + // Used for populating gate open/closed material. + public static Queue blockPopulatorQueue = new LinkedList<>(); + + // HashMap of player names for Bungee support + public static Map bungeeQueue = new HashMap<>(); + + // World names that contain stargates + public static HashSet managedWorlds = new HashSet<>(); + + @Override + public void onDisable() { + Portal.closeAllGates(); + Portal.clearGates(); + managedWorlds.clear(); + getServer().getScheduler().cancelTasks(this); + } + + @Override + public void onEnable() { + PluginDescriptionFile pdfFile = this.getDescription(); + pm = getServer().getPluginManager(); + newConfig = this.getConfig(); + log = Logger.getLogger("Minecraft"); + Stargate.server = getServer(); + Stargate.stargate = this; + + // Set portalFile and gateFolder to the plugin folder as defaults. + String dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); + portalFolder = dataFolderPath + "/portals/"; + gateFolder = dataFolderPath + "/gates/"; + langFolder = dataFolderPath + "/lang/"; + + log.info(pdfFile.getName() + " v." + pdfFile.getVersion() + " is enabled."); + + // Register events before loading gates to stop weird things happening. + pm.registerEvents(new pListener(), this); + pm.registerEvents(new bListener(), this); + + pm.registerEvents(new vListener(), this); + pm.registerEvents(new eListener(), this); + pm.registerEvents(new wListener(), this); + pm.registerEvents(new sListener(), this); + + this.loadConfig(); + + // Enable the required channels for Bungee support + if (enableBungee) { + Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCoordListener()); + } + + // It is important to load languages here, as they are used during reloadGates() + languageLoader = new LanguageLoader(langFolder, Stargate.langName); + + this.migrate(); + this.loadGates(); + this.loadAllPortals(); + + // Check to see if Economy is loaded yet. + if (EconomyHandler.setupEconomy(pm)) { + if (EconomyHandler.economy != null) + log.info("[stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); + } + + getServer().getScheduler().scheduleSyncRepeatingTask(this, new StarGateThread(), 0L, 100L); + getServer().getScheduler().scheduleSyncRepeatingTask(this, new BlockPopulatorThread(), 0L, 1L); + } + + public static int getOpenTime() { + return openTime; + } + + public static int getActiveTime() { + return activeTime; + } + + public void loadConfig() { + reloadConfig(); + newConfig = this.getConfig(); + // Copy default values if required + newConfig.options().copyDefaults(true); + + // Load values into variables + portalFolder = newConfig.getString("portal-folder"); + gateFolder = newConfig.getString("gate-folder"); + defNetwork = newConfig.getString("default-gate-network").trim(); + destroyExplosion = newConfig.getBoolean("destroyexplosion"); + maxGates = newConfig.getInt("maxgates"); + langName = newConfig.getString("lang"); + destMemory = newConfig.getBoolean("destMemory"); + ignoreEntrance = newConfig.getBoolean("ignoreEntrance"); + handleVehicles = newConfig.getBoolean("handleVehicles"); + sortLists = newConfig.getBoolean("sortLists"); + protectEntrance = newConfig.getBoolean("protectEntrance"); + enableBungee = newConfig.getBoolean("enableBungee"); + verifyPortals = newConfig.getBoolean("verifyPortals"); + // Sign color + String sc = newConfig.getString("signColor"); + try { + signColor = ChatColor.valueOf(sc.toUpperCase()); + } catch (Exception ignore) { + log.warning("[stargate] You have specified an invalid color in your config.yml. Defaulting to BLACK"); + signColor = ChatColor.BLACK; + } + // Debug + debug = newConfig.getBoolean("debug"); + permDebug = newConfig.getBoolean("permdebug"); + // Economy + EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); + EconomyHandler.createCost = newConfig.getInt("createcost"); + EconomyHandler.destroyCost = newConfig.getInt("destroycost"); + EconomyHandler.useCost = newConfig.getInt("usecost"); + EconomyHandler.toOwner = newConfig.getBoolean("toowner"); + EconomyHandler.chargeFreeDestination = newConfig.getBoolean("chargefreedestination"); + EconomyHandler.freeGatesGreen = newConfig.getBoolean("freegatesgreen"); + + this.saveConfig(); + } + + public void closeAllPortals() { + // Close all gates prior to reloading + for (Portal p : openList) { + p.close(true); + } + } + + public void loadGates() { + Gate.loadGates(gateFolder); + log.info("[stargate] Loaded " + Gate.getGateCount() + " gate layouts"); + } + + public void loadAllPortals() { + for (World world : getServer().getWorlds()) { + if (!managedWorlds.contains(world.getName())) { + Portal.loadAllGates(world); + managedWorlds.add(world.getName()); + } + } + } + + private void migrate() { + // Only migrate if new file doesn't exist. + File newPortalDir = new File(portalFolder); + if (!newPortalDir.exists()) { + newPortalDir.mkdirs(); + } + File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); + if (!newFile.exists()) { + newFile.getParentFile().mkdirs(); + } + } + + public static void debug(String rout, String msg) { + if (Stargate.debug) { + log.info("[stargate::" + rout + "] " + msg); + } else { + log.log(Level.FINEST, "[stargate::" + rout + "] " + msg); + } + } + + public static void sendMessage(CommandSender player, String message) { + sendMessage(player, message, true); + } + + public static void sendMessage(CommandSender player, String message, boolean error) { + if (message.isEmpty()) return; + message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); + if (error) + player.sendMessage(ChatColor.RED + Stargate.getString("prefix") + ChatColor.WHITE + message); + else + player.sendMessage(ChatColor.GREEN + Stargate.getString("prefix") + ChatColor.WHITE + message); + } + + public static void setLine(Sign sign, int index, String text) { + sign.setLine(index, Stargate.signColor + text); + } + + public static String getSaveLocation() { + return portalFolder; + } + + public static String getGateFolder() { + return gateFolder; + } + + public static String getDefaultNetwork() { + return defNetwork; + } + + public static String getString(String name) { + return languageLoader.getString(name); + } + + public static void openPortal(Player player, Portal portal) { + Portal destination = portal.getDestination(); + + // Always-open gate -- Do nothing + if (portal.isAlwaysOn()) { + return; + } + + // Random gate -- Do nothing + if (portal.isRandom()) + return; + + // Invalid destination + if ((destination == null) || (destination == portal)) { + Stargate.sendMessage(player, Stargate.getString("invalidMsg")); + return; + } + + // Gate is already open + if (portal.isOpen()) { + // Close if this player opened the gate + if (portal.getActivePlayer() == player) { + portal.close(false); + } + return; + } + + // Gate that someone else is using -- Deny access + if ((!portal.isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + // Check if the player can use the private gate + if (portal.isPrivate() && !Stargate.canPrivate(player, portal)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + // Destination blocked + if ((destination.isOpen()) && (!destination.isAlwaysOn())) { + Stargate.sendMessage(player, Stargate.getString("blockMsg")); + return; + } + + // Open gate + portal.open(player, false); + } + + /* + * Check whether the player has the given permissions. + */ + public static boolean hasPerm(Player player, String perm) { + if (permDebug) + Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); + return player.hasPermission(perm); + } + + /* + * Check a deep permission, this will check to see if the permissions is defined for this use + * If using Permissions it will return the same as hasPerm + * If using SuperPerms will return true if the node isn't defined + * Or the value of the node if it is + */ + public static boolean hasPermDeep(Player player, String perm) { + if (!player.isPermissionSet(perm)) { + if (permDebug) + Stargate.debug("hasPermDeep::SuperPerm", perm + " => true"); + return true; + } + if (permDebug) + Stargate.debug("hasPermDeep::SuperPerms", perm + " => " + player.hasPermission(perm)); + return player.hasPermission(perm); + } + + /* + * Check whether player can teleport to dest world + */ + public static boolean canAccessWorld(Player player, String world) { + // Can use all stargate player features or access all worlds + if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.world")) { + // Do a deep check to see if the player lacks this specific world node + return hasPermDeep(player, "stargate.world." + world); + } + // Can access dest world + return hasPerm(player, "stargate.world." + world); + } + + /* + * Check whether player can use network + */ + public static boolean canAccessNetwork(Player player, String network) { + // Can user all stargate player features, or access all networks + if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.network")) { + // Do a deep check to see if the player lacks this specific network node + return hasPermDeep(player, "stargate.network." + network); + } + // Can access this network + if (hasPerm(player, "stargate.network." + network)) return true; + // Is able to create personal gates (Assumption is made they can also access them) + String playerName = player.getName(); + if (playerName.length() > 11) playerName = playerName.substring(0, 11); + return network.equals(playerName) && hasPerm(player, "stargate.create.personal"); + } + + /* + * Check whether the player can access this server + */ + public static boolean canAccessServer(Player player, String server) { + // Can user all stargate player features, or access all servers + if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.servers")) { + // Do a deep check to see if the player lacks this specific server node + return hasPermDeep(player, "stargate.server." + server); + } + // Can access this server + return hasPerm(player, "stargate.server." + server); + } + + /* + * Call the StargateAccessPortal event, used for other plugins to bypass Permissions checks + */ + public static boolean canAccessPortal(Player player, Portal portal, boolean deny) { + StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); + Stargate.server.getPluginManager().callEvent(event); + return !event.getDeny(); + } + + /* + * Return true if the portal is free for the player + */ + public static boolean isFree(Player player, Portal src, Portal dest) { + // This gate is free + if (src.isFree()) return true; + // Player gets free use + if (hasPerm(player, "stargate.free") || Stargate.hasPerm(player, "stargate.free.use")) return true; + // Don't charge for free destination gates + return dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree(); + } + + /* + * Check whether the player can see this gate (Hidden property check) + */ + public static boolean canSee(Player player, Portal portal) { + // The gate is not hidden + if (!portal.isHidden()) return true; + // The player is an admin with the ability to see hidden gates + if (hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.hidden")) return true; + // The player is the owner of the gate + return portal.isOwner(player); + } + + /* + * Check if the player can use this private gate + */ + public static boolean canPrivate(Player player, Portal portal) { + // Check if the player is the owner of the gate + if (portal.isOwner(player)) return true; + // The player is an admin with the ability to use private gates + return hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.private"); + } + + /* + * Check if the player has access to {option} + */ + public static boolean canOption(Player player, String option) { + // Check if the player can use all options + if (hasPerm(player, "stargate.option")) return true; + // Check if they can use this specific option + return hasPerm(player, "stargate.option." + option); + } + + /* + * Check if the player can create gates on {network} + */ + public static boolean canCreate(Player player, String network) { + // Check for general create + if (hasPerm(player, "stargate.create")) return true; + // Check for all network create permission + if (hasPerm(player, "stargate.create.network")) { + // Do a deep check to see if the player lacks this specific network node + return hasPermDeep(player, "stargate.create.network." + network); + } + // Check for this specific network + return hasPerm(player, "stargate.create.network." + network); + + } + + /* + * Check if the player can create a personal gate + */ + public static boolean canCreatePersonal(Player player) { + // Check for general create + if (hasPerm(player, "stargate.create")) return true; + // Check for personal + return hasPerm(player, "stargate.create.personal"); + } + + /* + * Check if the player can create this gate layout + */ + public static boolean canCreateGate(Player player, String gate) { + // Check for general create + if (hasPerm(player, "stargate.create")) return true; + // Check for all gate create permissions + if (hasPerm(player, "stargate.create.gate")) { + // Do a deep check to see if the player lacks this specific gate node + return hasPermDeep(player, "stargate.create.gate." + gate); + } + // Check for this specific gate + return hasPerm(player, "stargate.create.gate." + gate); + } + + /* + * Check if the player can destroy this gate + */ + public static boolean canDestroy(Player player, Portal portal) { + String network = portal.getNetwork(); + // Check for general destroy + if (hasPerm(player, "stargate.destroy")) return true; + // Check for all network destroy permission + if (hasPerm(player, "stargate.destroy.network")) { + // Do a deep check to see if the player lacks permission for this network node + return hasPermDeep(player, "stargate.destroy.network." + network); + } + // Check for this specific network + if (hasPerm(player, "stargate.destroy.network." + network)) return true; + // Check for personal gate + return portal.isOwner(player) && hasPerm(player, "stargate.destroy.personal"); + } + + /* + * Charge player for {action} if required, true on success, false if can't afford + */ + public static boolean chargePlayer(Player player, String target, int cost) { + // If cost is 0 + if (cost == 0) return true; + // Economy is disabled + if (!EconomyHandler.useEconomy()) return true; + // Charge player + return EconomyHandler.chargePlayer(player, target, cost); + } + + /* + * Charge player for {action} if required, true on success, false if can't afford + */ + public static boolean chargePlayer(Player player, UUID target, int cost) { + // If cost is 0 + if (cost == 0) return true; + // Economy is disabled + if (!EconomyHandler.useEconomy()) return true; + // Charge player + return EconomyHandler.chargePlayer(player, target, cost); + } + + /* + * Charge player for {action} if required, true on success, false if can't afford + */ + public static boolean chargePlayer(Player player, int cost) { + // If cost is 0 + if (cost == 0) return true; + // Economy is disabled + if (!EconomyHandler.useEconomy()) return true; + // Charge player + return EconomyHandler.chargePlayer(player, cost); + } + + /* + * Determine the cost of a gate + */ + public static int getUseCost(Player player, Portal src, Portal dest) { + // Not using Economy + if (!EconomyHandler.useEconomy()) return 0; + // Portal is free + if (src.isFree()) return 0; + // Not charging for free destinations + if (dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree()) return 0; + // Cost is 0 if the player owns this gate and funds go to the owner + if (src.getGate().getToOwner() && src.isOwner(player)) return 0; + // Player gets free gate use + if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.use")) return 0; + + return src.getGate().getUseCost(); + } + + /* + * Determine the cost to create the gate + */ + public static int getCreateCost(Player player, Gate gate) { + // Not using Economy + if (!EconomyHandler.useEconomy()) return 0; + // Player gets free gate destruction + if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.create")) return 0; + + return gate.getCreateCost(); + } + + /* + * Determine the cost to destroy the gate + */ + public static int getDestroyCost(Player player, Gate gate) { + // Not using Economy + if (!EconomyHandler.useEconomy()) return 0; + // Player gets free gate destruction + if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.destroy")) return 0; + + return gate.getDestroyCost(); + } + + /* + * Check if a plugin is loaded/enabled already. Returns the plugin if so, null otherwise + */ + private Plugin checkPlugin(String p) { + Plugin plugin = pm.getPlugin(p); + return checkPlugin(plugin); + } + + private Plugin checkPlugin(Plugin plugin) { + if (plugin != null && plugin.isEnabled()) { + log.info("[stargate] Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")"); + return plugin; + } + return null; + } + + /* + * Parse a given text string and replace the variables + */ + public static String replaceVars(String format, String[] search, String[] replace) { + if (search.length != replace.length) return ""; + for (int i = 0; i < search.length; i++) { + format = format.replace(search[i], replace[i]); + } + return format; + } + + private class vListener implements Listener { + @EventHandler + public void onVehicleMove(VehicleMoveEvent event) { + if (!handleVehicles) return; + List passengers = event.getVehicle().getPassengers(); + Vehicle vehicle = event.getVehicle(); + + Portal portal = Portal.getByEntrance(event.getTo()); + if (portal == null || !portal.isOpen()) return; + + // We don't support vehicles in Bungee portals + if (portal.isBungee()) return; + + if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { + /* + Player player = (Player) passengers.get(0); + if (!portal.isOpenFor(player)) { + stargate.sendMessage(player, stargate.getString("denyMsg")); + return; + } + + Portal dest = portal.getDestination(player); + if (dest == null) return; + boolean deny = false; + // Check if player has access to this network + if (!canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + // Check if player has access to destination world + if (!canAccessWorld(player, dest.getWorld().getName())) { + deny = true; + } + + if (!canAccessPortal(player, portal, deny)) { + stargate.sendMessage(player, stargate.getString("denyMsg")); + portal.close(false); + return; + } + + int cost = stargate.getUseCost(player, portal, dest); + if (cost > 0) { + boolean success; + if(portal.getGate().getToOwner()) { + if(portal.getOwnerUUID() == null) { + success = stargate.chargePlayer(player, portal.getOwnerUUID(), cost); + } else { + success = stargate.chargePlayer(player, portal.getOwnerName(), cost); + } + } else { + success = stargate.chargePlayer(player, cost); + } + if(!success) { + // Insufficient Funds + stargate.sendMessage(player, stargate.getString("inFunds")); + portal.close(false); + return; + } + String deductMsg = stargate.getString("ecoDeduct"); + deductMsg = stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); + sendMessage(player, deductMsg, false); + if (portal.getGate().getToOwner()) { + Player p; + if(portal.getOwnerUUID() != null) { + p = server.getPlayer(portal.getOwnerUUID()); + } else { + p = server.getPlayer(portal.getOwnerName()); + } + if (p != null) { + String obtainedMsg = stargate.getString("ecoObtain"); + obtainedMsg = stargate.replaceVars(obtainedMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); + stargate.sendMessage(p, obtainedMsg, false); + } + } + } + + stargate.sendMessage(player, stargate.getString("teleportMsg"), false); + dest.teleport(vehicle); + portal.close(false); + */ + } else { + Portal dest = portal.getDestination(); + if (dest == null) return; + dest.teleport(vehicle); + } + } + } + + private class pListener implements Listener { + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (!enableBungee) return; + + Player player = event.getPlayer(); + String destination = bungeeQueue.remove(player.getName().toLowerCase()); + if (destination == null) return; + + Portal portal = Portal.getBungeeGate(destination); + if (portal == null) { + Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); + return; + } + portal.teleport(player, portal, null); + } + + @EventHandler + 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()) + && Portal.getByAdjacentEntrance(event.getFrom()) != null) { + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + 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()) { + return; + } + + Player player = event.getPlayer(); + Portal portal = Portal.getByEntrance(event.getTo()); + // No portal or not open + if (portal == null || !portal.isOpen()) return; + + // Not open for this player + if (!portal.isOpenFor(player)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + portal.teleport(player, portal, event); + return; + } + + Portal destination = portal.getDestination(player); + if (!portal.isBungee() && destination == null) return; + + boolean deny = false; + // Check if player has access to this server for Bungee gates + if (portal.isBungee()) { + if (!canAccessServer(player, portal.getNetwork())) { + deny = true; + } + } else { + // Check if player has access to this network + if (!canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + // Check if player has access to destination world + if (!canAccessWorld(player, destination.getWorld().getName())) { + deny = true; + } + } + + if (!canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + portal.teleport(player, portal, event); + portal.close(false); + return; + } + + int cost = Stargate.getUseCost(player, portal, destination); + if (cost > 0) { + boolean success; + if (portal.getGate().getToOwner()) { + if (portal.getOwnerUUID() == null) { + success = Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); + } else { + success = Stargate.chargePlayer(player, portal.getOwnerName(), cost); + } + } else { + success = Stargate.chargePlayer(player, cost); + } + if (!success) { + // Insufficient Funds + Stargate.sendMessage(player, Stargate.getString("inFunds")); + portal.close(false); + return; + } + String deductMsg = Stargate.getString("ecoDeduct"); + deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); + sendMessage(player, deductMsg, false); + if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) { + Player p; + if (portal.getOwnerUUID() != null) { + p = server.getPlayer(portal.getOwnerUUID()); + } else { + p = server.getPlayer(portal.getOwnerName()); + } + if (p != null) { + String obtainedMsg = Stargate.getString("ecoObtain"); + obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); + Stargate.sendMessage(p, obtainedMsg, false); + } + } + } + + Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + + // BungeeCord Support + if (portal.isBungee()) { + if (!enableBungee) { + player.sendMessage(Stargate.getString("bungeeDisabled")); + portal.close(false); + return; + } + + // Teleport the player back to this gate, for sanity's sake + portal.teleport(player, portal, 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() + "#@#" + portal.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(portal.getNetwork()); // Server + msgData.writeUTF("SGBungee"); // Channel + msgData.writeShort(msg.length()); // Data Length + msgData.writeBytes(msg); // Data + player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); + } catch (IOException ex) { + Stargate.log.severe("[stargate] Error sending BungeeCord teleport packet"); + ex.printStackTrace(); + return; + } + + // Connect player to new server + try { + ByteArrayOutputStream bao = new ByteArrayOutputStream(); + DataOutputStream msgData = new DataOutputStream(bao); + msgData.writeUTF("Connect"); + msgData.writeUTF(portal.getNetwork()); + + player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); + bao.reset(); + } catch (IOException ex) { + Stargate.log.severe("[stargate] Error sending BungeeCord connect packet"); + ex.printStackTrace(); + return; + } + + // Close portal if required (Should never be) + portal.close(false); + return; + } + + destination.teleport(player, portal, event); + portal.close(false); + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + + if (block == null) return; + + // Right click + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (block.getBlockData() instanceof WallSign) { + Portal portal = Portal.getByBlock(block); + if (portal == null) return; + // Cancel item use + event.setUseItemInHand(Result.DENY); + event.setUseInteractedBlock(Result.DENY); + + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + if ((!portal.isOpen()) && (!portal.isFixed())) { + portal.cycleDestination(player); + } + return; + } + + // Implement right-click to toggle a stargate, gets around spawn protection problem. + if (Tag.BUTTONS.isTagged(block.getType())) { + Portal portal = Portal.getByBlock(block); + if (portal == null) return; + + // Cancel item use + event.setUseItemInHand(Result.DENY); + event.setUseInteractedBlock(Result.DENY); + + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + openPortal(player, portal); + if (portal.isOpenFor(player)) { + event.setUseInteractedBlock(Result.ALLOW); + } + } + return; + } + + // Left click + if (event.getAction() == Action.LEFT_CLICK_BLOCK) { + // Check if we're scrolling a sign + if (block.getBlockData() instanceof WallSign) { + Portal portal = Portal.getByBlock(block); + if (portal == null) return; + + event.setUseInteractedBlock(Result.DENY); + // Only cancel event in creative mode + if (player.getGameMode().equals(GameMode.CREATIVE)) { + event.setCancelled(true); + } + + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + if ((!portal.isOpen()) && (!portal.isFixed())) { + portal.cycleDestination(player, -1); + } + } + } + } + } + + private class bListener implements Listener { + @EventHandler + public void onSignChange(SignChangeEvent event) { + if (event.isCancelled()) return; + Player player = event.getPlayer(); + Block block = event.getBlock(); + if (!(block.getBlockData() instanceof WallSign)) return; + + final Portal portal = Portal.createPortal(event, player); + // Not creating a gate, just placing a sign + if (portal == null) return; + + Stargate.sendMessage(player, Stargate.getString("createMsg"), false); + Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); + Stargate.server.getScheduler().scheduleSyncDelayedTask(stargate, new Runnable() { + public void run() { + portal.drawSign(); + } + }, 1); + } + + // Switch to HIGHEST priority so as to come after block protection plugins (Hopefully) + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlockBreak(BlockBreakEvent event) { + if (event.isCancelled()) return; + Block block = event.getBlock(); + Player player = event.getPlayer(); + + Portal portal = Portal.getByBlock(block); + if (portal == null && protectEntrance) + portal = Portal.getByEntrance(block); + if (portal == null) return; + + boolean deny = false; + String denyMsg = ""; + + if (!Stargate.canDestroy(player, portal)) { + denyMsg = "Permission Denied"; // TODO: Change to stargate.getString() + deny = true; + Stargate.log.info("[stargate] " + player.getName() + " tried to destroy gate"); + } + + int cost = Stargate.getDestroyCost(player, portal.getGate()); + + StargateDestroyEvent dEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); + Stargate.server.getPluginManager().callEvent(dEvent); + if (dEvent.isCancelled()) { + event.setCancelled(true); + return; + } + if (dEvent.getDeny()) { + Stargate.sendMessage(player, dEvent.getDenyReason()); + event.setCancelled(true); + return; + } + + cost = dEvent.getCost(); + + if (cost != 0) { + if (!Stargate.chargePlayer(player, cost)) { + Stargate.debug("onBlockBreak", "Insufficient Funds"); + Stargate.sendMessage(player, Stargate.getString("inFunds")); + event.setCancelled(true); + return; + } + + if (cost > 0) { + String deductMsg = Stargate.getString("ecoDeduct"); + deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); + sendMessage(player, deductMsg, false); + } else if (cost < 0) { + String refundMsg = Stargate.getString("ecoRefund"); + refundMsg = Stargate.replaceVars(refundMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(-cost), portal.getName()}); + sendMessage(player, refundMsg, false); + } + } + + portal.unregister(true); + Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); + } + + @EventHandler + public void onBlockPhysics(BlockPhysicsEvent event) { + Block block = event.getBlock(); + Portal portal = null; + + // Handle keeping portal material and buttons around + if (block.getType() == Material.NETHER_PORTAL) { + portal = Portal.getByEntrance(block); + } else if (Tag.BUTTONS.isTagged(block.getType())) { + portal = Portal.getByControl(block); + } + if (portal != null) event.setCancelled(true); + } + + @EventHandler + public void onBlockFromTo(BlockFromToEvent event) { + Portal portal = Portal.getByEntrance(event.getBlock()); + + if (portal != null) { + event.setCancelled((event.getBlock().getY() == event.getToBlock().getY())); + } + } + + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent event) { + for (Block block : event.getBlocks()) { + Portal portal = Portal.getByBlock(block); + if (portal != null) { + event.setCancelled(true); + return; + } + } + } + + @EventHandler + public void onPistonRetract(BlockPistonRetractEvent event) { + if (!event.isSticky()) return; + for (Block block : event.getBlocks()) { + Portal portal = Portal.getByBlock(block); + if (portal != null) { + event.setCancelled(true); + return; + } + } + } + } + + private class wListener implements Listener { + @EventHandler + public void onWorldLoad(WorldLoadEvent event) { + if (!managedWorlds.contains(event.getWorld().getName()) + && Portal.loadAllGates(event.getWorld())) { + managedWorlds.add(event.getWorld().getName()); + } + } + + // We need to reload all gates on world unload, boo + @EventHandler + public void onWorldUnload(WorldUnloadEvent event) { + Stargate.debug("onWorldUnload", "Reloading all Stargates"); + World w = event.getWorld(); + if (managedWorlds.contains(w.getName())) { + managedWorlds.remove(w.getName()); + Portal.clearGates(); + for (World world : server.getWorlds()) { + if (managedWorlds.contains(world.getName())) { + Portal.loadAllGates(world); + } + } + } + } + } + + private class eListener implements Listener { + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (event.isCancelled()) return; + for (Block b : event.blockList()) { + Portal portal = Portal.getByBlock(b); + if (portal == null) continue; + if (destroyExplosion) { + portal.unregister(true); + } else { + event.setCancelled(true); + break; + } + } + } + } + + private class sListener implements Listener { + @EventHandler + public void onPluginEnable(PluginEnableEvent event) { + if (EconomyHandler.setupEconomy(getServer().getPluginManager())) { + log.info("[stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); + } + } + + @EventHandler + public void onPluginDisable(PluginDisableEvent event) { + if (event.getPlugin().equals(EconomyHandler.vault)) { + log.info("[stargate] Vault plugin lost."); + } + } + } + + private class BlockPopulatorThread implements Runnable { + public void run() { + long sTime = System.nanoTime(); + while (System.nanoTime() - sTime < 25000000) { + BloxPopulator b = Stargate.blockPopulatorQueue.poll(); + if (b == null) return; + Block blk = b.getBlockLocation().getBlock(); + blk.setType(b.getMat(), false); + if (b.getMat() == Material.END_GATEWAY && blk.getWorld().getEnvironment() == World.Environment.THE_END) { + // force a location to prevent exit gateway generation + EndGateway gateway = (EndGateway) blk.getState(); + gateway.setExitLocation(blk.getWorld().getSpawnLocation()); + gateway.setExactTeleport(true); + gateway.update(false, false); + } else if (b.getAxis() != null) { + Orientable orientable = (Orientable) blk.getBlockData(); + orientable.setAxis(b.getAxis()); + blk.setBlockData(orientable); + } + } + } + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, 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(); + Portal.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) + log.info("[stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); + } + } + 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 BungeeCoordListener()); + } else { + Bukkit.getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord"); + Bukkit.getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord"); + } + } + + sendMessage(sender, "stargate reloaded"); + return true; + } + return false; + } + return false; + } + +} diff --git a/src/net/TheDgtl/Stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java similarity index 76% rename from src/net/TheDgtl/Stargate/event/StargateAccessEvent.java rename to src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 6dc1585..07d58a3 100644 --- a/src/net/TheDgtl/Stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -1,59 +1,71 @@ -package net.TheDgtl.Stargate.event; - -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -import net.TheDgtl.Stargate.Portal; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateAccessEvent extends StargateEvent { - private final Player player; - private boolean deny; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public StargateAccessEvent(Player player, Portal portal, boolean deny) { - super("StargateAccessEvent", portal); - - this.player = player; - this.deny = deny; - } - - public boolean getDeny() { - return this.deny; - } - - public void setDeny(boolean deny) { - this.deny = deny; - } - - public Player getPlayer() { - return this.player; - } - -} +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/* + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + + +@SuppressWarnings("unused") +public class StargateAccessEvent extends StargateEvent { + + private final Player player; + private boolean deny; + + private static final HandlerList handlers = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateAccessEvent(Player player, Portal portal, boolean deny) { + super("StargateAccessEvent", portal); + + this.player = player; + this.deny = deny; + } + + /** + * Gets whether the player should be denied access + * @return

Whether the player should be denied access

+ */ + public boolean getDeny() { + return this.deny; + } + + /** + * Sets whether to deny the player + * @param deny

Whether to deny the player

+ */ + public void setDeny(boolean deny) { + this.deny = deny; + } + + public Player getPlayer() { + return this.player; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java new file mode 100644 index 0000000..c66a65f --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -0,0 +1,72 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import java.util.ArrayList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargateActivateEvent extends StargateEvent { + + private final Player player; + private ArrayList destinations; + private String destination; + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateActivateEvent(Portal portal, Player player, ArrayList destinations, String destination) { + super("StargatActivateEvent", portal); + + this.player = player; + this.destinations = destinations; + this.destination = destination; + } + + public Player getPlayer() { + return player; + } + + public ArrayList getDestinations() { + return destinations; + } + + public void setDestinations(ArrayList destinations) { + this.destinations = destinations; + } + + public String getDestination() { + return destination; + } + + public void setDestination(String destination) { + this.destination = destination; + } + +} diff --git a/src/net/TheDgtl/Stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java similarity index 54% rename from src/net/TheDgtl/Stargate/event/StargateCloseEvent.java rename to src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index add60c0..89d586e 100644 --- a/src/net/TheDgtl/Stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -1,50 +1,53 @@ -package net.TheDgtl.Stargate.event; - -import org.bukkit.event.HandlerList; - -import net.TheDgtl.Stargate.Portal; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateCloseEvent extends StargateEvent { - private boolean force; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public StargateCloseEvent(Portal portal, boolean force) { - super("StargateCloseEvent", portal); - - this.force = force; - } - - public boolean getForce() { - return force; - } - - public void setForce(boolean force) { - this.force = force; - } -} +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.event.HandlerList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargateCloseEvent extends StargateEvent { + + private boolean force; + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateCloseEvent(Portal portal, boolean force) { + super("StargateCloseEvent", portal); + + this.force = force; + } + + public boolean getForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java new file mode 100644 index 0000000..eed8d74 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -0,0 +1,85 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargateCreateEvent extends StargateEvent { + + private final Player player; + private boolean deny; + private String denyReason; + private final String[] lines; + private int cost; + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateCreateEvent(Player player, Portal portal, String[] lines, boolean deny, String denyReason, int cost) { + super("StargateCreateEvent", portal); + this.player = player; + this.lines = lines; + this.deny = deny; + this.denyReason = denyReason; + this.cost = cost; + } + + public Player getPlayer() { + return player; + } + + public String getLine(int index) throws IndexOutOfBoundsException { + return lines[index]; + } + + public boolean getDeny() { + return deny; + } + + public void setDeny(boolean deny) { + this.deny = deny; + } + + public String getDenyReason() { + return denyReason; + } + + public void setDenyReason(String denyReason) { + this.denyReason = denyReason; + } + + public int getCost() { + return cost; + } + + public void setCost(int cost) { + this.cost = cost; + } + +} diff --git a/src/net/TheDgtl/Stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java similarity index 62% rename from src/net/TheDgtl/Stargate/event/StargateDeactivateEvent.java rename to src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index b193139..41b061e 100644 --- a/src/net/TheDgtl/Stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -1,39 +1,41 @@ -package net.TheDgtl.Stargate.event; - -import org.bukkit.event.HandlerList; - -import net.TheDgtl.Stargate.Portal; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateDeactivateEvent extends StargateEvent { - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public StargateDeactivateEvent(Portal portal) { - super("StargatDeactivateEvent", portal); - - } -} +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.event.HandlerList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargateDeactivateEvent extends StargateEvent { + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateDeactivateEvent(Portal portal) { + super("StargatDeactivateEvent", portal); + + } +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java new file mode 100644 index 0000000..227e0c5 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -0,0 +1,79 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargateDestroyEvent extends StargateEvent { + + private final Player player; + private boolean deny; + private String denyReason; + private int cost; + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { + super("StargateDestroyEvent", portal); + this.player = player; + this.deny = deny; + this.denyReason = denyMsg; + this.cost = cost; + } + + public Player getPlayer() { + return player; + } + + public boolean getDeny() { + return deny; + } + + public void setDeny(boolean deny) { + this.deny = deny; + } + + public String getDenyReason() { + return denyReason; + } + + public void setDenyReason(String denyReason) { + this.denyReason = denyReason; + } + + public int getCost() { + return cost; + } + + public void setCost(int cost) { + this.cost = cost; + } + +} diff --git a/src/net/TheDgtl/Stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java similarity index 55% rename from src/net/TheDgtl/Stargate/event/StargateEvent.java rename to src/main/java/net/knarcraft/stargate/event/StargateEvent.java index 7033f33..d3471da 100644 --- a/src/net/TheDgtl/Stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -1,48 +1,54 @@ -package net.TheDgtl.Stargate.event; - -import net.TheDgtl.Stargate.Portal; - -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public abstract class StargateEvent extends Event implements Cancellable { - protected Portal portal; - protected boolean cancelled; - - public StargateEvent(String event, Portal portal) { - this.portal = portal; - this.cancelled = false; - } - - public Portal getPortal() { - return portal; - } - - @Override - public boolean isCancelled() { - return this.cancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } -} +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; + +/* + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * An abstract event describing any stargate event + */ +@SuppressWarnings("unused") +public abstract class StargateEvent extends Event implements Cancellable { + + protected Portal portal; + protected boolean cancelled; + + public StargateEvent(String event, Portal portal) { + this.portal = portal; + this.cancelled = false; + } + + public Portal getPortal() { + return portal; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java new file mode 100644 index 0000000..180b700 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -0,0 +1,65 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargateOpenEvent extends StargateEvent { + + private final Player player; + private boolean force; + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargateOpenEvent(Player player, Portal portal, boolean force) { + super("StargateOpenEvent", portal); + + this.player = player; + this.force = force; + } + + /** + * Return the player than opened the gate. + * + * @return player than opened the gate + */ + public Player getPlayer() { + return player; + } + + public boolean getForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java new file mode 100644 index 0000000..2a3a537 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java @@ -0,0 +1,85 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * stargate - A portal plugin for Bukkit + * Copyright (C) 2011, 2012 Steven "Drakia" Scott + * Copyright (C) 2021 Kristian Knarvik + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +public class StargatePortalEvent extends StargateEvent { + + private final Player player; + private final Portal destination; + private Location exit; + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public StargatePortalEvent(Player player, Portal portal, Portal dest, Location exit) { + super("StargatePortalEvent", portal); + + this.player = player; + this.destination = dest; + this.exit = exit; + } + + /** + * Return the player that went through the gate. + * + * @return player that went through the gate + */ + public Player getPlayer() { + return player; + } + + /** + * Return the destination gate + * + * @return destination gate + */ + public Portal getDestination() { + return destination; + } + + /** + * Return the location of the players exit point + * + * @return org.bukkit.Location Location of the exit point + */ + public Location getExit() { + return exit; + } + + /** + * Set the location of the players exit point + */ + public void setExit(Location loc) { + this.exit = loc; + } + +} diff --git a/src/config.yml b/src/main/resources/config.yml similarity index 90% rename from src/config.yml rename to src/main/resources/config.yml index 65f2b73..75997b3 100644 --- a/src/config.yml +++ b/src/main/resources/config.yml @@ -1,54 +1,54 @@ -# Stargate Configuration File -# Main Stargate config -# -# portal-folder - The folder for storing portals -# gate-folder - The folder for storing gate layouts -# default-gate-network - The default gate network -# destroyexplosion - Whether or not to destroy gates with explosions (Creeper, TNT, etc) -# maxgates - The maximum number of gates allowed on a network - 0 for unlimited -# lang - The language file to load for messages -# destMemory - Whether to remember the cursor location between uses -# ignoreEntrance - Ignore the entrance blocks of a gate when checking. Used to work around snowmen -# handleVehicles - Whether to allow vehicles through gates -# sortLists - Whether to sort network lists alphabetically -# protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) -# signColor - The color used for drawing signs (Default: BLACK). -# verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when a stargate is loaded. -############################ -# Stargate economy options # -############################ -# useeconomy - Whether to use an economy plugin -# createcost - The cost to create a gate -# destroycost - The cost to destroy a gate -# usecost - The cost to use a gate -# toowner - Whether the charge for using a gate goes to the gates owner -# chargefreedestination - Whether a gate whose destination is a free gate is still charged -# freegatesgreen - Whether a free gate in the destination list is drawn green -################# -# Debug options # -################# -# debug - Debug -- Only enable if you have issues, massive console output -# permdebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) -portal-folder: plugins/Stargate/portals/ -gate-folder: plugins/Stargate/gates/ -default-gate-network: central -destroyexplosion: false -maxgates: 0 -lang: en -destMemory: false -ignoreEntrance: false -handleVehicles: true -sortLists: false -protectEntrance: false -signColor: BLACK -useeconomy: false -createcost: 0 -destroycost: 0 -usecost: 0 -toowner: false -chargefreedestination: true -freegatesgreen: false -debug: false -permdebug: false -enableBungee: false +# stargate Configuration File +# Main stargate config +# +# portal-folder - The folder for storing portals +# gate-folder - The folder for storing gate layouts +# default-gate-network - The default gate network +# destroyexplosion - Whether or not to destroy gates with explosions (Creeper, TNT, etc) +# maxgates - The maximum number of gates allowed on a network - 0 for unlimited +# lang - The language file to load for messages +# destMemory - Whether to remember the cursor location between uses +# ignoreEntrance - Ignore the entrance blocks of a gate when checking. Used to work around snowmen +# handleVehicles - Whether to allow vehicles through gates +# sortLists - Whether to sort network lists alphabetically +# protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) +# signColor - The color used for drawing signs (Default: BLACK). +# verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when a stargate is loaded. +############################ +# stargate economy options # +############################ +# useeconomy - Whether to use an economy plugin +# createcost - The cost to create a gate +# destroycost - The cost to destroy a gate +# usecost - The cost to use a gate +# toowner - Whether the charge for using a gate goes to the gates owner +# chargefreedestination - Whether a gate whose destination is a free gate is still charged +# freegatesgreen - Whether a free gate in the destination list is drawn green +################# +# Debug options # +################# +# debug - Debug -- Only enable if you have issues, massive console output +# permdebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) +portal-folder: plugins/stargate/portals/ +gate-folder: plugins/stargate/gates/ +default-gate-network: central +destroyexplosion: false +maxgates: 0 +lang: en +destMemory: false +ignoreEntrance: false +handleVehicles: true +sortLists: false +protectEntrance: false +signColor: BLACK +useeconomy: false +createcost: 0 +destroycost: 0 +usecost: 0 +toowner: false +chargefreedestination: true +freegatesgreen: false +debug: false +permdebug: false +enableBungee: false verifyPortals: false \ No newline at end of file diff --git a/src/net/TheDgtl/Stargate/resources/de.txt b/src/main/resources/lang/de.txt similarity index 92% rename from src/net/TheDgtl/Stargate/resources/de.txt rename to src/main/resources/lang/de.txt index 4bcfbb4..c10be27 100644 --- a/src/net/TheDgtl/Stargate/resources/de.txt +++ b/src/main/resources/lang/de.txt @@ -1,28 +1,28 @@ -author=EduardBaer -prefix=[Stargate] -teleportMsg=Du wurdest Teleportiert. -destroyMsg=Gate zerst๖rt -invalidMsg=Ungltiges Ziel -blockMsg=Ziel blockiert -destEmpty=Zielliste leer -denyMsg=Zugriff verweigert - -ecoDeduct=%cost% abgezogen -ecoRefund=%cost% zurckerstattet -ecoObtain=%cost% von Stargate %portal% erhalten -ecoInFunds=Das kannst du dir nicht leisten. - -createMsg=Gate erstellt. -createNetDeny=Du hast keinen Zugriff auf dieses Netzwerk. -createGateDeny=Du hast keinen Zugriff auf dieses Gate-Layout. -createPersonal=Gate im pers๖nlichen Netzwerk erstellt. -createNameLength=Name zu kurz oder zu lang. -createExists=Ein Gate mit diesem Name existiert bereits. -createFull=Dieses Netzwerk ist voll. -createWorldDeny=Du hast keinen Zugriff auf diese Welt. -createConflict=Dieses Gate steht im Konflikt mit einem bereits existierenden. - -signRightClick=Right click -signToUse=to use gate -signRandom=Random +author=EduardBaer +prefix=[Stargate] +teleportMsg=Du wurdest Teleportiert. +destroyMsg=Gate zerst๖rt +invalidMsg=Ungltiges Ziel +blockMsg=Ziel blockiert +destEmpty=Zielliste leer +denyMsg=Zugriff verweigert + +ecoDeduct=%cost% abgezogen +ecoRefund=%cost% zurckerstattet +ecoObtain=%cost% von Stargate %portal% erhalten +ecoInFunds=Das kannst du dir nicht leisten. + +createMsg=Gate erstellt. +createNetDeny=Du hast keinen Zugriff auf dieses Netzwerk. +createGateDeny=Du hast keinen Zugriff auf dieses Gate-Layout. +createPersonal=Gate im pers๖nlichen Netzwerk erstellt. +createNameLength=Name zu kurz oder zu chosenLanguage. +createExists=Ein Gate mit diesem Name existiert bereits. +createFull=Dieses Netzwerk ist voll. +createWorldDeny=Du hast keinen Zugriff auf diese Welt. +createConflict=Dieses Gate steht im Konflikt mit einem bereits existierenden. + +signRightClick=Right click +signToUse=to use gate +signRandom=Random signDisconnected=Disconnected \ No newline at end of file diff --git a/src/net/TheDgtl/Stargate/resources/en.txt b/src/main/resources/lang/en.txt similarity index 96% rename from src/net/TheDgtl/Stargate/resources/en.txt rename to src/main/resources/lang/en.txt index 8b50bd0..5227ba7 100644 --- a/src/net/TheDgtl/Stargate/resources/en.txt +++ b/src/main/resources/lang/en.txt @@ -1,32 +1,32 @@ -prefix=[Stargate] -teleportMsg=Teleported -destroyMsg=Gate Destroyed -invalidMsg=Invalid Destination -blockMsg=Destination Blocked -destEmpty=Destination List Empty -denyMsg=Access Denied - -ecoDeduct=Deducted %cost% -ecoRefund=Refunded %cost% -ecoObtain=Obtained %cost% from Stargate %portal% -ecoInFunds=Insufficient Funds - -createMsg=Gate Created -createNetDeny=You do not have access to that network -createGateDeny=You do not have access to that gate layout -createPersonal=Creating gate on personal network -createNameLength=Name too short or too long. -createExists=A gate by that name already exists -createFull=This network is full -createWorldDeny=You do not have access to that world -createConflict=Gate conflicts with existing gate - -signRightClick=Right click -signToUse=to use gate -signRandom=Random -signDisconnected=Disconnected - -bungeeDisabled=BungeeCord support is disabled. -bungeeDeny=You do not have permission to create BungeeCord gates. -bungeeEmpty=BungeeCord gates require both a destination and network. -bungeeSign=Teleport to +prefix=[Stargate] +teleportMsg=Teleported +destroyMsg=Gate Destroyed +invalidMsg=Invalid Destination +blockMsg=Destination Blocked +destEmpty=Destination List Empty +denyMsg=Access Denied + +ecoDeduct=Deducted %cost% +ecoRefund=Refunded %cost% +ecoObtain=Obtained %cost% from Stargate %portal% +ecoInFunds=Insufficient Funds + +createMsg=Gate Created +createNetDeny=You do not have access to that network +createGateDeny=You do not have access to that gate layout +createPersonal=Creating gate on personal network +createNameLength=Name too short or too long. +createExists=A gate by that name already exists +createFull=This network is full +createWorldDeny=You do not have access to that world +createConflict=Gate conflicts with existing gate + +signRightClick=Right click +signToUse=to use gate +signRandom=Random +signDisconnected=Disconnected + +bungeeDisabled=BungeeCord support is disabled. +bungeeDeny=You do not have permission to create BungeeCord gates. +bungeeEmpty=BungeeCord gates require both a destination and network. +bungeeSign=Teleport to diff --git a/src/net/TheDgtl/Stargate/resources/es.txt b/src/main/resources/lang/es.txt similarity index 100% rename from src/net/TheDgtl/Stargate/resources/es.txt rename to src/main/resources/lang/es.txt diff --git a/src/net/TheDgtl/Stargate/resources/fr.txt b/src/main/resources/lang/fr.txt similarity index 100% rename from src/net/TheDgtl/Stargate/resources/fr.txt rename to src/main/resources/lang/fr.txt diff --git a/src/net/TheDgtl/Stargate/resources/hu.txt b/src/main/resources/lang/hu.txt similarity index 100% rename from src/net/TheDgtl/Stargate/resources/hu.txt rename to src/main/resources/lang/hu.txt diff --git a/src/net/TheDgtl/Stargate/resources/it.txt b/src/main/resources/lang/it.txt similarity index 100% rename from src/net/TheDgtl/Stargate/resources/it.txt rename to src/main/resources/lang/it.txt diff --git a/src/net/TheDgtl/Stargate/resources/nl.txt b/src/main/resources/lang/nl.txt similarity index 94% rename from src/net/TheDgtl/Stargate/resources/nl.txt rename to src/main/resources/lang/nl.txt index 57f3db3..2e29b3c 100644 --- a/src/net/TheDgtl/Stargate/resources/nl.txt +++ b/src/main/resources/lang/nl.txt @@ -16,7 +16,7 @@ createMsg=Gate gemaakt createNetDeny=Je hebt geen toegang tot dat netwerk. createGateDeny=Je mag die Gate-Layout niet gebruiken createPersonal=Gate op persoonlijk netwerk gemaakt. -createNameLength=Naam te lang of te kort. +createNameLength=Naam te chosenLanguage of te kort. createExists=Er bestaat al een gate met die naam createFull=Dit netwerk is vol. createWorldDeny=Je mag niet in die wereld komen. diff --git a/src/net/TheDgtl/Stargate/resources/pt-br.txt b/src/main/resources/lang/pt-br.txt similarity index 100% rename from src/net/TheDgtl/Stargate/resources/pt-br.txt rename to src/main/resources/lang/pt-br.txt diff --git a/src/net/TheDgtl/Stargate/resources/ru.txt b/src/main/resources/lang/ru.txt similarity index 100% rename from src/net/TheDgtl/Stargate/resources/ru.txt rename to src/main/resources/lang/ru.txt diff --git a/src/plugin.yml b/src/main/resources/plugin.yml similarity index 84% rename from src/plugin.yml rename to src/main/resources/plugin.yml index 75b676c..3f08d22 100644 --- a/src/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,30 +1,30 @@ -name: Stargate -main: net.TheDgtl.Stargate.Stargate -version: 0.8.0.3 -description: Stargate mod for Bukkit -author: Drakia -website: http://www.thedgtl.net -api-version: 1.13 -commands: - sg: - description: Used to reload the plugin. Console use only. - usage: / reload - Used to reload the plugin. Console use only. -permissions: - stargate.use: - description: Allow use of all gates linking to any world in any network - default: true - stargate.create: - description: Allow creating gates on any network - default: op - stargate.destroy: - description: Allow destruction gates on any network - default: op - stargate.free: - description: Allow free use/creation/destruction of gates - default: op - stargate.option: - description: Allow use of all options - default: op - stargate.admin: - description: Allow all admin features (Hidden/Private only so far) +name: Stargate +main: net.knarcraft.stargate.Stargate +version: 0.8.0.0 +description: Stargate mod for Bukkit +author: EpicKnarvik97 +website: https://knarcraft.net +api-version: 1.16 +commands: + sg: + description: Used to reload the plugin. Console use only. + usage: / reload - Used to reload the plugin. Console use only. +permissions: + stargate.use: + description: Allow use of all gates linking to any world in any network + default: true + stargate.create: + description: Allow creating gates on any network + default: op + stargate.destroy: + description: Allow destruction gates on any network + default: op + stargate.free: + description: Allow free use/creation/destruction of gates + default: op + stargate.option: + description: Allow use of all options + default: op + stargate.admin: + description: Allow all admin features (Hidden/Private only so far) default: op \ No newline at end of file diff --git a/src/net/TheDgtl/Stargate/Blox.java b/src/net/TheDgtl/Stargate/Blox.java deleted file mode 100644 index f45c023..0000000 --- a/src/net/TheDgtl/Stargate/Blox.java +++ /dev/null @@ -1,173 +0,0 @@ -package net.TheDgtl.Stargate; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.type.Sign; -import org.bukkit.block.data.type.WallSign; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class Blox { - private final int x; - private final int y; - private final int z; - private final World world; - private Blox parent = null; - - public Blox (World world, int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - this.world = world; - } - - public Blox (Block block) { - this.x = block.getX(); - this.y = block.getY(); - this.z = block.getZ(); - this.world = block.getWorld(); - } - - public Blox (Location location) { - this.x = location.getBlockX(); - this.y = location.getBlockY(); - this.z = location.getBlockZ(); - this.world = location.getWorld(); - } - - public Blox (World world, String string) { - String[] split = string.split(","); - this.x = Integer.parseInt(split[0]); - this.y = Integer.parseInt(split[1]); - this.z = Integer.parseInt(split[2]); - this.world = world; - } - - public Blox makeRelative(int x, int y, int z) { - return new Blox(this.world, this.x + x, this.y + y, this.z + z); - } - - public Location makeRelativeLoc(double x, double y, double z, float rotX, float rotY) { - return new Location(this.world, (double)this.x + x, (double)this.y + y, (double)this.z + z, rotX, rotY); - } - - public Blox modRelative(int right, int depth, int distance, int modX, int modY, int modZ) { - return makeRelative(-right * modX + distance * modZ, -depth * modY, -right * modZ + -distance * modX); - } - - public Location modRelativeLoc(double right, double depth, double distance, float rotX, float rotY, int modX, int modY, int modZ) { - return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); - } - - public void setType(Material type) { - world.getBlockAt(x, y, z).setType(type); - } - - public Material getType() { - return world.getBlockAt(x, y, z).getType(); - } - - public Block getBlock() { - return world.getBlockAt(x, y, z); - } - - public Location getLocation() { - return new Location(world, x, y, z); - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getZ() { - return z; - } - - public World getWorld() { - return world; - } - - public Block getParent() { - if (parent == null) findParent(); - if (parent == null) return null; - return parent.getBlock(); - } - - private void findParent() { - int offsetX = 0; - int offsetY = 0; - int offsetZ = 0; - - BlockData blk = getBlock().getBlockData(); - if (blk instanceof WallSign) { - BlockFace facing = ((WallSign) blk).getFacing().getOppositeFace(); - offsetX = facing.getModX(); - offsetZ = facing.getModZ(); - } else if (blk instanceof Sign) { - offsetY = -1; - } else { - return; - } - parent = new Blox(world, getX() + offsetX, getY() + offsetY, getZ() + offsetZ); - } - - public String toString() { - StringBuilder builder = new StringBuilder(); - //builder.append(world.getName()); - //builder.append(','); - builder.append(x); - builder.append(','); - builder.append(y); - builder.append(','); - builder.append(z); - return builder.toString(); - } - - @Override - public int hashCode() { - int result = 18; - - result = result * 27 + x; - result = result * 27 + y; - result = result * 27 + z; - result = result * 27 + world.getName().hashCode(); - - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - Blox blox = (Blox) obj; - return (x == blox.x) && (y == blox.y) && (z == blox.z) && (world.getName().equals(blox.world.getName())); - } -} \ No newline at end of file diff --git a/src/net/TheDgtl/Stargate/BloxPopulator.java b/src/net/TheDgtl/Stargate/BloxPopulator.java deleted file mode 100644 index 88290fb..0000000 --- a/src/net/TheDgtl/Stargate/BloxPopulator.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.TheDgtl.Stargate; - -import org.bukkit.Axis; -import org.bukkit.Material; - -public class BloxPopulator { - private Blox blox; - private Material nextMat; - private Axis nextAxis; - - public BloxPopulator(Blox b, Material m) { - blox = b; - nextMat = m; - nextAxis = null; - } - - public BloxPopulator(Blox b, Material m, Axis a) { - blox = b; - nextMat = m; - nextAxis = a; - } - - public void setBlox(Blox b) { - blox = b; - } - - public void setMat(Material m) { - nextMat = m; - } - - public void setAxis(Axis a) { - nextAxis = a; - } - - public Blox getBlox() { - return blox; - } - - public Material getMat() { - return nextMat; - } - - public Axis getAxis() { - return nextAxis; - } - -} diff --git a/src/net/TheDgtl/Stargate/EconomyHandler.java b/src/net/TheDgtl/Stargate/EconomyHandler.java deleted file mode 100644 index 36963d7..0000000 --- a/src/net/TheDgtl/Stargate/EconomyHandler.java +++ /dev/null @@ -1,106 +0,0 @@ -package net.TheDgtl.Stargate; - -import net.milkbowl.vault.economy.Economy; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.RegisteredServiceProvider; - -import java.util.UUID; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class EconomyHandler { - public static boolean economyEnabled = false; - public static Economy economy = null; - public static Plugin vault = null; - - public static int useCost = 0; - public static int createCost = 0; - public static int destroyCost = 0; - public static boolean toOwner = false; - public static boolean chargeFreeDestination = true; - public static boolean freeGatesGreen = false; - - public static double getBalance(Player player) { - if (!economyEnabled) return 0; - return economy.getBalance(player); - } - - public static boolean chargePlayer(Player player, String target, double amount) { - if (!economyEnabled) return true; - if(player.getName().equals(target)) return true; - if(economy != null) { - if(!economy.has(player, amount)) return false; - economy.withdrawPlayer(player, amount); - economy.depositPlayer(target, amount); - } - return true; - } - - public static boolean chargePlayer(Player player, UUID target, double amount) { - if (!economyEnabled) return true; - if(player.getUniqueId().compareTo(target) == 0) return true; - if(economy != null) { - if(!economy.has(player, amount)) return false; - economy.withdrawPlayer(player, amount); - economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); - } - return true; - } - - public static boolean chargePlayer(Player player, double amount) { - if (!economyEnabled) return true; - if(economy != null) { - if(!economy.has(player, amount)) return false; - economy.withdrawPlayer(player, amount); - } - return true; - } - - public static String format(int amt) { - if (economyEnabled) { - return economy.format(amt); - } - return ""; - } - - public static boolean setupEconomy(PluginManager pm) { - if (!economyEnabled) return false; - // Check for Vault - Plugin p = pm.getPlugin("Vault"); - if (p != null && p.isEnabled()) { - RegisteredServiceProvider economyProvider = Stargate.server.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); - if (economyProvider != null) { - economy = economyProvider.getProvider(); - vault = p; - return true; - } - } - economyEnabled = false; - return false; - } - - public static boolean useEconomy() { - return economyEnabled && economy != null; - } - -} diff --git a/src/net/TheDgtl/Stargate/Gate.java b/src/net/TheDgtl/Stargate/Gate.java deleted file mode 100644 index 31bb93f..0000000 --- a/src/net/TheDgtl/Stargate/Gate.java +++ /dev/null @@ -1,513 +0,0 @@ -package net.TheDgtl.Stargate; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Scanner; -import java.util.logging.Level; - -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.block.Block; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class Gate { - private static final Character ANYTHING = ' '; - private static final Character ENTRANCE = '.'; - private static final Character EXIT = '*'; - private static final HashMap gates = new HashMap<>(); - private static final HashMap> controlBlocks = new HashMap<>(); - private static final HashSet frameBlocks = new HashSet<>(); - - private final String filename; - private final Character[][] layout; - private final HashMap types; - private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; - private RelativeBlockVector[] border = new RelativeBlockVector[0]; - private RelativeBlockVector[] controls = new RelativeBlockVector[0]; - private RelativeBlockVector exitBlock = null; - private final HashMap exits = new HashMap<>(); - private Material portalBlockOpen = Material.NETHER_PORTAL; - private Material portalBlockClosed = Material.AIR; - private Material button = Material.STONE_BUTTON; - - // Economy information - private int useCost = -1; - private int createCost = -1; - private int destroyCost = -1; - private boolean toOwner = false; - - public Gate(String filename, Character[][] layout, HashMap types) { - this.filename = filename; - this.layout = layout; - this.types = types; - - populateCoordinates(); - } - - private void populateCoordinates() { - ArrayList entranceList = new ArrayList<>(); - ArrayList borderList = new ArrayList<>(); - ArrayList controlList = new ArrayList<>(); - RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; - int[] exitDepths = new int[layout[0].length]; - RelativeBlockVector lastExit = null; - - 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('-')) { - controlList.add(new RelativeBlockVector(x, y, 0)); - } - - if (key.equals(ENTRANCE) || key.equals(EXIT)) { - entranceList.add(new RelativeBlockVector(x, y, 0)); - exitDepths[x] = y; - if (key.equals(EXIT)) { - this.exitBlock = new RelativeBlockVector(x, y, 0); - } - } else if (!key.equals(ANYTHING)) { - borderList.add(new RelativeBlockVector(x, y, 0)); - } - } - } - - for (int x = 0; x < exitDepths.length; x++) { - relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0); - } - - for (int x = relativeExits.length - 1; x >= 0; x--) { - if (relativeExits[x] != null) { - lastExit = relativeExits[x]; - } else { - relativeExits[x] = lastExit; - } - - if (exitDepths[x] > 0) this.exits.put(relativeExits[x], x); - } - - this.entrances = entranceList.toArray(this.entrances); - this.border = borderList.toArray(this.border); - this.controls = controlList.toArray(this.controls); - } - - public void save(String gateFolder) { - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(gateFolder + filename)); - - writeConfig(bw, "portal-open", portalBlockOpen.name()); - writeConfig(bw, "portal-closed", portalBlockClosed.name()); - writeConfig(bw, "button", button.name()); - if (useCost != -1) - writeConfig(bw, "usecost", useCost); - if (createCost != -1) - writeConfig(bw, "createcost", createCost); - if (destroyCost != -1) - writeConfig(bw, "destroycost", destroyCost); - writeConfig(bw, "toowner", toOwner); - - for (Map.Entry entry : types.entrySet()) { - Character type = entry.getKey(); - Material value = entry.getValue(); - // Skip control values - if (type.equals(ANYTHING) || type.equals(ENTRANCE) || type.equals(EXIT)) { - continue; - } - - bw.append(type); - bw.append('='); - if(value != null) { - bw.append(value.toString()); - } - bw.newLine(); - } - - bw.newLine(); - - for(Character[] aLayout : layout) { - for(Character symbol : aLayout) { - bw.append(symbol); - } - bw.newLine(); - } - - bw.close(); - } catch (IOException ex) { - Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); - } - } - - private void writeConfig(BufferedWriter bw, String key, int value) throws IOException { - bw.append(String.format("%s=%d", key, value)); - bw.newLine(); - } - - private void writeConfig(BufferedWriter bw, String key, boolean value) throws IOException { - bw.append(String.format("%s=%b", key, value)); - bw.newLine(); - } - - private void writeConfig(BufferedWriter bw, String key, String value) throws IOException { - bw.append(String.format("%s=%s", key, value)); - bw.newLine(); - } - - public Character[][] getLayout() { - return layout; - } - - public HashMap getTypes() { - return types; - } - - public RelativeBlockVector[] getEntrances() { - return entrances; - } - - public RelativeBlockVector[] getBorder() { - return border; - } - - public RelativeBlockVector[] getControls() { - return controls; - } - - public HashMap getExits() { - return exits; - } - public RelativeBlockVector getExit() { - return exitBlock; - } - - public Material getControlBlock() { - return types.get('-'); - } - - public String getFilename() { - return filename; - } - - public Material getPortalBlockOpen() { - return portalBlockOpen; - } - - public void setPortalBlockOpen(Material type) { - portalBlockOpen = type; - } - - public Material getPortalBlockClosed() { - return portalBlockClosed; - } - - public void setPortalBlockClosed(Material type) { - portalBlockClosed = type; - } - - public Material getButton() { - return button; - } - - public int getUseCost() { - if (useCost < 0) return EconomyHandler.useCost; - return useCost; - } - - public Integer getCreateCost() { - if (createCost < 0) return EconomyHandler.createCost; - return createCost; - } - - public Integer getDestroyCost() { - if (destroyCost < 0) return EconomyHandler.destroyCost; - return destroyCost; - } - - public Boolean getToOwner() { - return toOwner; - } - - public boolean matches(Blox topleft, int modX, int modZ) { - return matches(topleft, modX, modZ, false); - } - - public boolean matches(Blox 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; - - 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 (type != portalBlockClosed && type != portalBlockOpen) { - Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); - return false; - } - } 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); - return false; - } - } - } - } - - return true; - } - - public static void registerGate(Gate gate) { - gates.put(gate.getFilename(), gate); - - Material blockID = gate.getControlBlock(); - - if (!controlBlocks.containsKey(blockID)) { - controlBlocks.put(blockID, new ArrayList<>()); - } - - controlBlocks.get(blockID).add(gate); - } - - public static Gate loadGate(File file) { - Scanner scanner = null; - boolean designing = false; - ArrayList> design = new ArrayList<>(); - HashMap types = new HashMap<>(); - HashMap config = new HashMap<>(); - HashSet frameTypes = new HashSet<>(); - int cols = 0; - - // Init types map - types.put(ENTRANCE, Material.AIR); - types.put(EXIT, Material.AIR); - types.put(ANYTHING, Material.AIR); - - try { - scanner = new Scanner(file); - - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - - if (designing) { - ArrayList row = new ArrayList<>(); - - if (line.length() > cols) { - cols = line.length(); - } - - for (Character symbol : line.toCharArray()) { - if ((symbol.equals('?')) || (!types.containsKey(symbol))) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Unknown symbol '" + symbol + "' in diagram"); - return null; - } - row.add(symbol); - } - - design.add(row); - } else { - if ((line.isEmpty()) || (!line.contains("="))) { - designing = true; - } else { - String[] split = line.split("="); - String key = split[0].trim(); - String value = split[1].trim(); - - if (key.length() == 1) { - Character symbol = key.charAt(0); - Material id = Material.getMaterial(value); - if(id == null) { - throw new Exception("Invalid material in line: " + line); - } - types.put(symbol, id); - frameTypes.add(id); - } else { - config.put(key, value); - } - } - } - } - } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); - return null; - } finally { - if (scanner != null) scanner.close(); - } - - Character[][] layout = new Character[design.size()][cols]; - - for (int y = 0; y < design.size(); y++) { - ArrayList row = design.get(y); - Character[] result = new Character[cols]; - - for (int x = 0; x < cols; x++) { - if (x < row.size()) { - result[x] = row.get(x); - } else { - result[x] = ' '; - } - } - - layout[y] = result; - } - - Gate gate = new Gate(file.getName(), layout, types); - - gate.portalBlockOpen = readConfig(config, gate, file, "portal-open", gate.portalBlockOpen); - gate.portalBlockClosed = readConfig(config, gate, file, "portal-closed", gate.portalBlockClosed); - gate.button = readConfig(config, gate, file, "button", gate.button); - gate.useCost = readConfig(config, gate, file, "usecost", -1); - gate.destroyCost = readConfig(config, gate, file, "destroycost", -1); - gate.createCost = readConfig(config, gate, file, "createcost", -1); - gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); - - if (gate.getControls().length != 2) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gates must have exactly 2 control points."); - return null; - } - - if (!Tag.BUTTONS.isTagged(gate.button)) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gate button must be a type of button."); - return null; - } - - // Merge frame types, add open mat to list - frameBlocks.addAll(frameTypes); - - gate.save(file.getParent() + "/"); // Updates format for version changes - return gate; - } - - private static int readConfig(HashMap config, Gate gate, File file, String key, int def) { - if (config.containsKey(key)) { - try { - return Integer.parseInt(config.get(key)); - } catch (NumberFormatException ex) { - Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), file, key)); - } - } - - return def; - } - - private static Material readConfig(HashMap config, Gate gate, File file, String key, Material def) { - if (config.containsKey(key)) { - Material mat = Material.getMaterial(config.get(key)); - if(mat != null) { - return mat; - } - Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", file, key)); - } - return def; - } - - public static void loadGates(String gateFolder) { - File dir = new File(gateFolder); - File[] files; - - if (dir.exists()) { - files = dir.listFiles(new StargateFilenameFilter()); - } else { - files = new File[0]; - } - - if (files == null || files.length == 0) { - if (dir.mkdir()) { - populateDefaults(gateFolder); - } - } else { - for (File file : files) { - Gate gate = loadGate(file); - if (gate != null) registerGate(gate); - } - } - } - - public static void populateDefaults(String gateFolder) { - Character[][] layout = new Character[][] { - {' ', 'X','X', ' '}, - {'X', '.', '.', 'X'}, - {'-', '.', '.', '-'}, - {'X', '*', '.', 'X'}, - {' ', 'X', 'X', ' '}, - }; - HashMap types = new HashMap<>(); - types.put(ENTRANCE, Material.AIR); - types.put(EXIT, Material.AIR); - types.put(ANYTHING, Material.AIR); - types.put('X', Material.OBSIDIAN); - types.put('-', Material.OBSIDIAN); - - Gate gate = new Gate("nethergate.gate", layout, types); - gate.save(gateFolder); - registerGate(gate); - } - - public static Gate[] getGatesByControlBlock(Block block) { - return getGatesByControlBlock(block.getType()); - } - - public static Gate[] getGatesByControlBlock(Material type) { - Gate[] result = new Gate[0]; - ArrayList lookup = controlBlocks.get(type); - - if (lookup != null) result = lookup.toArray(result); - - return result; - } - - public static Gate getGateByName(String name) { - return gates.get(name); - } - - public static int getGateCount() { - return gates.size(); - } - - public static boolean isGateBlock(Material type) { - return frameBlocks.contains(type); - } - - static class StargateFilenameFilter implements FilenameFilter { - public boolean accept(File dir, String name) { - return name.endsWith(".gate"); - } - } - - public static void clearGates() { - gates.clear(); - controlBlocks.clear(); - frameBlocks.clear(); - } -} diff --git a/src/net/TheDgtl/Stargate/LangLoader.java b/src/net/TheDgtl/Stargate/LangLoader.java deleted file mode 100644 index ad4a718..0000000 --- a/src/net/TheDgtl/Stargate/LangLoader.java +++ /dev/null @@ -1,226 +0,0 @@ -package net.TheDgtl.Stargate; - -import org.bukkit.ChatColor; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Set; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class LangLoader { - private final String UTF8_BOM = "\uFEFF"; - // Variables - private final String datFolder; - private String lang; - private HashMap strList; - private final HashMap defList; - - public LangLoader(String datFolder, String lang) { - this.lang = lang; - this.datFolder = datFolder; - - File tmp = new File(datFolder, lang + ".txt"); - if (!tmp.exists()) { - tmp.getParentFile().mkdirs(); - } - updateLanguage(lang); - - strList = load(lang); - // We have a default hashMap used for when new text is added. - InputStream is = Stargate.class.getResourceAsStream("resources/" + lang + ".txt"); - if (is != null) { - defList = load("en", is); - } else { - defList = null; - Stargate.log.severe("[Stargate] Error loading backup language. There may be missing text ingame"); - } - } - - public boolean reload() { - // This extracts/updates the language as needed - updateLanguage(lang); - strList = load(lang); - return true; - } - - public String getString(String name) { - String val = strList.get(name); - if (val == null && defList != null) val = defList.get(name); - if (val == null) return ""; - return val; - } - - public void setLang(String lang) { - this.lang = lang; - } - - // This function updates on-disk language files - // with missing lines from the in-JAR files - private void updateLanguage(String lang) { - // Load the current language file - ArrayList keyList = new ArrayList<>(); - ArrayList valList = new ArrayList<>(); - - HashMap curLang = load(lang); - - InputStream is = Stargate.class.getResourceAsStream("resources/" + lang + ".txt"); - if (is == null) return; - - boolean updated = false; - FileOutputStream fos = null; - try { - // Input stuff - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - - String line = br.readLine(); - boolean firstLine = true; - while (line != null) { - // Strip UTF BOM - if (firstLine) line = removeUTF8BOM(line); - firstLine = false; - // Split at first "=" - int eq = line.indexOf('='); - if (eq == -1) { - keyList.add(""); - valList.add(""); - line = br.readLine(); - continue; - } - String key = line.substring(0, eq); - String val = line.substring(eq); - - if (curLang == null || curLang.get(key) == null) { - keyList.add(key); - valList.add(val); - updated = true; - } else { - keyList.add(key); - valList.add("=" + curLang.get(key).replace('\u00A7', '&')); - curLang.remove(key); - } - line = br.readLine(); - } - br.close(); - - // Save file - fos = new FileOutputStream(datFolder + lang + ".txt"); - OutputStreamWriter out = new OutputStreamWriter(fos, StandardCharsets.UTF_8); - BufferedWriter bw = new BufferedWriter(out); - - // Output normal Language data - for (int i = 0; i < keyList.size(); i++) { - bw.write(keyList.get(i) + valList.get(i)); - bw.newLine(); - } - bw.newLine(); - // Output any custom language strings the user had - if(curLang != null) { - for (String key : curLang.keySet()) { - bw.write(key + "=" + curLang.get(key)); - bw.newLine(); - } - } - - bw.close(); - } catch (Exception ex) { - ex.printStackTrace(); - } finally { - if (fos != null) { - try {fos.close();} catch (Exception ex) {} - } - } - if (updated) - Stargate.log.info("[Stargate] Your language file (" + lang + ".txt) has been updated"); - } - - private HashMap load(String lang) { - return load(lang, null); - } - - private HashMap load(String lang, InputStream is) { - HashMap strings = new HashMap<>(); - FileInputStream fis = null; - InputStreamReader isr = null; - try { - if (is == null) { - fis = new FileInputStream(datFolder + lang + ".txt"); - isr = new InputStreamReader(fis, StandardCharsets.UTF_8); - } else { - isr = new InputStreamReader(is, StandardCharsets.UTF_8); - } - BufferedReader br = new BufferedReader(isr); - String line = br.readLine(); - boolean firstLine = true; - while (line != null) { - // Strip UTF BOM - if (firstLine) line = removeUTF8BOM(line); - firstLine = false; - // Split at first "=" - int eq = line.indexOf('='); - if (eq == -1) { - line = br.readLine(); - continue; - } - String key = line.substring(0, eq); - String val = ChatColor.translateAlternateColorCodes('&', line.substring(eq + 1)); - strings.put(key, val); - line = br.readLine(); - } - } catch (Exception ex) { - return null; - } finally { - if (fis != null) { - try { - fis.close(); - } catch (Exception ex) {} - } - } - return strings; - } - - public void debug() { - Set keys = strList.keySet(); - for (String key : keys) { - Stargate.debug("LangLoader::Debug::strList", key + " => " + strList.get(key)); - } - if (defList == null) return; - keys = defList.keySet(); - for (String key : keys) { - Stargate.debug("LangLoader::Debug::defList", key + " => " + defList.get(key)); - } - } - - private String removeUTF8BOM(String s) { - if (s.startsWith(UTF8_BOM)) { - s = s.substring(1); - } - return s; - } -} diff --git a/src/net/TheDgtl/Stargate/Portal.java b/src/net/TheDgtl/Stargate/Portal.java deleted file mode 100644 index 2a74f76..0000000 --- a/src/net/TheDgtl/Stargate/Portal.java +++ /dev/null @@ -1,1495 +0,0 @@ -package net.TheDgtl.Stargate; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.util.*; -import java.util.logging.Level; - -import net.TheDgtl.Stargate.event.StargateActivateEvent; -import net.TheDgtl.Stargate.event.StargateCloseEvent; -import net.TheDgtl.Stargate.event.StargateCreateEvent; -import net.TheDgtl.Stargate.event.StargateDeactivateEvent; -import net.TheDgtl.Stargate.event.StargateOpenEvent; -import net.TheDgtl.Stargate.event.StargatePortalEvent; - -import org.bukkit.Axis; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.block.data.Bisected; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Directional; -import org.bukkit.block.data.Powerable; -import org.bukkit.block.data.type.WallSign; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.entity.minecart.StorageMinecart; -import org.bukkit.entity.Vehicle; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.util.Vector; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class Portal { - // Static variables used to store portal lists - private static final HashMap lookupBlocks = new HashMap<>(); - private static final HashMap lookupEntrances = new HashMap<>(); - private static final HashMap lookupControls = new HashMap<>(); - private static final ArrayList allPortals = new ArrayList<>(); - private static final HashMap> allPortalsNet = new HashMap<>(); - private static final HashMap> lookupNamesNet = new HashMap<>(); - - // A list of Bungee gates - private static final HashMap bungeePortals = new HashMap<>(); - - // Gate location block info - private final Blox topLeft; - private final int modX; - private final int modZ; - private final float rotX; - private final Axis rot; - - // Block references - private final Blox id; - private Blox button; - private Blox[] frame; - private Blox[] entrances; - - // Gate information - private String name; - private String destination; - private String lastDest = ""; - private String network; - private final Gate gate; - private String ownerName = ""; - private UUID ownerUUID = null; - private final World world; - private boolean verified; - private boolean fixed; - - // Options - private boolean hidden = false; - private boolean alwaysOn = false; - private boolean priv = false; - private boolean free = false; - private boolean backwards = false; - private boolean show = false; - private boolean noNetwork = false; - private boolean random = false; - private boolean bungee = false; - - // In-use information - private Player player; - private Player activePlayer; - private ArrayList destinations = new ArrayList<>(); - private boolean isOpen = false; - private long openTime; - - private Portal(Blox topLeft, int modX, int modZ, - float rotX, Blox id, Blox button, - String dest, String name, - boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, - boolean hidden, boolean alwaysOn, boolean priv, boolean free, boolean backwards, boolean show, boolean noNetwork, boolean random, boolean bungee) { - this.topLeft = topLeft; - this.modX = modX; - this.modZ = modZ; - this.rotX = rotX; - this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; - this.id = id; - this.destination = dest; - this.button = button; - this.verified = verified; - this.network = network; - this.name = name; - this.gate = gate; - this.ownerUUID = ownerUUID; - this.ownerName = ownerName; - this.hidden = hidden; - this.alwaysOn = alwaysOn; - this.priv = priv; - this.free = free; - this.backwards = backwards; - this.show = show; - this.noNetwork = noNetwork; - this.random = random; - this.bungee = bungee; - this.world = topLeft.getWorld(); - this.fixed = dest.length() > 0 || this.random || this.bungee; - - if (this.isAlwaysOn() && !this.isFixed()) { - this.alwaysOn = false; - Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); - } - - if (this.random && !this.isAlwaysOn()) { - this.alwaysOn = true; - Stargate.debug("Portal", "Gate marked as random, set to always-on"); - } - - if (verified) { - this.drawSign(); - } - } - - /** - * Option Check Functions - */ - public boolean isOpen() { - return isOpen || isAlwaysOn(); - } - - public boolean isAlwaysOn() { - return alwaysOn; - } - - public boolean isHidden() { - return hidden; - } - - public boolean isPrivate() { - return priv; - } - - public boolean isFree() { - return free; - } - - public boolean isBackwards() { - return backwards; - } - - public boolean isShown() { - return show; - } - - public boolean isNoNetwork() { - return noNetwork; - } - - public boolean isRandom() { - return random; - } - - public boolean isBungee() { - return bungee; - } - - public void setAlwaysOn(boolean alwaysOn) { - this.alwaysOn = alwaysOn; - } - - public void setHidden(boolean hidden) { - this.hidden = hidden; - } - - public void setPrivate(boolean priv) { - this.priv = priv; - } - - public void setFree(boolean free) { - this.free = free; - } - - public void setBackwards(boolean backwards) { - this.backwards = backwards; - } - - public void setShown(boolean show) { - this.show = show; - } - - public void setNoNetwork(boolean noNetwork) { - this.noNetwork = noNetwork; - } - - public void setRandom(boolean random) { - this.random = random; - } - - /** - * Getters and Setters - */ - - public float getRotation() { - return rotX; - } - - public Axis getAxis() { - return rot; - } - - public Player getActivePlayer() { - return activePlayer; - } - - public String getNetwork() { - return network; - } - - public void setNetwork(String network) { - this.network = network; - } - - public long getOpenTime() { - return openTime; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = filterName(name); - drawSign(); - } - - public Portal getDestination(Player player) { - if (isRandom()) { - destinations = getDestinations(player, getNetwork()); - if (destinations.size() == 0) { - return null; - } - String dest = destinations.get((new Random()).nextInt(destinations.size())); - destinations.clear(); - return Portal.getByName(dest, getNetwork()); - } - return Portal.getByName(destination, getNetwork()); - } - - public Portal getDestination() { - return getDestination(null); - } - - public void setDestination(Portal destination) { - setDestination(destination.getName()); - } - - public void setDestination(String destination) { - this.destination = destination; - } - - public String getDestinationName() { - return destination; - } - - public Gate getGate() { - return gate; - } - - public String getOwnerName() { - return ownerName; - } - - public UUID getOwnerUUID() { - return ownerUUID; - } - - public void setOwner(UUID owner) { - this.ownerUUID = owner; - } - - public boolean isOwner(Player player) { - if(this.ownerUUID != null) { - return player.getUniqueId().compareTo(this.ownerUUID) == 0; - } else { - return player.getName().equalsIgnoreCase(this.ownerName); - } - } - - public Blox[] getEntrances() { - if (entrances == null) { - RelativeBlockVector[] space = gate.getEntrances(); - entrances = new Blox[space.length]; - int i = 0; - - for (RelativeBlockVector vector : space) { - entrances[i++] = getBlockAt(vector); - } - } - return entrances; - } - - public Blox[] getFrame() { - if (frame == null) { - RelativeBlockVector[] border = gate.getBorder(); - frame = new Blox[border.length]; - int i = 0; - - for (RelativeBlockVector vector : border) { - frame[i++] = getBlockAt(vector); - } - } - - return frame; - } - - public Blox getSign() { - return id; - } - - public World getWorld() { - return world; - } - - public Blox getButton() { - return button; - } - - public void setButton(Blox button) { - this.button = button; - } - - public static ArrayList getNetwork(String network) { - return allPortalsNet.get(network.toLowerCase()); - } - - public boolean open(boolean force) { - return open(null, force); - } - - public boolean open(Player openFor, boolean force) { - // Call the StargateOpenEvent - StargateOpenEvent event = new StargateOpenEvent(openFor, this, force); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) return false; - force = event.getForce(); - - if (isOpen() && !force) return false; - - Material openType = gate.getPortalBlockOpen(); - Axis ax = openType == Material.NETHER_PORTAL ? rot : null; - for (Blox inside : getEntrances()) { - Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, ax)); - } - - isOpen = true; - openTime = System.currentTimeMillis() / 1000; - Stargate.openList.add(this); - Stargate.activeList.remove(this); - - // Open remote gate - if (!isAlwaysOn()) { - player = openFor; - - Portal end = getDestination(); - // Only open dest if it's not-fixed or points at this gate - if (!random && end != null && (!end.isFixed() || end.getDestinationName().equalsIgnoreCase(getName())) && !end.isOpen()) { - end.open(openFor, false); - end.setDestination(this); - if (end.isVerified()) end.drawSign(); - } - } - - return true; - } - - public void close(boolean force) { - if (!isOpen) return; - // Call the StargateCloseEvent - StargateCloseEvent event = new StargateCloseEvent(this, force); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - force = event.getForce(); - - if (isAlwaysOn() && !force) return; // Only close always-open if forced - - // Close this gate, then the dest gate. - Material closedType = gate.getPortalBlockClosed(); - for (Blox inside : getEntrances()) { - Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType)); - } - - player = null; - isOpen = false; - Stargate.openList.remove(this); - Stargate.activeList.remove(this); - - if (!isAlwaysOn()) { - Portal end = getDestination(); - - if (end != null && end.isOpen()) { - end.deactivate(); // Clear it's destination first. - end.close(false); - } - } - - deactivate(); - } - - public boolean isOpenFor(Player player) { - if (!isOpen) { - return false; - } - if ((isAlwaysOn()) || (this.player == null)) { - return true; - } - return (player != null) && (player.getName().equalsIgnoreCase(this.player.getName())); - } - - public boolean isFixed() { - return fixed; - } - - public boolean isPowered() { - RelativeBlockVector[] controls = gate.getControls(); - - for (RelativeBlockVector vector : controls) { - BlockData data = getBlockAt(vector).getBlock().getBlockData(); - - if (data instanceof Powerable && ((Powerable) data).isPowered()) { - return true; - } - } - - return false; - } - - public void teleport(Player player, Portal origin, PlayerMoveEvent event) { - Location traveller = player.getLocation(); - Location exit = getExit(traveller); - - // Handle backwards gates - int adjust = 180; - 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); - // Teleport is cancelled - if (pEvent.isCancelled()) { - origin.teleport(player, origin, event); - return; - } - // Update exit if needed - exit = pEvent.getExit(); - } - - // If no event is passed in, assume it's a teleport, and act as such - if (event == null) { - exit.setYaw(this.getRotation()); - player.teleport(exit); - } else { - // The new method to teleport in a move event is set the "to" field. - event.setTo(exit); - } - } - - 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); - - double velocity = vehicle.getVelocity().length(); - - // Stop and teleport - vehicle.setVelocity(new Vector()); - - // Get new velocity - final Vector newVelocity = new Vector(modX, 0.0F, modZ); - newVelocity.multiply(velocity); - - List passengers = vehicle.getPassengers(); - if (!passengers.isEmpty()) { - final Vehicle v = exit.getWorld().spawn(exit, vehicle.getClass()); - final Entity passenger = passengers.get(0); - vehicle.eject(); - vehicle.remove(); - passenger.eject(); - passenger.teleport(exit); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> { - v.addPassenger(passenger); - v.setVelocity(newVelocity); - }, 1); - } else { - Vehicle mc = exit.getWorld().spawn(exit, vehicle.getClass()); - if (mc instanceof StorageMinecart) { - StorageMinecart smc = (StorageMinecart)mc; - smc.getInventory().setContents(((StorageMinecart)vehicle).getInventory().getContents()); - } - mc.setVelocity(newVelocity); - vehicle.remove(); - } - } - - public Location getExit(Location traveller) { - Location loc = null; - // Check if the gate has an exit block - if (gate.getExit() != null) { - Blox exit = getBlockAt(gate.getExit()); - int back = (isBackwards()) ? -1 : 1; - loc = exit.modRelativeLoc(0D, 0D, 1D, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); - } else { - Stargate.log.log(Level.WARNING, "[Stargate] 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); - } - - loc.setPitch(traveller.getPitch()); - return loc; - } - return traveller; - } - - public boolean isChunkLoaded() { - return getWorld().isChunkLoaded(topLeft.getBlock().getChunk()); - } - - public boolean isVerified() { - verified = true; - if(!Stargate.verifyPortals) { - return true; - } - for (RelativeBlockVector control : gate.getControls()) { - verified = verified && getBlockAt(control).getBlock().getType().equals(gate.getControlBlock()); - } - return verified; - } - - public boolean wasVerified() { - if(!Stargate.verifyPortals) { - return true; - } - return verified; - } - - public boolean checkIntegrity() { - if(!Stargate.verifyPortals) { - return true; - } - return gate.matches(topLeft, modX, modZ); - } - - public ArrayList getDestinations(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(getName())) continue; - // Check if dest is a fixed gate not pointing to this gate - if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(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; - // Visible to this player. - if (Stargate.canSee(player, portal)) { - destinations.add(portal.getName()); - } - } - return destinations; - } - - public boolean activate(Player player) { - destinations.clear(); - destination = ""; - Stargate.activeList.add(this); - activePlayer = player; - String network = getNetwork(); - destinations = getDestinations(player, network); - if (Stargate.sortLists) { - Collections.sort(destinations); - } - if (Stargate.destMemory && !lastDest.isEmpty() && destinations.contains(lastDest)) { - destination = lastDest; - } - - StargateActivateEvent event = new StargateActivateEvent(this, player, destinations, destination); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) { - Stargate.activeList.remove(this); - return false; - } - destination = event.getDestination(); - destinations = event.getDestinations(); - drawSign(); - return true; - } - - public void deactivate() { - StargateDeactivateEvent event = new StargateDeactivateEvent(this); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - - Stargate.activeList.remove(this); - if (isFixed()) { - return; - } - destinations.clear(); - destination = ""; - activePlayer = null; - drawSign(); - } - - public boolean isActive() { - return isFixed() || (destinations.size() > 0); - } - - public void cycleDestination(Player player) { - cycleDestination(player, 1); - } - - public void cycleDestination(Player player, int dir) { - boolean activate = false; - if (!isActive() || getActivePlayer() != player) { - // If the event is cancelled, return - if (!activate(player)) { - return; - } - Stargate.debug("cycleDestination", "Network Size: " + allPortalsNet.get(network.toLowerCase()).size()); - Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); - activate = true; - } - - if (destinations.size() == 0) { - Stargate.sendMessage(player, Stargate.getString("destEmpty")); - return; - } - - if (!Stargate.destMemory || !activate || lastDest.isEmpty()) { - int index = destinations.indexOf(destination); - index += dir; - if (index >= destinations.size()) - index = 0; - else if (index < 0) - index = destinations.size() - 1; - destination = destinations.get(index); - lastDest = destination; - } - openTime = System.currentTimeMillis() / 1000; - drawSign(); - } - - public final void drawSign() { - BlockState state = id.getBlock().getState(); - if (!(state instanceof Sign)) { - Stargate.log.warning("[Stargate] Sign block is not a Sign object"); - Stargate.debug("Portal::drawSign", "Block: " + id.getBlock().getType() + " @ " + id.getBlock().getLocation()); - return; - } - Sign sign = (Sign) state; - Stargate.setLine(sign, 0, "-" + name + "-"); - int max = destinations.size() - 1; - int done = 0; - - if (!isActive()) { - Stargate.setLine(sign, ++done, Stargate.getString("signRightClick")); - Stargate.setLine(sign, ++done, Stargate.getString("signToUse")); - if (!noNetwork) { - Stargate.setLine(sign, ++done, "(" + network + ")"); - } - } else { - // Awesome new logic for Bungee gates - if (isBungee()) { - Stargate.setLine(sign, ++done, Stargate.getString("bungeeSign")); - Stargate.setLine(sign, ++done, ">" + destination + "<"); - Stargate.setLine(sign, ++done, "[" + network + "]"); - } else if (isFixed()) { - if (isRandom()) { - Stargate.setLine(sign, ++done, "> " + Stargate.getString("signRandom") + " <"); - } else { - Stargate.setLine(sign, ++done, ">" + destination + "<"); - } - if (noNetwork) { - Stargate.setLine(sign, ++done, ""); - } else { - Stargate.setLine(sign, ++done, "(" + network + ")"); - } - Portal dest = Portal.getByName(destination, network); - if (dest == null && !isRandom()) { - Stargate.setLine(sign, ++done, Stargate.getString("signDisconnected")); - } else { - Stargate.setLine(sign, ++done, ""); - } - } else { - int index = destinations.indexOf(destination); - if ((index == max) && (max > 1) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index - 2), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 2)); - } else { - Stargate.setLine(sign, done, destinations.get(index - 2)); - } - } - if ((index > 0) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index - 1), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 1)); - } else { - Stargate.setLine(sign, done, destinations.get(index - 1)); - } - } - if (++done <= 3) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destination, network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + ">" + destination + "<"); - } else { - Stargate.setLine(sign, done, " >" + destination + "< "); - } - } - if ((max >= index + 1) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index + 1), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 1)); - } else { - Stargate.setLine(sign, done, destinations.get(index + 1)); - } - } - if ((max >= index + 2) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index + 2), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 2)); - } else { - Stargate.setLine(sign, done, destinations.get(index + 2)); - } - } - } - } - - for (done++; done <= 3; done++) { - sign.setLine(done, ""); - } - - sign.update(); - } - - public void unregister(boolean removeAll) { - Stargate.debug("Unregister", "Unregistering gate " + getName()); - close(true); - - for (Blox block : getFrame()) { - lookupBlocks.remove(block); - } - // Include the sign and button - lookupBlocks.remove(id); - if (button != null) { - lookupBlocks.remove(button); - } - - lookupControls.remove(id); - if (button != null) - lookupControls.remove(button); - - for (Blox entrance : getEntrances()) { - lookupEntrances.remove(entrance); - } - - if (removeAll) - allPortals.remove(this); - - if (bungee) { - bungeePortals.remove(getName().toLowerCase()); - } else { - lookupNamesNet.get(getNetwork().toLowerCase()).remove(getName().toLowerCase()); - allPortalsNet.get(getNetwork().toLowerCase()).remove(getName().toLowerCase()); - - for (String originName : allPortalsNet.get(getNetwork().toLowerCase())) { - Portal origin = Portal.getByName(originName, getNetwork()); - if (origin == null) continue; - if (!origin.getDestinationName().equalsIgnoreCase(getName())) continue; - if (!origin.isVerified()) continue; - if (origin.isFixed()) origin.drawSign(); - if (origin.isAlwaysOn()) origin.close(true); - } - } - - if (id.getBlock().getBlockData() instanceof WallSign) { - Sign sign = (Sign)id.getBlock().getState(); - sign.setLine(0, getName()); - sign.setLine(1, ""); - sign.setLine(2, ""); - sign.setLine(3, ""); - sign.update(); - } - - saveAllGates(getWorld()); - } - - private Blox getBlockAt(RelativeBlockVector vector) { - return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); - } - - private void register() { - fixed = destination.length() > 0 || random || bungee; - - // Bungee gates are stored in their own list - if (isBungee()) { - bungeePortals.put(getName().toLowerCase(), this); - } else { - // Check if network exists in our network list - if (!lookupNamesNet.containsKey(getNetwork().toLowerCase())) { - Stargate.debug("register", "Network " + getNetwork() + " not in lookupNamesNet, adding"); - lookupNamesNet.put(getNetwork().toLowerCase(), new HashMap<>()); - } - lookupNamesNet.get(getNetwork().toLowerCase()).put(getName().toLowerCase(), this); - - // Check if this network exists - if (!allPortalsNet.containsKey(getNetwork().toLowerCase())) { - Stargate.debug("register", "Network " + getNetwork() + " not in allPortalsNet, adding"); - allPortalsNet.put(getNetwork().toLowerCase(), new ArrayList<>()); - } - allPortalsNet.get(getNetwork().toLowerCase()).add(getName().toLowerCase()); - } - - for (Blox block : getFrame()) { - lookupBlocks.put(block, this); - } - // Include the sign and button - lookupBlocks.put(id, this); - if (button != null) { - lookupBlocks.put(button, this); - } - - lookupControls.put(id, this); - if (button != null) - lookupControls.put(button, this); - - for (Blox entrance : getEntrances()) { - lookupEntrances.put(entrance, this); - } - - allPortals.add(this); - } - - public static Portal createPortal(SignChangeEvent event, Player player) { - Blox id = new Blox(event.getBlock()); - Block idParent = id.getParent(); - if (idParent == null) { - return null; - } - - if (Gate.getGatesByControlBlock(idParent).length == 0) return null; - - if (Portal.getByBlock(idParent) != null) { - Stargate.debug("createPortal", "idParent belongs to existing gate"); - return null; - } - - Blox parent = new Blox(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); - Blox topleft = null; - String name = filterName(event.getLine(0)); - String destName = 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 free = (options.indexOf('f') != - 1); - boolean backwards = (options.indexOf('b') != -1); - boolean show = (options.indexOf('s') != -1); - boolean noNetwork = (options.indexOf('n') != -1); - boolean random = (options.indexOf('r') != -1); - boolean bungee = (options.indexOf('u') != -1); - - // Check permissions for options. - if (hidden && !Stargate.canOption(player, "hidden")) hidden = false; - if (alwaysOn && !Stargate.canOption(player, "alwayson")) alwaysOn = false; - if (priv && !Stargate.canOption(player, "private")) priv = false; - if (free && !Stargate.canOption(player, "free")) free = false; - if (backwards && !Stargate.canOption(player, "backwards")) backwards = false; - if (show && !Stargate.canOption(player, "show")) show = false; - if (noNetwork && !Stargate.canOption(player, "nonetwork")) noNetwork = false; - if (random && !Stargate.canOption(player, "random")) random = false; - - // Can not create a non-fixed always-on gate. - if (alwaysOn && destName.length() == 0) { - alwaysOn = false; - } - - // Show isn't useful if A is false - if (show && !alwaysOn) { - show = false; - } - - // Random gates are always on and can't be shown - if (random) { - alwaysOn = true; - show = false; - } - - // Bungee gates are always on and don't support Random - if (bungee) { - alwaysOn = true; - random = false; - } - - // Moved the layout check so as to avoid invalid messages when not making a gate - int modX = 0; - int modZ = 0; - float rotX = 0f; - BlockFace buttonfacing = BlockFace.DOWN; - - if (idParent.getX() > id.getBlock().getX()) { - modZ -= 1; - rotX = 90f; - buttonfacing = BlockFace.WEST; - } else if (idParent.getX() < id.getBlock().getX()) { - modZ += 1; - rotX = 270f; - buttonfacing = BlockFace.EAST; - } else if (idParent.getZ() > id.getBlock().getZ()) { - modX += 1; - rotX = 180f; - buttonfacing = BlockFace.NORTH; - } else if (idParent.getZ() < id.getBlock().getZ()) { - modX -= 1; - rotX = 0f; - buttonfacing = BlockFace.SOUTH; - } - - Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); - Gate gate = null; - RelativeBlockVector buttonVector = null; - - for (Gate possibility : possibleGates) { - if ((gate == null) && (buttonVector == null)) { - RelativeBlockVector[] vectors = possibility.getControls(); - RelativeBlockVector otherControl = null; - - for (RelativeBlockVector vector : vectors) { - Blox tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); - - if (gate == null) { - if (possibility.matches(tl, modX, modZ, true)) { - gate = possibility; - topleft = tl; - - if (otherControl != null) { - buttonVector = otherControl; - } - } - } else if (otherControl != null) { - buttonVector = vector; - } - - otherControl = vector; - } - } - } - - if ((gate == null) || (buttonVector == null)) { - Stargate.debug("createPortal", "Could not find matching gate layout"); - return null; - } - - // If the player is trying to create a Bungee gate without permissions, drop out here - // Do this after the gate layout check, in the least - if (bungee) { - if (!Stargate.enableBungee) { - Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); - return null; - } else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { - Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); - return null; - } else if (destName.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); - - if (!bungee && (network.length() < 1 || network.length() > 11)) { - network = Stargate.getDefaultNetwork(); - } - - boolean deny = false; - String denyMsg = ""; - - // Check if the player can create gates on this network - if (!bungee && !Stargate.canCreate(player, network)) { - Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); - if (Stargate.canCreatePersonal(player)) { - network = player.getName(); - if (network.length() > 11) network = network.substring(0, 11); - Stargate.debug("createPortal", "Creating personal portal"); - Stargate.sendMessage(player, Stargate.getString("createPersonal")); - } else { - Stargate.debug("createPortal", "Player does not have access to network"); - deny = true; - denyMsg = Stargate.getString("createNetDeny"); - //return null; - } - } - - // Check if the player can create this gate layout - String gateName = gate.getFilename(); - gateName = gateName.substring(0, gateName.indexOf('.')); - if (!deny && !Stargate.canCreateGate(player, gateName)) { - Stargate.debug("createPortal", "Player does not have access to gate layout"); - deny = true; - denyMsg = Stargate.getString("createGateDeny"); - } - - // Check if the user can create gates to this world. - if (!bungee && !deny && destName.length() > 0) { - Portal p = Portal.getByName(destName, network); - if (p != null) { - String world = p.getWorld().getName(); - if (!Stargate.canAccessWorld(player, world)) { - Stargate.debug("canCreate", "Player does not have access to destination world"); - deny = true; - denyMsg = Stargate.getString("createWorldDeny"); - } - } - } - - // Bleh, gotta check to make sure none of this gate belongs to another gate. Boo slow. - for (RelativeBlockVector v : gate.getBorder()) { - Blox b = topleft.modRelative(v.getRight(), v.getDepth(), v.getDistance(), modX, 1, modZ); - if (Portal.getByBlock(b.getBlock()) != null) { - Stargate.debug("createPortal", "Gate conflicts with existing gate"); - Stargate.sendMessage(player, Stargate.getString("createConflict")); - return null; - } - } - - Blox button = null; - Portal portal = null; - 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); - - int cost = Stargate.getCreateCost(player, gate); - - // Call StargateCreateEvent - StargateCreateEvent cEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); - Stargate.server.getPluginManager().callEvent(cEvent); - if (cEvent.isCancelled()) { - return null; - } - if (cEvent.getDeny()) { - Stargate.sendMessage(player, cEvent.getDenyReason()); - return null; - } - - cost = cEvent.getCost(); - - // Name & Network can be changed in the event, so do these checks here. - if (portal.getName().length() < 1 || portal.getName().length() > 11) { - Stargate.debug("createPortal", "Name length error"); - Stargate.sendMessage(player, Stargate.getString("createNameLength")); - return null; - } - - // Don't do network checks for bungee gates - if (portal.isBungee()) { - if (bungeePortals.get(portal.getName().toLowerCase()) != null) { - Stargate.debug("createPortal::Bungee", "Gate Exists"); - Stargate.sendMessage(player, Stargate.getString("createExists")); - return null; - } - } else { - if (getByName(portal.getName(), portal.getNetwork()) != null) { - Stargate.debug("createPortal", "Name Error"); - Stargate.sendMessage(player, Stargate.getString("createExists")); - return null; - } - - // Check if there are too many gates in this network - ArrayList netList = allPortalsNet.get(portal.getNetwork().toLowerCase()); - if (Stargate.maxGates > 0 && netList != null && netList.size() >= Stargate.maxGates) { - Stargate.sendMessage(player, Stargate.getString("createFull")); - return null; - } - } - - if (cost > 0) { - if (!Stargate.chargePlayer(player, cost)) { - String inFundMsg = Stargate.getString("ecoInFunds"); - inFundMsg = Stargate.replaceVars(inFundMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), name}); - Stargate.sendMessage(player, inFundMsg); - Stargate.debug("createPortal", "Insufficient Funds"); - return null; - } - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), name}); - Stargate.sendMessage(player, deductMsg, false); - } - - // No button on an always-open gate. - if (!alwaysOn) { - button = topleft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); - Directional buttondata = (Directional) Bukkit.createBlockData(gate.getButton()); - buttondata.setFacing(buttonfacing); - button.getBlock().setBlockData(buttondata); - portal.setButton(button); - } - - portal.register(); - portal.drawSign(); - // Open always on gate - if (portal.isRandom() || portal.isBungee()) { - portal.open(true); - } else if (portal.isAlwaysOn()) { - Portal dest = Portal.getByName(destName, portal.getNetwork()); - if (dest != null) { - portal.open(true); - dest.drawSign(); - } - // Set the inside of the gate to its closed material - } else { - for (Blox inside : portal.getEntrances()) { - inside.setType(portal.getGate().getPortalBlockClosed()); - } - } - - // Don't do network stuff for bungee gates - if (!portal.isBungee()) { - // Open any always on gate pointing at this gate - for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { - Portal origin = Portal.getByName(originName, portal.getNetwork()); - if (origin == null) continue; - if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; - if (!origin.isVerified()) continue; - if (origin.isFixed()) origin.drawSign(); - if (origin.isAlwaysOn()) origin.open(true); - } - } - - saveAllGates(portal.getWorld()); - - return portal; - } - - public static Portal getByName(String name, String network) { - if (!lookupNamesNet.containsKey(network.toLowerCase())) return null; - return lookupNamesNet.get(network.toLowerCase()).get(name.toLowerCase()); - - } - - public static Portal getByEntrance(Location location) { - return lookupEntrances.get(new Blox(location)); - } - - public static Portal getByEntrance(Block block) { - return lookupEntrances.get(new Blox(block)); - } - - public static Portal getByAdjacentEntrance(Location loc) { - int centerX = loc.getBlockX(); - int centerY = loc.getBlockY(); - int centerZ = loc.getBlockZ(); - World world = loc.getWorld(); - Portal portal = lookupEntrances.get(new Blox(world, centerX, centerY, centerZ)); - if(portal != null) { - return portal; - } - portal = lookupEntrances.get(new Blox(world, centerX + 1, centerY, centerZ)); - if(portal != null) { - return portal; - } - portal = lookupEntrances.get(new Blox(world, centerX - 1, centerY, centerZ)); - if(portal != null) { - return portal; - } - portal = lookupEntrances.get(new Blox(world, centerX, centerY, centerZ + 1)); - if(portal != null) { - return portal; - } - portal = lookupEntrances.get(new Blox(world, centerX, centerY, centerZ - 1)); - if(portal != null) { - return portal; - } - return null; - } - - public static Portal getByControl(Block block) { - return lookupControls.get(new Blox(block)); - } - - public static Portal getByBlock(Block block) { - return lookupBlocks.get(new Blox(block)); - } - - public static Portal getBungeeGate(String name) { - return bungeePortals.get(name.toLowerCase()); - } - - public static void saveAllGates(World world) { - Stargate.managedWorlds.add(world.getName()); - String loc = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; - - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(loc, false)); - - for (Portal portal : allPortals) { - String wName = portal.world.getName(); - if (!wName.equalsIgnoreCase(world.getName())) continue; - StringBuilder builder = new StringBuilder(); - Blox sign = portal.id; - Blox button = portal.button; - - builder.append(portal.name); - builder.append(':'); - builder.append(sign.toString()); - builder.append(':'); - builder.append((button != null) ? button.toString() : ""); - builder.append(':'); - builder.append(portal.modX); - builder.append(':'); - builder.append(portal.modZ); - builder.append(':'); - builder.append(portal.rotX); - builder.append(':'); - builder.append(portal.topLeft.toString()); - builder.append(':'); - builder.append(portal.gate.getFilename()); - builder.append(':'); - builder.append(portal.isFixed() ? portal.getDestinationName() : ""); - builder.append(':'); - builder.append(portal.getNetwork()); - builder.append(':'); - UUID owner = portal.getOwnerUUID(); - if(owner != null) { - builder.append(portal.getOwnerUUID().toString()); - } else { - builder.append(portal.getOwnerName()); - } - builder.append(':'); - builder.append(portal.isHidden()); - builder.append(':'); - builder.append(portal.isAlwaysOn()); - builder.append(':'); - builder.append(portal.isPrivate()); - builder.append(':'); - builder.append(portal.world.getName()); - builder.append(':'); - builder.append(portal.isFree()); - builder.append(':'); - builder.append(portal.isBackwards()); - builder.append(':'); - builder.append(portal.isShown()); - builder.append(':'); - builder.append(portal.isNoNetwork()); - builder.append(':'); - builder.append(portal.isRandom()); - builder.append(':'); - builder.append(portal.isBungee()); - - bw.append(builder.toString()); - bw.newLine(); - } - - bw.close(); - } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); - } - } - - public static void clearGates() { - lookupBlocks.clear(); - lookupNamesNet.clear(); - lookupEntrances.clear(); - lookupControls.clear(); - allPortals.clear(); - allPortalsNet.clear(); - } - - public static boolean loadAllGates(World world) { - String location = Stargate.getSaveLocation(); - - File db = new File(location, world.getName() + ".db"); - - if (db.exists()) { - int l = 0; - int portalCount = 0; - try { - Scanner scanner = new Scanner(db); - while (scanner.hasNextLine()) { - l++; - String line = scanner.nextLine().trim(); - if (line.startsWith("#") || line.isEmpty()) { - continue; - } - String[] split = line.split(":"); - if (split.length < 8) { - Stargate.log.info("[Stargate] Invalid line - " + l); - continue; - } - String name = split[0]; - Blox sign = new Blox(world, split[1]); - Blox button = (split[2].length() > 0) ? new Blox(world, split[2]) : null; - int modX = Integer.parseInt(split[3]); - int modZ = Integer.parseInt(split[4]); - float rotX = Float.parseFloat(split[5]); - Blox topLeft = new Blox(world, split[6]); - Gate gate = Gate.getGateByName(split[7]); - if (gate == null) { - Stargate.log.info("[Stargate] Gate layout on line " + l + " does not exist [" + split[7] + "]"); - continue; - } - - String dest = (split.length > 8) ? split[8] : ""; - String network = (split.length > 9) ? split[9] : Stargate.getDefaultNetwork(); - if (network.isEmpty()) network = Stargate.getDefaultNetwork(); - String ownerString = (split.length > 10) ? split[10] : ""; - boolean hidden = (split.length > 11) && split[11].equalsIgnoreCase("true"); - boolean alwaysOn = (split.length > 12) && split[12].equalsIgnoreCase("true"); - boolean priv = (split.length > 13) && split[13].equalsIgnoreCase("true"); - boolean free = (split.length > 15) && split[15].equalsIgnoreCase("true"); - boolean backwards = (split.length > 16) && split[16].equalsIgnoreCase("true"); - boolean show = (split.length > 17) && split[17].equalsIgnoreCase("true"); - boolean noNetwork = (split.length > 18) && split[18].equalsIgnoreCase("true"); - boolean random = (split.length > 19) && split[19].equalsIgnoreCase("true"); - boolean bungee = (split.length > 20) && split[20].equalsIgnoreCase("true"); - - // Attempt to get owner as UUID - UUID ownerUUID = null; - String ownerName; - if(ownerString.length() > 16) { - try { - ownerUUID = UUID.fromString(ownerString); - OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); - ownerName = offlineOwner.getName(); - } catch (IllegalArgumentException ex) { - // neither name nor UUID, so keep it as-is - ownerName = ownerString; - Stargate.debug("loadAllGates", "Invalid Stargate owner string: " + ownerString); - } - } else { - ownerName = ownerString; - } - - Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, dest, name, false, network, gate, ownerUUID, ownerName, hidden, alwaysOn, priv, free, backwards, show, noNetwork, random, bungee); - portal.register(); - portal.close(true); - } - scanner.close(); - - // Open any always-on gates. Do this here as it should be more efficient than in the loop. - int OpenCount = 0; - for (Iterator iter = allPortals.iterator(); iter.hasNext(); ) { - Portal portal = iter.next(); - if (portal == null) continue; - - // Verify portal integrity/register portal - if (!portal.wasVerified()) { - if (!portal.isVerified() || !portal.checkIntegrity()) { - // DEBUG - for (RelativeBlockVector control : portal.getGate().getControls()) { - if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { - Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); - } - } - portal.unregister(false); - iter.remove(); - Stargate.log.info("[Stargate] Destroying stargate at " + portal.toString()); - continue; - } - } - portalCount++; - - if (portal.isFixed() && (Stargate.enableBungee && portal.isBungee() - || portal.getDestination() != null && portal.isAlwaysOn())) { - portal.open(true); - OpenCount++; - } - } - Stargate.log.info("[Stargate] {" + world.getName() + "} Loaded " + portalCount + " stargates with " + OpenCount + " set as always-on"); - return true; - } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + db.getName() + ": " + l); - e.printStackTrace(); - } - } else { - Stargate.log.info("[Stargate] {" + world.getName() + "} No stargates for world "); - } - return false; - } - - public static void closeAllGates() { - Stargate.log.info("Closing all stargates."); - for (Portal p : allPortals) { - if (p == null) continue; - p.close(true); - } - } - - public static String filterName(String input) { - if (input == null) { - return ""; - } - return input.replaceAll("[\\|:#]", "").trim(); - } - - @Override - public String toString() { - return String.format("Portal [id=%s, network=%s name=%s, type=%s]", id, network, name, gate.getFilename()); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((network == null) ? 0 : network.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Portal other = (Portal) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equalsIgnoreCase(other.name)) - return false; - if (network == null) { - if (other.network != null) - return false; - } else if (!network.equalsIgnoreCase(other.network)) - return false; - return true; - } -} diff --git a/src/net/TheDgtl/Stargate/Stargate.java b/src/net/TheDgtl/Stargate/Stargate.java deleted file mode 100644 index 2b995c5..0000000 --- a/src/net/TheDgtl/Stargate/Stargate.java +++ /dev/null @@ -1,1294 +0,0 @@ -package net.TheDgtl.Stargate; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.logging.Level; -import java.util.logging.Logger; - -import net.TheDgtl.Stargate.event.StargateAccessEvent; -import net.TheDgtl.Stargate.event.StargateDestroyEvent; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.EndGateway; -import org.bukkit.block.Sign; -import org.bukkit.block.data.Orientable; -import org.bukkit.block.data.type.WallSign; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Vehicle; -import org.bukkit.event.Event.Result; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockFromToEvent; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPistonRetractEvent; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerTeleportEvent; -import org.bukkit.event.server.PluginDisableEvent; -import org.bukkit.event.server.PluginEnableEvent; -import org.bukkit.event.vehicle.VehicleMoveEvent; -import org.bukkit.event.world.WorldLoadEvent; -import org.bukkit.event.world.WorldUnloadEvent; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.java.JavaPlugin; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -@SuppressWarnings("unused") -public class Stargate extends JavaPlugin { - public static Logger log; - private FileConfiguration newConfig; - private PluginManager pm; - public static Server server; - public static Stargate stargate; - private static LangLoader lang; - - private static String portalFolder; - private static String gateFolder; - private static String langFolder; - private static String defNetwork = "central"; - private static boolean destroyExplosion = false; - public static int maxGates = 0; - private static String langName = "en"; - private static final int activeTime = 10; - private static final int openTime = 10; - public static boolean destMemory = false; - public static boolean handleVehicles = true; - public static boolean sortLists = false; - public static boolean protectEntrance = false; - public static boolean enableBungee = true; - public static boolean verifyPortals = true; - public static ChatColor signColor; - - // Temp workaround for snowmen, don't check gate entrance - public static boolean ignoreEntrance = false; - - // Used for debug - public static boolean debug = false; - public static boolean permDebug = false; - - public static ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); - public static ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); - - // Used for populating gate open/closed material. - public static Queue blockPopulatorQueue = new LinkedList<>(); - - // HashMap of player names for Bungee support - public static Map bungeeQueue = new HashMap<>(); - - // World names that contain stargates - public static HashSet managedWorlds = new HashSet<>(); - - public void onDisable() { - Portal.closeAllGates(); - Portal.clearGates(); - managedWorlds.clear(); - getServer().getScheduler().cancelTasks(this); - } - - public void onEnable() { - PluginDescriptionFile pdfFile = this.getDescription(); - pm = getServer().getPluginManager(); - newConfig = this.getConfig(); - log = Logger.getLogger("Minecraft"); - Stargate.server = getServer(); - Stargate.stargate = this; - - // Set portalFile and gateFolder to the plugin folder as defaults. - portalFolder = getDataFolder().getPath().replaceAll("\\\\", "/") + "/portals/"; - gateFolder = getDataFolder().getPath().replaceAll("\\\\", "/") + "/gates/"; - langFolder = getDataFolder().getPath().replaceAll("\\\\", "/") + "/lang/"; - - log.info(pdfFile.getName() + " v." + pdfFile.getVersion() + " is enabled."); - - // Register events before loading gates to stop weird things happening. - pm.registerEvents(new pListener(), this); - pm.registerEvents(new bListener(), this); - - pm.registerEvents(new vListener(), this); - pm.registerEvents(new eListener(), this); - pm.registerEvents(new wListener(), this); - pm.registerEvents(new sListener(), this); - - this.loadConfig(); - - // Enable the required channels for Bungee support - if (enableBungee) { - Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new pmListener()); - } - - // It is important to load languages here, as they are used during reloadGates() - lang = new LangLoader(langFolder, Stargate.langName); - - this.migrate(); - this.loadGates(); - this.loadAllPortals(); - - // Check to see if Economy is loaded yet. - if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) - log.info("[Stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); - } - - getServer().getScheduler().scheduleSyncRepeatingTask(this, new SGThread(), 0L, 100L); - getServer().getScheduler().scheduleSyncRepeatingTask(this, new BlockPopulatorThread(), 0L, 1L); - } - - public void loadConfig() { - reloadConfig(); - newConfig = this.getConfig(); - // Copy default values if required - newConfig.options().copyDefaults(true); - - // Load values into variables - portalFolder = newConfig.getString("portal-folder"); - gateFolder = newConfig.getString("gate-folder"); - defNetwork = newConfig.getString("default-gate-network").trim(); - destroyExplosion = newConfig.getBoolean("destroyexplosion"); - maxGates = newConfig.getInt("maxgates"); - langName = newConfig.getString("lang"); - destMemory = newConfig.getBoolean("destMemory"); - ignoreEntrance = newConfig.getBoolean("ignoreEntrance"); - handleVehicles = newConfig.getBoolean("handleVehicles"); - sortLists = newConfig.getBoolean("sortLists"); - protectEntrance = newConfig.getBoolean("protectEntrance"); - enableBungee = newConfig.getBoolean("enableBungee"); - verifyPortals = newConfig.getBoolean("verifyPortals"); - // Sign color - String sc = newConfig.getString("signColor"); - try { - signColor = ChatColor.valueOf(sc.toUpperCase()); - } catch (Exception ignore) { - log.warning("[Stargate] You have specified an invalid color in your config.yml. Defaulting to BLACK"); - signColor = ChatColor.BLACK; - } - // Debug - debug = newConfig.getBoolean("debug"); - permDebug = newConfig.getBoolean("permdebug"); - // Economy - EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); - EconomyHandler.createCost = newConfig.getInt("createcost"); - EconomyHandler.destroyCost = newConfig.getInt("destroycost"); - EconomyHandler.useCost = newConfig.getInt("usecost"); - EconomyHandler.toOwner = newConfig.getBoolean("toowner"); - EconomyHandler.chargeFreeDestination = newConfig.getBoolean("chargefreedestination"); - EconomyHandler.freeGatesGreen = newConfig.getBoolean("freegatesgreen"); - - this.saveConfig(); - } - - public void closeAllPortals() { - // Close all gates prior to reloading - for (Portal p : openList) { - p.close(true); - } - } - - public void loadGates() { - Gate.loadGates(gateFolder); - log.info("[Stargate] Loaded " + Gate.getGateCount() + " gate layouts"); - } - - public void loadAllPortals() { - for (World world : getServer().getWorlds()) { - if(!managedWorlds.contains(world.getName())) { - Portal.loadAllGates(world); - managedWorlds.add(world.getName()); - } - } - } - - private void migrate() { - // Only migrate if new file doesn't exist. - File newPortalDir = new File(portalFolder); - if (!newPortalDir.exists()) { - newPortalDir.mkdirs(); - } - File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); - if (!newFile.exists()) { - newFile.getParentFile().mkdirs(); - } - } - - public static void debug(String rout, String msg) { - if (Stargate.debug) { - log.info("[Stargate::" + rout + "] " + msg); - } else { - log.log(Level.FINEST, "[Stargate::" + rout + "] " + msg); - } - } - - public static void sendMessage(CommandSender player, String message) { - sendMessage(player, message, true); - } - - public static void sendMessage(CommandSender player, String message, boolean error) { - if (message.isEmpty()) return; - message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); - if (error) - player.sendMessage(ChatColor.RED + Stargate.getString("prefix") + ChatColor.WHITE + message); - else - player.sendMessage(ChatColor.GREEN + Stargate.getString("prefix") + ChatColor.WHITE + message); - } - - public static void setLine(Sign sign, int index, String text) { - sign.setLine(index, Stargate.signColor + text); - } - - public static String getSaveLocation() { - return portalFolder; - } - - public static String getGateFolder() { - return gateFolder; - } - - public static String getDefaultNetwork() { - return defNetwork; - } - - public static String getString(String name) { - return lang.getString(name); - } - - public static void openPortal(Player player, Portal portal) { - Portal destination = portal.getDestination(); - - // Always-open gate -- Do nothing - if (portal.isAlwaysOn()) { - return; - } - - // Random gate -- Do nothing - if (portal.isRandom()) - return; - - // Invalid destination - if ((destination == null) || (destination == portal)) { - Stargate.sendMessage(player, Stargate.getString("invalidMsg")); - return; - } - - // Gate is already open - if (portal.isOpen()) { - // Close if this player opened the gate - if (portal.getActivePlayer() == player) { - portal.close(false); - } - return; - } - - // Gate that someone else is using -- Deny access - if ((!portal.isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - // Check if the player can use the private gate - if (portal.isPrivate() && !Stargate.canPrivate(player, portal)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - // Destination blocked - if ((destination.isOpen()) && (!destination.isAlwaysOn())) { - Stargate.sendMessage(player, Stargate.getString("blockMsg")); - return; - } - - // Open gate - portal.open(player, false); - } - - /* - * Check whether the player has the given permissions. - */ - public static boolean hasPerm(Player player, String perm) { - if (permDebug) - Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); - return player.hasPermission(perm); - } - - /* - * Check a deep permission, this will check to see if the permissions is defined for this use - * If using Permissions it will return the same as hasPerm - * If using SuperPerms will return true if the node isn't defined - * Or the value of the node if it is - */ - public static boolean hasPermDeep(Player player, String perm) { - if (!player.isPermissionSet(perm)) { - if (permDebug) - Stargate.debug("hasPermDeep::SuperPerm", perm + " => true"); - return true; - } - if (permDebug) - Stargate.debug("hasPermDeep::SuperPerms", perm + " => " + player.hasPermission(perm)); - return player.hasPermission(perm); - } - - /* - * Check whether player can teleport to dest world - */ - public static boolean canAccessWorld(Player player, String world) { - // Can use all Stargate player features or access all worlds - if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.world")) { - // Do a deep check to see if the player lacks this specific world node - return hasPermDeep(player, "stargate.world." + world); - } - // Can access dest world - return hasPerm(player, "stargate.world." + world); - } - - /* - * Check whether player can use network - */ - public static boolean canAccessNetwork(Player player, String network) { - // Can user all Stargate player features, or access all networks - if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.network")) { - // Do a deep check to see if the player lacks this specific network node - return hasPermDeep(player, "stargate.network." + network); - } - // Can access this network - if (hasPerm(player, "stargate.network." + network)) return true; - // Is able to create personal gates (Assumption is made they can also access them) - String playerName = player.getName(); - if (playerName.length() > 11) playerName = playerName.substring(0, 11); - return network.equals(playerName) && hasPerm(player, "stargate.create.personal"); - } - - /* - * Check whether the player can access this server - */ - public static boolean canAccessServer(Player player, String server) { - // Can user all Stargate player features, or access all servers - if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.servers")) { - // Do a deep check to see if the player lacks this specific server node - return hasPermDeep(player, "stargate.server." + server); - } - // Can access this server - return hasPerm(player, "stargate.server." + server); - } - - /* - * Call the StargateAccessPortal event, used for other plugins to bypass Permissions checks - */ - public static boolean canAccessPortal(Player player, Portal portal, boolean deny) { - StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); - Stargate.server.getPluginManager().callEvent(event); - return !event.getDeny(); - } - - /* - * Return true if the portal is free for the player - */ - public static boolean isFree(Player player, Portal src, Portal dest) { - // This gate is free - if (src.isFree()) return true; - // Player gets free use - if (hasPerm(player, "stargate.free") || Stargate.hasPerm(player, "stargate.free.use")) return true; - // Don't charge for free destination gates - return dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree(); - } - - /* - * Check whether the player can see this gate (Hidden property check) - */ - public static boolean canSee(Player player, Portal portal) { - // The gate is not hidden - if (!portal.isHidden()) return true; - // The player is an admin with the ability to see hidden gates - if (hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.hidden")) return true; - // The player is the owner of the gate - return portal.isOwner(player); - } - - /* - * Check if the player can use this private gate - */ - public static boolean canPrivate(Player player, Portal portal) { - // Check if the player is the owner of the gate - if (portal.isOwner(player)) return true; - // The player is an admin with the ability to use private gates - return hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.private"); - } - - /* - * Check if the player has access to {option} - */ - public static boolean canOption(Player player, String option) { - // Check if the player can use all options - if (hasPerm(player, "stargate.option")) return true; - // Check if they can use this specific option - return hasPerm(player, "stargate.option." + option); - } - - /* - * Check if the player can create gates on {network} - */ - public static boolean canCreate(Player player, String network) { - // Check for general create - if (hasPerm(player, "stargate.create")) return true; - // Check for all network create permission - if (hasPerm(player, "stargate.create.network")) { - // Do a deep check to see if the player lacks this specific network node - return hasPermDeep(player, "stargate.create.network." + network); - } - // Check for this specific network - return hasPerm(player, "stargate.create.network." + network); - - } - - /* - * Check if the player can create a personal gate - */ - public static boolean canCreatePersonal(Player player) { - // Check for general create - if (hasPerm(player, "stargate.create")) return true; - // Check for personal - return hasPerm(player, "stargate.create.personal"); - } - - /* - * Check if the player can create this gate layout - */ - public static boolean canCreateGate(Player player, String gate) { - // Check for general create - if (hasPerm(player, "stargate.create")) return true; - // Check for all gate create permissions - if (hasPerm(player, "stargate.create.gate")) { - // Do a deep check to see if the player lacks this specific gate node - return hasPermDeep(player, "stargate.create.gate." + gate); - } - // Check for this specific gate - return hasPerm(player, "stargate.create.gate." + gate); - } - - /* - * Check if the player can destroy this gate - */ - public static boolean canDestroy(Player player, Portal portal) { - String network = portal.getNetwork(); - // Check for general destroy - if (hasPerm(player, "stargate.destroy")) return true; - // Check for all network destroy permission - if (hasPerm(player, "stargate.destroy.network")) { - // Do a deep check to see if the player lacks permission for this network node - return hasPermDeep(player, "stargate.destroy.network." + network); - } - // Check for this specific network - if (hasPerm(player, "stargate.destroy.network." + network)) return true; - // Check for personal gate - return portal.isOwner(player) && hasPerm(player, "stargate.destroy.personal"); - } - - /* - * Charge player for {action} if required, true on success, false if can't afford - */ - public static boolean chargePlayer(Player player, String target, int cost) { - // If cost is 0 - if (cost == 0) return true; - // Economy is disabled - if (!EconomyHandler.useEconomy()) return true; - // Charge player - return EconomyHandler.chargePlayer(player, target, cost); - } - - /* - * Charge player for {action} if required, true on success, false if can't afford - */ - public static boolean chargePlayer(Player player, UUID target, int cost) { - // If cost is 0 - if (cost == 0) return true; - // Economy is disabled - if (!EconomyHandler.useEconomy()) return true; - // Charge player - return EconomyHandler.chargePlayer(player, target, cost); - } - - /* - * Charge player for {action} if required, true on success, false if can't afford - */ - public static boolean chargePlayer(Player player, int cost) { - // If cost is 0 - if (cost == 0) return true; - // Economy is disabled - if (!EconomyHandler.useEconomy()) return true; - // Charge player - return EconomyHandler.chargePlayer(player, cost); - } - - /* - * Determine the cost of a gate - */ - public static int getUseCost(Player player, Portal src, Portal dest) { - // Not using Economy - if (!EconomyHandler.useEconomy()) return 0; - // Portal is free - if (src.isFree()) return 0; - // Not charging for free destinations - if (dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree()) return 0; - // Cost is 0 if the player owns this gate and funds go to the owner - if (src.getGate().getToOwner() && src.isOwner(player)) return 0; - // Player gets free gate use - if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.use")) return 0; - - return src.getGate().getUseCost(); - } - - /* - * Determine the cost to create the gate - */ - public static int getCreateCost(Player player, Gate gate) { - // Not using Economy - if (!EconomyHandler.useEconomy()) return 0; - // Player gets free gate destruction - if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.create")) return 0; - - return gate.getCreateCost(); - } - - /* - * Determine the cost to destroy the gate - */ - public static int getDestroyCost(Player player, Gate gate) { - // Not using Economy - if (!EconomyHandler.useEconomy()) return 0; - // Player gets free gate destruction - if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.destroy")) return 0; - - return gate.getDestroyCost(); - } - - /* - * Check if a plugin is loaded/enabled already. Returns the plugin if so, null otherwise - */ - private Plugin checkPlugin(String p) { - Plugin plugin = pm.getPlugin(p); - return checkPlugin(plugin); - } - - private Plugin checkPlugin(Plugin plugin) { - if (plugin != null && plugin.isEnabled()) { - log.info("[Stargate] Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")"); - return plugin; - } - return null; - } - - /* - * Parse a given text string and replace the variables - */ - public static String replaceVars(String format, String[] search, String[] replace) { - if (search.length != replace.length) return ""; - for (int i = 0; i < search.length; i++) { - format = format.replace(search[i], replace[i]); - } - return format; - } - - private class vListener implements Listener { - @EventHandler - public void onVehicleMove(VehicleMoveEvent event) { - if (!handleVehicles) return; - List passengers = event.getVehicle().getPassengers(); - Vehicle vehicle = event.getVehicle(); - - Portal portal = Portal.getByEntrance(event.getTo()); - if (portal == null || !portal.isOpen()) return; - - // We don't support vehicles in Bungee portals - if (portal.isBungee()) return; - - if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - /* - Player player = (Player) passengers.get(0); - if (!portal.isOpenFor(player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - Portal dest = portal.getDestination(player); - if (dest == null) return; - boolean deny = false; - // Check if player has access to this network - if (!canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - // Check if player has access to destination world - if (!canAccessWorld(player, dest.getWorld().getName())) { - deny = true; - } - - if (!canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.close(false); - return; - } - - int cost = Stargate.getUseCost(player, portal, dest); - if (cost > 0) { - boolean success; - if(portal.getGate().getToOwner()) { - if(portal.getOwnerUUID() == null) { - success = Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = Stargate.chargePlayer(player, portal.getOwnerName(), cost); - } - } else { - success = Stargate.chargePlayer(player, cost); - } - if(!success) { - // Insufficient Funds - Stargate.sendMessage(player, Stargate.getString("inFunds")); - portal.close(false); - return; - } - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - if (portal.getGate().getToOwner()) { - Player p; - if(portal.getOwnerUUID() != null) { - p = server.getPlayer(portal.getOwnerUUID()); - } else { - p = server.getPlayer(portal.getOwnerName()); - } - if (p != null) { - String obtainedMsg = Stargate.getString("ecoObtain"); - obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - Stargate.sendMessage(p, obtainedMsg, false); - } - } - } - - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - dest.teleport(vehicle); - portal.close(false); - */ - } else { - Portal dest = portal.getDestination(); - if (dest == null) return; - dest.teleport(vehicle); - } - } - } - - private class pListener implements Listener { - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - if (!enableBungee) return; - - Player player = event.getPlayer(); - String destination = bungeeQueue.remove(player.getName().toLowerCase()); - if (destination == null) return; - - Portal portal = Portal.getBungeeGate(destination); - if (portal == null) { - Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); - return; - } - portal.teleport(player, portal, null); - } - - @EventHandler - 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()) - && Portal.getByAdjacentEntrance(event.getFrom()) != null) { - event.setCancelled(true); - } - } - - @EventHandler - public void onPlayerMove(PlayerMoveEvent event) { - 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()) { - return; - } - - Player player = event.getPlayer(); - Portal portal = Portal.getByEntrance(event.getTo()); - // No portal or not open - if (portal == null || !portal.isOpen()) return; - - // Not open for this player - if (!portal.isOpenFor(player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.teleport(player, portal, event); - return; - } - - Portal destination = portal.getDestination(player); - if (!portal.isBungee() && destination == null) return; - - boolean deny = false; - // Check if player has access to this server for Bungee gates - if (portal.isBungee()) { - if (!canAccessServer(player, portal.getNetwork())) { - deny = true; - } - } else { - // Check if player has access to this network - if (!canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - // Check if player has access to destination world - if (!canAccessWorld(player, destination.getWorld().getName())) { - deny = true; - } - } - - if (!canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.teleport(player, portal, event); - portal.close(false); - return; - } - - int cost = Stargate.getUseCost(player, portal, destination); - if (cost > 0) { - boolean success; - if(portal.getGate().getToOwner()) { - if(portal.getOwnerUUID() == null) { - success = Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = Stargate.chargePlayer(player, portal.getOwnerName(), cost); - } - } else { - success = Stargate.chargePlayer(player, cost); - } - if(!success) { - // Insufficient Funds - Stargate.sendMessage(player, Stargate.getString("inFunds")); - portal.close(false); - return; - } - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) { - Player p; - if(portal.getOwnerUUID() != null) { - p = server.getPlayer(portal.getOwnerUUID()); - } else { - p = server.getPlayer(portal.getOwnerName()); - } - if (p != null) { - String obtainedMsg = Stargate.getString("ecoObtain"); - obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - Stargate.sendMessage(p, obtainedMsg, false); - } - } - } - - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - - // BungeeCord Support - if (portal.isBungee()) { - if (!enableBungee) { - player.sendMessage(Stargate.getString("bungeeDisabled")); - portal.close(false); - return; - } - - // Teleport the player back to this gate, for sanity's sake - portal.teleport(player, portal, 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() + "#@#" + portal.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(portal.getNetwork()); // Server - msgData.writeUTF("SGBungee"); // Channel - msgData.writeShort(msg.length()); // Data Length - msgData.writeBytes(msg); // Data - player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); - } catch (IOException ex) { - Stargate.log.severe("[Stargate] Error sending BungeeCord teleport packet"); - ex.printStackTrace(); - return; - } - - // Connect player to new server - try { - ByteArrayOutputStream bao = new ByteArrayOutputStream(); - DataOutputStream msgData = new DataOutputStream(bao); - msgData.writeUTF("Connect"); - msgData.writeUTF(portal.getNetwork()); - - player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); - bao.reset(); - } catch(IOException ex) { - Stargate.log.severe("[Stargate] Error sending BungeeCord connect packet"); - ex.printStackTrace(); - return; - } - - // Close portal if required (Should never be) - portal.close(false); - return; - } - - destination.teleport(player, portal, event); - portal.close(false); - } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - Player player = event.getPlayer(); - Block block = event.getClickedBlock(); - - if(block == null) return; - - // Right click - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (block.getBlockData() instanceof WallSign) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; - // Cancel item use - event.setUseItemInHand(Result.DENY); - event.setUseInteractedBlock(Result.DENY); - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - if ((!portal.isOpen()) && (!portal.isFixed())) { - portal.cycleDestination(player); - } - return; - } - - // Implement right-click to toggle a stargate, gets around spawn protection problem. - if (Tag.BUTTONS.isTagged(block.getType())) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; - - // Cancel item use - event.setUseItemInHand(Result.DENY); - event.setUseInteractedBlock(Result.DENY); - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - openPortal(player, portal); - if (portal.isOpenFor(player)) { - event.setUseInteractedBlock(Result.ALLOW); - } - } - return; - } - - // Left click - if (event.getAction() == Action.LEFT_CLICK_BLOCK) { - // Check if we're scrolling a sign - if (block.getBlockData() instanceof WallSign) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; - - event.setUseInteractedBlock(Result.DENY); - // Only cancel event in creative mode - if (player.getGameMode().equals(GameMode.CREATIVE)) { - event.setCancelled(true); - } - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - if ((!portal.isOpen()) && (!portal.isFixed())) { - portal.cycleDestination(player, -1); - } - } - } - } - } - - private class bListener implements Listener { - @EventHandler - public void onSignChange(SignChangeEvent event) { - if (event.isCancelled()) return; - Player player = event.getPlayer(); - Block block = event.getBlock(); - if (!(block.getBlockData() instanceof WallSign)) return; - - final Portal portal = Portal.createPortal(event, player); - // Not creating a gate, just placing a sign - if (portal == null) return; - - Stargate.sendMessage(player, Stargate.getString("createMsg"), false); - Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); - Stargate.server.getScheduler().scheduleSyncDelayedTask(stargate, new Runnable() { - public void run() { - portal.drawSign(); - } - }, 1); - } - - // Switch to HIGHEST priority so as to come after block protection plugins (Hopefully) - @EventHandler(priority = EventPriority.HIGHEST) - public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled()) return; - Block block = event.getBlock(); - Player player = event.getPlayer(); - - Portal portal = Portal.getByBlock(block); - if (portal == null && protectEntrance) - portal = Portal.getByEntrance(block); - if (portal == null) return; - - boolean deny = false; - String denyMsg = ""; - - if (!Stargate.canDestroy(player, portal)) { - denyMsg = "Permission Denied"; // TODO: Change to Stargate.getString() - deny = true; - Stargate.log.info("[Stargate] " + player.getName() + " tried to destroy gate"); - } - - int cost = Stargate.getDestroyCost(player, portal.getGate()); - - StargateDestroyEvent dEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); - Stargate.server.getPluginManager().callEvent(dEvent); - if (dEvent.isCancelled()) { - event.setCancelled(true); - return; - } - if (dEvent.getDeny()) { - Stargate.sendMessage(player, dEvent.getDenyReason()); - event.setCancelled(true); - return; - } - - cost = dEvent.getCost(); - - if (cost != 0) { - if (!Stargate.chargePlayer(player, cost)) { - Stargate.debug("onBlockBreak", "Insufficient Funds"); - Stargate.sendMessage(player, Stargate.getString("inFunds")); - event.setCancelled(true); - return; - } - - if (cost > 0) { - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - } else if (cost < 0) { - String refundMsg = Stargate.getString("ecoRefund"); - refundMsg = Stargate.replaceVars(refundMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(-cost), portal.getName()}); - sendMessage(player, refundMsg, false); - } - } - - portal.unregister(true); - Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); - } - - @EventHandler - public void onBlockPhysics(BlockPhysicsEvent event) { - Block block = event.getBlock(); - Portal portal = null; - - // Handle keeping portal material and buttons around - if (block.getType() == Material.NETHER_PORTAL) { - portal = Portal.getByEntrance(block); - } else if (Tag.BUTTONS.isTagged(block.getType())) { - portal = Portal.getByControl(block); - } - if (portal != null) event.setCancelled(true); - } - - @EventHandler - public void onBlockFromTo(BlockFromToEvent event) { - Portal portal = Portal.getByEntrance(event.getBlock()); - - if (portal != null) { - event.setCancelled((event.getBlock().getY() == event.getToBlock().getY())); - } - } - - @EventHandler - public void onPistonExtend(BlockPistonExtendEvent event) { - for(Block block : event.getBlocks()) { - Portal portal = Portal.getByBlock(block); - if (portal != null) { - event.setCancelled(true); - return; - } - } - } - - @EventHandler - public void onPistonRetract(BlockPistonRetractEvent event) { - if (!event.isSticky()) return; - for(Block block : event.getBlocks()) { - Portal portal = Portal.getByBlock(block); - if (portal != null) { - event.setCancelled(true); - return; - } - } - } - } - - private class wListener implements Listener { - @EventHandler - public void onWorldLoad(WorldLoadEvent event) { - if(!managedWorlds.contains(event.getWorld().getName()) - && Portal.loadAllGates(event.getWorld())) { - managedWorlds.add(event.getWorld().getName()); - } - } - - // We need to reload all gates on world unload, boo - @EventHandler - public void onWorldUnload(WorldUnloadEvent event) { - Stargate.debug("onWorldUnload", "Reloading all Stargates"); - World w = event.getWorld(); - if(managedWorlds.contains(w.getName())) { - managedWorlds.remove(w.getName()); - Portal.clearGates(); - for(World world : server.getWorlds()) { - if(managedWorlds.contains(world.getName())) { - Portal.loadAllGates(world); - } - } - } - } - } - - private class eListener implements Listener { - @EventHandler - public void onEntityExplode(EntityExplodeEvent event) { - if (event.isCancelled()) return; - for (Block b : event.blockList()) { - Portal portal = Portal.getByBlock(b); - if (portal == null) continue; - if (destroyExplosion) { - portal.unregister(true); - } else { - event.setCancelled(true); - break; - } - } - } - } - - private class sListener implements Listener { - @EventHandler - public void onPluginEnable(PluginEnableEvent event) { - if (EconomyHandler.setupEconomy(getServer().getPluginManager())) { - log.info("[Stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); - } - } - - @EventHandler - public void onPluginDisable(PluginDisableEvent event) { - if (event.getPlugin().equals(EconomyHandler.vault)) { - log.info("[Stargate] Vault plugin lost."); - } - } - } - - private class BlockPopulatorThread implements Runnable { - public void run() { - long sTime = System.nanoTime(); - while (System.nanoTime() - sTime < 25000000) { - BloxPopulator b = Stargate.blockPopulatorQueue.poll(); - if (b == null) return; - Block blk = b.getBlox().getBlock(); - blk.setType(b.getMat(), false); - if(b.getMat() == Material.END_GATEWAY && blk.getWorld().getEnvironment() == World.Environment.THE_END) { - // force a location to prevent exit gateway generation - EndGateway gateway = (EndGateway) blk.getState(); - gateway.setExitLocation(blk.getWorld().getSpawnLocation()); - gateway.setExactTeleport(true); - gateway.update(false, false); - } else if(b.getAxis() != null) { - Orientable orientable = (Orientable) blk.getBlockData(); - orientable.setAxis(b.getAxis()); - blk.setBlockData(orientable); - } - } - } - } - - private class SGThread implements Runnable { - public void run() { - long time = System.currentTimeMillis() / 1000; - // Close open portals - for (Iterator iter = Stargate.openList.iterator(); iter.hasNext();) { - Portal p = iter.next(); - // Skip always open gates - if (p.isAlwaysOn()) continue; - if (!p.isOpen()) continue; - if (time > p.getOpenTime() + Stargate.openTime) { - p.close(false); - iter.remove(); - } - } - // Deactivate active portals - for (Iterator iter = Stargate.activeList.iterator(); iter.hasNext();) { - Portal p = iter.next(); - if (!p.isActive()) continue; - if (time > p.getOpenTime() + Stargate.activeTime) { - p.deactivate(); - iter.remove(); - } - } - } - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, 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 (!lang.getString("author").isEmpty()) - sender.sendMessage("Language created by " + lang.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(); - Portal.clearGates(); - Gate.clearGates(); - - // Store the old Bungee enabled value - boolean oldEnableBungee = enableBungee; - // Reload data - loadConfig(); - loadGates(); - loadAllPortals(); - lang.setLang(langName); - lang.reload(); - - // Load Economy support if enabled/clear if disabled - if (EconomyHandler.economyEnabled && EconomyHandler.economy == null) { - if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) - log.info("[Stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); - } - } - 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 pmListener()); - } else { - Bukkit.getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord"); - } - } - - sendMessage(sender, "Stargate reloaded"); - return true; - } - return false; - } - return false; - } -} diff --git a/src/net/TheDgtl/Stargate/event/StargateActivateEvent.java b/src/net/TheDgtl/Stargate/event/StargateActivateEvent.java deleted file mode 100644 index e254c3b..0000000 --- a/src/net/TheDgtl/Stargate/event/StargateActivateEvent.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.TheDgtl.Stargate.event; - -import java.util.ArrayList; - -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -import net.TheDgtl.Stargate.Portal; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateActivateEvent extends StargateEvent { - private final Player player; - private ArrayList destinations; - private String destination; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public StargateActivateEvent(Portal portal, Player player, ArrayList destinations, String destination) { - super("StargatActivateEvent", portal); - - this.player = player; - this.destinations = destinations; - this.destination = destination; - } - - public Player getPlayer() { - return player; - } - - public ArrayList getDestinations() { - return destinations; - } - - public void setDestinations(ArrayList destinations) { - this.destinations = destinations; - } - - public String getDestination() { - return destination; - } - - public void setDestination(String destination) { - this.destination = destination; - } -} diff --git a/src/net/TheDgtl/Stargate/event/StargateCreateEvent.java b/src/net/TheDgtl/Stargate/event/StargateCreateEvent.java deleted file mode 100644 index 05a46d0..0000000 --- a/src/net/TheDgtl/Stargate/event/StargateCreateEvent.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.TheDgtl.Stargate.event; - -import net.TheDgtl.Stargate.Portal; -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateCreateEvent extends StargateEvent { - private final Player player; - private boolean deny; - private String denyReason; - private final String[] lines; - private int cost; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public StargateCreateEvent(Player player, Portal portal, String[] lines, boolean deny, String denyReason, int cost) { - super("StargateCreateEvent", portal); - this.player = player; - this.lines = lines; - this.deny = deny; - this.denyReason = denyReason; - this.cost = cost; - } - - public Player getPlayer() { - return player; - } - - public String getLine(int index) throws IndexOutOfBoundsException { - return lines[index]; - } - - public boolean getDeny() { - return deny; - } - - public void setDeny(boolean deny) { - this.deny = deny; - } - - public String getDenyReason() { - return denyReason; - } - - public void setDenyReason(String denyReason) { - this.denyReason = denyReason; - } - - public int getCost() { - return cost; - } - - public void setCost(int cost) { - this.cost = cost; - } - -} diff --git a/src/net/TheDgtl/Stargate/event/StargateDestroyEvent.java b/src/net/TheDgtl/Stargate/event/StargateDestroyEvent.java deleted file mode 100644 index 7ea06fe..0000000 --- a/src/net/TheDgtl/Stargate/event/StargateDestroyEvent.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.TheDgtl.Stargate.event; - -import net.TheDgtl.Stargate.Portal; -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateDestroyEvent extends StargateEvent { - private final Player player; - private boolean deny; - private String denyReason; - private int cost; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { - super("StargateDestroyEvent", portal); - this.player = player; - this.deny = deny; - this.denyReason = denyMsg; - this.cost = cost; - } - - public Player getPlayer() { - return player; - } - - public boolean getDeny() { - return deny; - } - - public void setDeny(boolean deny) { - this.deny = deny; - } - - public String getDenyReason() { - return denyReason; - } - - public void setDenyReason(String denyReason) { - this.denyReason = denyReason; - } - - public int getCost() { - return cost; - } - - public void setCost(int cost) { - this.cost = cost; - } - -} diff --git a/src/net/TheDgtl/Stargate/event/StargateOpenEvent.java b/src/net/TheDgtl/Stargate/event/StargateOpenEvent.java deleted file mode 100644 index 26ddc08..0000000 --- a/src/net/TheDgtl/Stargate/event/StargateOpenEvent.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.TheDgtl.Stargate.event; - -import net.TheDgtl.Stargate.Portal; - -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargateOpenEvent extends StargateEvent { - private final Player player; - private boolean force; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public StargateOpenEvent(Player player, Portal portal, boolean force) { - super ("StargateOpenEvent", portal); - - this.player = player; - this.force = force; - } - - /** - * Return the player than opened the gate. - * @return player than opened the gate - */ - public Player getPlayer() { - return player; - } - - public boolean getForce() { - return force; - } - - public void setForce(boolean force) { - this.force = force; - } -} diff --git a/src/net/TheDgtl/Stargate/event/StargatePortalEvent.java b/src/net/TheDgtl/Stargate/event/StargatePortalEvent.java deleted file mode 100644 index d02eb63..0000000 --- a/src/net/TheDgtl/Stargate/event/StargatePortalEvent.java +++ /dev/null @@ -1,80 +0,0 @@ -package net.TheDgtl.Stargate.event; - -import net.TheDgtl.Stargate.Portal; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; - -/** - * Stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -public class StargatePortalEvent extends StargateEvent { - private final Player player; - private final Portal destination; - private Location exit; - - private static final HandlerList handlers = new HandlerList(); - - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public StargatePortalEvent(Player player, Portal portal, Portal dest, Location exit) { - super ("StargatePortalEvent", portal); - - this.player = player; - this.destination = dest; - this.exit = exit; - } - - /** - * Return the player that went through the gate. - * @return player that went through the gate - */ - public Player getPlayer() { - return player; - } - - /** - * Return the destination gate - * @return destination gate - */ - public Portal getDestination() { - return destination; - } - - /** - * Return the location of the players exit point - * @return org.bukkit.Location Location of the exit point - */ - public Location getExit() { - return exit; - } - - /** - * Set the location of the players exit point - */ - public void setExit(Location loc) { - this.exit = loc; - } -} diff --git a/src/net/TheDgtl/Stargate/pmListener.java b/src/net/TheDgtl/Stargate/pmListener.java deleted file mode 100644 index ee83ba9..0000000 --- a/src/net/TheDgtl/Stargate/pmListener.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.TheDgtl.Stargate; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.bukkit.entity.Player; -import org.bukkit.plugin.messaging.PluginMessageListener; - -public class pmListener implements PluginMessageListener { - - @Override - public void onPluginMessageReceived(String channel, Player unused, byte[] message) { - if (!Stargate.enableBungee || !channel.equals("BungeeCord")) return; - - // Get data from message - String inChannel; - byte[] data; - try { - DataInputStream in = new DataInputStream(new ByteArrayInputStream(message)); - inChannel = in.readUTF(); - short len = in.readShort(); - data = new byte[len]; - in.readFully(data); - } catch (IOException ex) { - Stargate.log.severe("[Stargate] Error receiving BungeeCord message"); - ex.printStackTrace(); - return; - } - - // Verify that it's an SGBungee packet - if (!inChannel.equals("SGBungee")) { - return; - } - - // Data should be player name, and destination gate name - String msg = new String(data); - String[] parts = msg.split("#@#"); - - String playerName = parts[0]; - String destination = parts[1]; - - // Check if the player is online, if so, teleport, otherwise, queue - Player player = Stargate.server.getPlayer(playerName); - if (player == null) { - Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); - } else { - Portal dest = Portal.getBungeeGate(destination); - // Specified an invalid gate. For now we'll just let them connect at their current location - if (dest == null) { - Stargate.log.info("[Stargate] Bungee gate " + destination + " does not exist"); - return; - } - dest.teleport(player, dest, null); - } - } -} From c8d82a85756bd260b5c649d21977e908874cfb29 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Feb 2021 16:33:45 +0100 Subject: [PATCH 002/378] Removes CommonFunctions as it wasn't used --- .../knarcraft/stargate/CommonFunctions.java | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 src/main/java/net/knarcraft/stargate/CommonFunctions.java diff --git a/src/main/java/net/knarcraft/stargate/CommonFunctions.java b/src/main/java/net/knarcraft/stargate/CommonFunctions.java deleted file mode 100644 index 7c374fe..0000000 --- a/src/main/java/net/knarcraft/stargate/CommonFunctions.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.knarcraft.stargate; - -import java.io.InputStream; - -/* - * stargate - A portal plugin for Bukkit - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/** - * A holding class for methods shared between classes - * - * @author Kristian Knarvik - */ -public final class CommonFunctions { - - private CommonFunctions() {} - - /** - * Gets a resource as an InputStream - * - * @param resourceName

The name of the resource you want to readFromServer

- * @return

An input stream which can be used to access the resource

- */ - public static InputStream getResourceAsStream(String resourceName) { - ClassLoader classloader = Thread.currentThread().getContextClassLoader(); - return classloader.getResourceAsStream(resourceName); - } - -} From a268370f52fad83652e2249107c95a6513e6d3a8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Feb 2021 16:34:13 +0100 Subject: [PATCH 003/378] Updates plugin version to 0.9 --- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 36dff1a..8c6a88e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ net.knarcraft Stargate - 0.8.0.0 + 0.9.0.0 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3f08d22..2cbb296 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.8.0.0 +version: 0.9.0.0 description: Stargate mod for Bukkit author: EpicKnarvik97 website: https://knarcraft.net From ad2be874044f33bb91cb970e1c0d417db5c04dd1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Feb 2021 16:37:42 +0100 Subject: [PATCH 004/378] Cleans and commments the BlockLocation class by storing most of its information as a Location --- .../net/knarcraft/stargate/BlockLocation.java | 162 +++++++++++++----- 1 file changed, 117 insertions(+), 45 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index f607666..21f8efa 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -32,27 +32,23 @@ import org.bukkit.block.data.type.WallSign; /** * This class represents a block location + * + *

The BlockLocation class is basically a Location with some extra functionality.

*/ public class BlockLocation { - private final int x; - private final int y; - private final int z; - private final World world; + private final Location location; private BlockLocation parent = null; /** - * Creates a new block + * Creates a new block location * @param world

The world the block exists in

* @param x

The x coordinate of the block

* @param y

The y coordinate of the block

* @param z

The z coordinate of the block

*/ public BlockLocation(World world, int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - this.world = world; + this.location = new Location(world, x, y, z); } /** @@ -60,10 +56,7 @@ public class BlockLocation { * @param block

The block to

*/ public BlockLocation(Block block) { - this.x = block.getX(); - this.y = block.getY(); - this.z = block.getZ(); - this.world = block.getWorld(); + this.location = new Location(block.getWorld(), block.getX(), block.getY(), block.getZ()); } /** @@ -71,10 +64,7 @@ public class BlockLocation { * @param location

The location the block exists in

*/ public BlockLocation(Location location) { - this.x = location.getBlockX(); - this.y = location.getBlockY(); - this.z = location.getBlockZ(); - this.world = location.getWorld(); + this.location = location.clone(); } /** @@ -84,10 +74,8 @@ public class BlockLocation { */ public BlockLocation(World world, String string) { String[] split = string.split(","); - this.x = Integer.parseInt(split[0]); - this.y = Integer.parseInt(split[1]); - this.z = Integer.parseInt(split[2]); - this.world = world; + this.location = new Location(world, Integer.parseInt(split[0]), Integer.parseInt(split[1]), + Integer.parseInt(split[2])); } /** @@ -95,93 +83,174 @@ public class BlockLocation { * @param x

The x position relative to this block's position

* @param y

The y position relative to this block's position

* @param z

The z position relative to this block's position

- * @return

A new block

+ * @return

A new block location

*/ public BlockLocation makeRelative(int x, int y, int z) { - return new BlockLocation(this.world, this.x + x, this.y + y, this.z + z); + return new BlockLocation(this.location.clone().add(x, y, z)); } + /** + * Makes a location relative to the block location + * @param x

The x position relative to this block's position

+ * @param y

The y position relative to this block's position

+ * @param z

The z position relative to this block's position

+ * @param rotX

The x rotation of the location

+ * @param rotY

The y rotation of the location

+ * @return

A new location

+ */ public Location makeRelativeLoc(double x, double y, double z, float rotX, float rotY) { - return new Location(this.world, (double) this.x + x, (double) this.y + y, (double) this.z + z, rotX, rotY); + Location newLocation = this.location.clone(); + newLocation.setYaw(rotX); + newLocation.setPitch(rotY); + return newLocation.add(x, y, z); } + /** + * 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

+ * @return A new location relative to this block location + */ public BlockLocation modRelative(int right, int depth, int distance, int modX, int modY, int modZ) { return makeRelative(-right * modX + distance * modZ, -depth * modY, -right * modZ + -distance * modX); } + /** + * Makes a 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 rotX

The yaw of the location

+ * @param rotY

Unused

+ * @param modX

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

+ * @param modY

Unused

+ * @param modZ

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

+ * @return A new location relative to this block location + */ public Location modRelativeLoc(double right, double depth, double distance, float rotX, float rotY, int modX, int modY, int modZ) { return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); } + /** + * Sets the type for the block at this location + * @param type

The new block material type

+ */ public void setType(Material type) { - world.getBlockAt(x, y, z).setType(type); + this.location.getBlock().setType(type); } + /** + * Gets the type for the block at this location + * @return

The block material type

+ */ public Material getType() { - return world.getBlockAt(x, y, z).getType(); + return this.location.getBlock().getType(); } + /** + * Gets the block at this location + * @return

The block at this location

+ */ public Block getBlock() { - return world.getBlockAt(x, y, z); + return this.location.getBlock(); } + /** + * Gets the location representing this block location + * @return

The location representing this block location

+ */ public Location getLocation() { - return new Location(world, x, y, z); + return this.location.clone(); } + /** + * Gets the integer x coordinate for this block location + * @return

The x coordinate for this block location

+ */ public int getX() { - return x; + return this.location.getBlockX(); } + /** + * Gets the integer y coordinate for this block location + * @return

The y coordinate for this block location

+ */ public int getY() { - return y; + return this.location.getBlockY(); } + /** + * Gets the integer z coordinate for this block location + * @return

The z coordinate for this block location

+ */ public int getZ() { - return z; + return this.location.getBlockZ(); } + /** + * Gets the world this block location is within + * @return

The world for this block location

+ */ public World getWorld() { - return world; + return this.location.getWorld(); } + /** + * Gets this block location's parent block + * @return

This block location's parent block

+ */ public Block getParent() { - if (parent == null) findParent(); - if (parent == null) return null; + if (parent == null) { + findParent(); + } + if (parent == null) { + return null; + } return parent.getBlock(); } + /** + * Tries to find the parent block location + * + *

If this block location is a sign, the parent is the block location of the block the sign is connected to.

+ */ private void findParent() { int offsetX = 0; int offsetY = 0; int offsetZ = 0; - BlockData blk = getBlock().getBlockData(); - if (blk instanceof WallSign) { - BlockFace facing = ((WallSign) blk).getFacing().getOppositeFace(); + BlockData blockData = getBlock().getBlockData(); + if (blockData instanceof WallSign) { + BlockFace facing = ((WallSign) blockData).getFacing().getOppositeFace(); offsetX = facing.getModX(); offsetZ = facing.getModZ(); - } else if (blk instanceof Sign) { + } else if (blockData instanceof Sign) { offsetY = -1; } else { return; } - parent = new BlockLocation(world, getX() + offsetX, getY() + offsetY, getZ() + offsetZ); + parent = this.makeRelative(offsetX, offsetY, offsetZ); } @Override public String toString() { - return String.valueOf(x) + ',' + y + ',' + z; + return String.valueOf(this.location.getBlockX()) + ',' + this.location.getBlockY() + ',' + this.location.getBlockZ(); } @Override public int hashCode() { int result = 18; - result = result * 27 + x; - result = result * 27 + y; - result = result * 27 + z; - result = result * 27 + world.getName().hashCode(); + result = result * 27 + this.location.getBlockX(); + result = result * 27 + this.location.getBlockY(); + result = result * 27 + this.location.getBlockZ(); + if (this.location.getWorld() != null) { + result = result * 27 + this.location.getWorld().getName().hashCode(); + } return result; } @@ -193,7 +262,10 @@ public class BlockLocation { if (getClass() != obj.getClass()) return false; BlockLocation blockLocation = (BlockLocation) obj; - return (x == blockLocation.x) && (y == blockLocation.y) && (z == blockLocation.z) && (world.getName().equals(blockLocation.world.getName())); + + return blockLocation.getX() == this.getX() && blockLocation.getY() == this.getY() && + blockLocation.getZ() == this.getZ() && + blockLocation.getWorld().getName().equals(this.getWorld().getName()); } } \ No newline at end of file From 4e3867eae91622c748f5378b07b10b9afcdfd8dc Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Feb 2021 16:58:33 +0100 Subject: [PATCH 005/378] Simplifies BlockLocation by making it extend Location --- .../net/knarcraft/stargate/BlockLocation.java | 86 ++++++------------- 1 file changed, 24 insertions(+), 62 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index 21f8efa..8ad6fb6 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -35,9 +35,8 @@ import org.bukkit.block.data.type.WallSign; * *

The BlockLocation class is basically a Location with some extra functionality.

*/ -public class BlockLocation { +public class BlockLocation extends Location { - private final Location location; private BlockLocation parent = null; /** @@ -48,7 +47,7 @@ public class BlockLocation { * @param z

The z coordinate of the block

*/ public BlockLocation(World world, int x, int y, int z) { - this.location = new Location(world, x, y, z); + super(world, x, y, z); } /** @@ -56,15 +55,7 @@ public class BlockLocation { * @param block

The block to

*/ public BlockLocation(Block block) { - this.location = new Location(block.getWorld(), block.getX(), block.getY(), block.getZ()); - } - - /** - * Creates a new block from a location - * @param location

The location the block exists in

- */ - public BlockLocation(Location location) { - this.location = location.clone(); + super(block.getWorld(), block.getX(), block.getY(), block.getZ()); } /** @@ -73,9 +64,8 @@ public class BlockLocation { * @param string

A comma separated list of z, y and z coordinates as integers

*/ public BlockLocation(World world, String string) { - String[] split = string.split(","); - this.location = new Location(world, Integer.parseInt(split[0]), Integer.parseInt(split[1]), - Integer.parseInt(split[2])); + super(world, Integer.parseInt(string.split(",")[0]), Integer.parseInt(string.split(",")[1]), + Integer.parseInt(string.split(",")[2])); } /** @@ -86,7 +76,7 @@ public class BlockLocation { * @return

A new block location

*/ public BlockLocation makeRelative(int x, int y, int z) { - return new BlockLocation(this.location.clone().add(x, y, z)); + return (BlockLocation) this.clone().add(x, y, z); } /** @@ -99,7 +89,7 @@ public class BlockLocation { * @return

A new location

*/ public Location makeRelativeLoc(double x, double y, double z, float rotX, float rotY) { - Location newLocation = this.location.clone(); + Location newLocation = this.clone(); newLocation.setYaw(rotX); newLocation.setPitch(rotY); return newLocation.add(x, y, z); @@ -140,7 +130,7 @@ public class BlockLocation { * @param type

The new block material type

*/ public void setType(Material type) { - this.location.getBlock().setType(type); + this.getBlock().setType(type); } /** @@ -148,7 +138,7 @@ public class BlockLocation { * @return

The block material type

*/ public Material getType() { - return this.location.getBlock().getType(); + return this.getBlock().getType(); } /** @@ -156,7 +146,7 @@ public class BlockLocation { * @return

The block at this location

*/ public Block getBlock() { - return this.location.getBlock(); + return this.getBlock(); } /** @@ -164,39 +154,7 @@ public class BlockLocation { * @return

The location representing this block location

*/ public Location getLocation() { - return this.location.clone(); - } - - /** - * Gets the integer x coordinate for this block location - * @return

The x coordinate for this block location

- */ - public int getX() { - return this.location.getBlockX(); - } - - /** - * Gets the integer y coordinate for this block location - * @return

The y coordinate for this block location

- */ - public int getY() { - return this.location.getBlockY(); - } - - /** - * Gets the integer z coordinate for this block location - * @return

The z coordinate for this block location

- */ - public int getZ() { - return this.location.getBlockZ(); - } - - /** - * Gets the world this block location is within - * @return

The world for this block location

- */ - public World getWorld() { - return this.location.getWorld(); + return this.clone(); } /** @@ -238,18 +196,18 @@ public class BlockLocation { @Override public String toString() { - return String.valueOf(this.location.getBlockX()) + ',' + this.location.getBlockY() + ',' + this.location.getBlockZ(); + return String.valueOf(this.getBlockX()) + ',' + this.getBlockY() + ',' + this.getBlockZ(); } @Override public int hashCode() { int result = 18; - result = result * 27 + this.location.getBlockX(); - result = result * 27 + this.location.getBlockY(); - result = result * 27 + this.location.getBlockZ(); - if (this.location.getWorld() != null) { - result = result * 27 + this.location.getWorld().getName().hashCode(); + result = result * 27 + this.getBlockX(); + result = result * 27 + this.getBlockY(); + result = result * 27 + this.getBlockZ(); + if (this.getWorld() != null) { + result = result * 27 + this.getWorld().getName().hashCode(); } return result; @@ -263,9 +221,13 @@ public class BlockLocation { BlockLocation blockLocation = (BlockLocation) obj; - return blockLocation.getX() == this.getX() && blockLocation.getY() == this.getY() && - blockLocation.getZ() == this.getZ() && - blockLocation.getWorld().getName().equals(this.getWorld().getName()); + World thisWorld = this.getWorld(); + World otherWorld = blockLocation.getWorld(); + boolean worldsEqual = (thisWorld == null && otherWorld == null) || ((thisWorld != null && otherWorld != null) + && thisWorld == otherWorld); + + return blockLocation.getBlockX() == this.getBlockX() && blockLocation.getBlockY() == this.getBlockY() && + blockLocation.getBlockZ() == this.getBlockZ() && worldsEqual; } } \ No newline at end of file From 27aa0ed29d3d06a9aea40531c7e515e3fc868fb8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 00:31:53 +0100 Subject: [PATCH 006/378] Removes a function from BlockLocation present in Location which caused an infinite loop --- src/main/java/net/knarcraft/stargate/BlockLocation.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index 8ad6fb6..e8f969b 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -141,14 +141,6 @@ public class BlockLocation extends Location { return this.getBlock().getType(); } - /** - * Gets the block at this location - * @return

The block at this location

- */ - public Block getBlock() { - return this.getBlock(); - } - /** * Gets the location representing this block location * @return

The location representing this block location

From 9233776b2cad938e7141e6c2876aad1a20466053 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 00:32:20 +0100 Subject: [PATCH 007/378] Adds comments to BloxPopulator --- .../net/knarcraft/stargate/BloxPopulator.java | 64 +++++++++++++++---- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BloxPopulator.java b/src/main/java/net/knarcraft/stargate/BloxPopulator.java index 87bedb8..63031c0 100644 --- a/src/main/java/net/knarcraft/stargate/BloxPopulator.java +++ b/src/main/java/net/knarcraft/stargate/BloxPopulator.java @@ -3,44 +3,82 @@ package net.knarcraft.stargate; import org.bukkit.Axis; import org.bukkit.Material; +/** + * Used to store information about a custom block populator + */ public class BloxPopulator { private BlockLocation blockLocation; private Material nextMat; private Axis nextAxis; - public BloxPopulator(BlockLocation b, Material m) { - blockLocation = b; - nextMat = m; + /** + * Instantiates a new block populator + * @param blockLocation

The location to start from

+ * @param material

The material to populate

+ */ + public BloxPopulator(BlockLocation blockLocation, Material material) { + this.blockLocation = blockLocation; + nextMat = material; nextAxis = null; } - public BloxPopulator(BlockLocation b, Material m, Axis a) { - blockLocation = b; - nextMat = m; - nextAxis = a; + /** + * Instantiates a new block populator + * @param blockLocation

The location to start from

+ * @param material

The material to populate

+ * @param axis

The axis to populate along

+ */ + public BloxPopulator(BlockLocation blockLocation, Material material, Axis axis) { + this.blockLocation = blockLocation; + nextMat = material; + nextAxis = axis; } - public void setBlockLocation(BlockLocation b) { - blockLocation = b; + /** + * Sets the location to start from + * @param blockLocation

The new start location

+ */ + public void setBlockLocation(BlockLocation blockLocation) { + this.blockLocation = blockLocation; } - public void setMat(Material m) { - nextMat = m; + /** + * Sets the polulator material + * @param material

The new populator material

+ */ + public void setMat(Material material) { + nextMat = material; } - public void setAxis(Axis a) { - nextAxis = a; + /** + * Sets the populator axis + * @param axis

The new populator axis

+ */ + public void setAxis(Axis axis) { + nextAxis = axis; } + /** + * Gets the location to start from + * @return

The location to start from

+ */ public BlockLocation getBlockLocation() { return blockLocation; } + /** + * Gets the material used for population + * @return

The material used for population

+ */ public Material getMat() { return nextMat; } + /** + * Gets the current population axis + * @return

The current population axis

+ */ public Axis getAxis() { return nextAxis; } From 6e1a69881c77888c36cc946f6569708cc4463e7a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 00:32:58 +0100 Subject: [PATCH 008/378] Cleans, comments and renames BungeeCordListener --- .../stargate/BungeeCoordListener.java | 58 -------------- .../stargate/BungeeCordListener.java | 80 +++++++++++++++++++ 2 files changed, 80 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/net/knarcraft/stargate/BungeeCoordListener.java create mode 100644 src/main/java/net/knarcraft/stargate/BungeeCordListener.java diff --git a/src/main/java/net/knarcraft/stargate/BungeeCoordListener.java b/src/main/java/net/knarcraft/stargate/BungeeCoordListener.java deleted file mode 100644 index 57fe488..0000000 --- a/src/main/java/net/knarcraft/stargate/BungeeCoordListener.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.knarcraft.stargate; - -import org.bukkit.entity.Player; -import org.bukkit.plugin.messaging.PluginMessageListener; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -public class BungeeCoordListener implements PluginMessageListener { - - @Override - public void onPluginMessageReceived(String channel, Player unused, byte[] message) { - if (!Stargate.enableBungee || !channel.equals("BungeeCord")) return; - - // Get data from message - String inChannel; - byte[] data; - try { - DataInputStream in = new DataInputStream(new ByteArrayInputStream(message)); - inChannel = in.readUTF(); - short len = in.readShort(); - data = new byte[len]; - in.readFully(data); - } catch (IOException ex) { - Stargate.log.severe("[stargate] Error receiving BungeeCord message"); - ex.printStackTrace(); - return; - } - - // Verify that it's an SGBungee packet - if (!inChannel.equals("SGBungee")) { - return; - } - - // Data should be player name, and destination gate name - String msg = new String(data); - String[] parts = msg.split("#@#"); - - String playerName = parts[0]; - String destination = parts[1]; - - // Check if the player is online, if so, teleport, otherwise, queue - Player player = Stargate.server.getPlayer(playerName); - if (player == null) { - Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); - } else { - Portal dest = Portal.getBungeeGate(destination); - // Specified an invalid gate. For now we'll just let them connect at their current location - if (dest == null) { - Stargate.log.info("[stargate] Bungee gate " + destination + " does not exist"); - return; - } - dest.teleport(player, dest, null); - } - } - -} diff --git a/src/main/java/net/knarcraft/stargate/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/BungeeCordListener.java new file mode 100644 index 0000000..b4e4c43 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/BungeeCordListener.java @@ -0,0 +1,80 @@ +package net.knarcraft.stargate; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; + +/** + * This listener teleports a user if a valid message is received from BungeeCord + * + *

Specifically, if a string starts with SGBungee encoded to be readable by readUTF followed by + * PlayerName#@#DestinationPortal is received on the BungeeCord channel, this listener will teleport the player to the + * destination portal.

+ */ +public class BungeeCordListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(String channel, Player unused, byte[] message) { + if (!Stargate.enableBungee || !channel.equals("BungeeCord")) { + return; + } + + String receivedMessage = readPluginMessage(message); + if (receivedMessage == null) { + return; + } + + String[] messageParts = receivedMessage.split("#@#"); + + String playerName = messageParts[0]; + String destination = messageParts[1]; + + // Check if the player is online, if so, teleport, otherwise, queue + Player player = Stargate.server.getPlayer(playerName); + if (player == null) { + Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); + } else { + Portal destinationPortal = Portal.getBungeeGate(destination); + // Specified an invalid gate. For now we'll just let them connect at their current location + if (destinationPortal == null) { + Stargate.log.info("[stargate] Bungee gate " + destination + " does not exist"); + return; + } + destinationPortal.teleport(player, destinationPortal, null); + } + } + + /** + * Reads a plugin message byte array to a string + * @param message

The byte array to read

+ * @return

The message contained in the byte array

+ */ + private String readPluginMessage(byte[] message) { + // Get data from message + String inChannel; + byte[] data; + try { + DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(message)); + inChannel = dataInputStream.readUTF(); + short dataLength = dataInputStream.readShort(); + data = new byte[dataLength]; + dataInputStream.readFully(data); + } catch (IOException ex) { + Stargate.log.severe("[stargate] Error receiving BungeeCord message"); + ex.printStackTrace(); + return null; + } + + // Verify that it's an SGBungee packet + if (!inChannel.equals("SGBungee")) { + return null; + } + + // Data should be player name, and destination gate name + return new String(data); + } + +} From 6d6a7e52b2be802b5bf01e7d3bcf018f03633f00 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 00:33:55 +0100 Subject: [PATCH 009/378] Renames usages of BungeeCoordListener to BungeeCordListener --- src/main/java/net/knarcraft/stargate/Stargate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 269e541..9079b37 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -167,7 +167,7 @@ public class Stargate extends JavaPlugin { // Enable the required channels for Bungee support if (enableBungee) { Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCoordListener()); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); } // It is important to load languages here, as they are used during reloadGates() @@ -1262,7 +1262,7 @@ public class Stargate extends JavaPlugin { if (oldEnableBungee != enableBungee) { if (enableBungee) { Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCoordListener()); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); } else { Bukkit.getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord"); Bukkit.getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord"); From 6825266a92fd34af51951c93c86f720260909e4d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 00:35:34 +0100 Subject: [PATCH 010/378] Fixes a bug caused by BlockLocation not being able to be instantiated from a location object --- src/main/java/net/knarcraft/stargate/Portal.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index dca3bd0..7eac5d9 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -1211,7 +1211,8 @@ public class Portal { } public static Portal getByEntrance(Location location) { - return lookupEntrances.get(new BlockLocation(location)); + return lookupEntrances.get(new BlockLocation(location.getWorld(), location.getBlockX(), location.getBlockY(), + location.getBlockZ())); } public static Portal getByEntrance(Block block) { From df111c27503a042c70a88ede34b07dd7465402e8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 01:54:18 +0100 Subject: [PATCH 011/378] Adds Norwegian translation --- src/main/resources/lang/no.txt | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/resources/lang/no.txt diff --git a/src/main/resources/lang/no.txt b/src/main/resources/lang/no.txt new file mode 100644 index 0000000..6a7e8d8 --- /dev/null +++ b/src/main/resources/lang/no.txt @@ -0,0 +1,33 @@ +author=EpicKnarvik97 +prefix=[Stjerneport] +teleportMsg=Teleporterte +destroyMsg=Port ร˜delagt +invalidMsg=Ugyldig Destinasjon +blockMsg=Destinasjon Blokkert +destEmpty=Destinasjonslisten Er Tom +denyMsg=Tilgang Avslรฅtt + +ecoDeduct=Fratrekk %cost% +ecoRefund=Refundert %cost% +ecoObtain=Fikk %cost% fra Stjerneport %portal% +ecoInFunds=Manglende Midler + +createMsg=Port opprettet +createNetDeny=Du har ikke tilgang til det nettverket +createGateDeny=Du har ikke tilgang til den portutformingen +createPersonal=Oppretter port pรฅ personlig nettverk +createNameLength=Navnet er for kort eller for langt. +createExists=En port ved det navnet eksisterer allerede +createFull=Dette nettverket er fullt +createWorldDeny=Du har ikke tilgang til den verdenen +createConflict=Port er i konflikt med en eksisterende port + +signRightClick=Hรธyreklikk +signToUse=for รฅ bruke port +signRandom=Tilfeldig +signDisconnected=Koblet fra + +bungeeDisabled=BungeeCord stรธtte er slรฅtt av. +bungeeDeny=Du har ikke tillatelse til รฅ opprette BungeeCord porter. +bungeeEmpty=BungeeCord porter behรธver bรฅde en destinasjon og et nettverk. +bungeeSign=Teleporter til From 341a445d1609d43d5093faf565a48802ca48a639 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 05:07:35 +0100 Subject: [PATCH 012/378] =?UTF-8?q?Fixes=20language=20file=20formats,=20fi?= =?UTF-8?q?xes=20name=20of=20Norwegian=20Bokm=C3=A5l=20and=20adds=20Norewg?= =?UTF-8?q?ian=20Bokm=C3=A5l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/lang/de.txt | 10 +++--- src/main/resources/lang/es.txt | 8 ++--- src/main/resources/lang/fr.txt | 2 +- src/main/resources/lang/{no.txt => nb-no.txt} | 4 +-- src/main/resources/lang/nn-no.txt | 33 +++++++++++++++++++ src/main/resources/lang/pt-br.txt | 2 +- src/main/resources/lang/ru.txt | 2 +- 7 files changed, 47 insertions(+), 14 deletions(-) rename src/main/resources/lang/{no.txt => nb-no.txt} (91%) create mode 100644 src/main/resources/lang/nn-no.txt diff --git a/src/main/resources/lang/de.txt b/src/main/resources/lang/de.txt index c10be27..c2c2f61 100644 --- a/src/main/resources/lang/de.txt +++ b/src/main/resources/lang/de.txt @@ -1,22 +1,22 @@ author=EduardBaer prefix=[Stargate] teleportMsg=Du wurdest Teleportiert. -destroyMsg=Gate zerst๖rt -invalidMsg=Ungltiges Ziel +destroyMsg=Gate zerstรถrt +invalidMsg=Ungรผltiges Ziel blockMsg=Ziel blockiert destEmpty=Zielliste leer denyMsg=Zugriff verweigert ecoDeduct=%cost% abgezogen -ecoRefund=%cost% zurckerstattet +ecoRefund=%cost% zurรผckerstattet ecoObtain=%cost% von Stargate %portal% erhalten ecoInFunds=Das kannst du dir nicht leisten. createMsg=Gate erstellt. createNetDeny=Du hast keinen Zugriff auf dieses Netzwerk. createGateDeny=Du hast keinen Zugriff auf dieses Gate-Layout. -createPersonal=Gate im pers๖nlichen Netzwerk erstellt. -createNameLength=Name zu kurz oder zu chosenLanguage. +createPersonal=Gate im persรถnlichen Netzwerk erstellt. +createNameLength=Name zu kurz oder zu lang. createExists=Ein Gate mit diesem Name existiert bereits. createFull=Dieses Netzwerk ist voll. createWorldDeny=Du hast keinen Zugriff auf diese Welt. diff --git a/src/main/resources/lang/es.txt b/src/main/resources/lang/es.txt index 5fe853b..5c5338f 100644 --- a/src/main/resources/lang/es.txt +++ b/src/main/resources/lang/es.txt @@ -1,10 +1,10 @@ author=Manuestaire prefix=[Stargate] teleportMsg=Teletransportado -destroyMsg=Portal Destruํdo +destroyMsg=Portal Destruรญdo invalidMsg=Elige Destino blockMsg=Destino Bloqueado -destEmpty=La lista de destinos estแ vacํa +destEmpty=La lista de destinos estรก vacรญa denyMsg=Acceso denegado ecoDeduct=Pagaste %cost% @@ -14,11 +14,11 @@ ecoInFunds=No tienes suficiente dinero createMsg=Portal creado createNetDeny=No tienes acceso a esta red -createGateDeny=No tienes acceso a este dise๑o de portal +createGateDeny=No tienes acceso a este diseรฑo de portal createPersonal=Creando el portal en una red personal createNameLength=Nombre demasiado largo o demasiado corto createExists=Ya existe una puerta con este nombre -createFull=Esta red estแ llena +createFull=Esta red estรก llena createWorldDeny=No tienes permisos para acceder a ese mundo createConflict=El portal entra en conflicto con un portal ya existente diff --git a/src/main/resources/lang/fr.txt b/src/main/resources/lang/fr.txt index 8b945a4..66fd9ca 100644 --- a/src/main/resources/lang/fr.txt +++ b/src/main/resources/lang/fr.txt @@ -1,4 +1,4 @@ -๏ปฟauthor=Dauphin14 +author=Dauphin14 prefix=[Stargate] teleportMsg=Tรฉlรฉportation Rรฉussie. destroyMsg=Portail detruit. diff --git a/src/main/resources/lang/no.txt b/src/main/resources/lang/nb-no.txt similarity index 91% rename from src/main/resources/lang/no.txt rename to src/main/resources/lang/nb-no.txt index 6a7e8d8..22b0d15 100644 --- a/src/main/resources/lang/no.txt +++ b/src/main/resources/lang/nb-no.txt @@ -1,5 +1,5 @@ author=EpicKnarvik97 -prefix=[Stjerneport] +prefix=[Stjerneport] teleportMsg=Teleporterte destroyMsg=Port ร˜delagt invalidMsg=Ugyldig Destinasjon @@ -29,5 +29,5 @@ signDisconnected=Koblet fra bungeeDisabled=BungeeCord stรธtte er slรฅtt av. bungeeDeny=Du har ikke tillatelse til รฅ opprette BungeeCord porter. -bungeeEmpty=BungeeCord porter behรธver bรฅde en destinasjon og et nettverk. +bungeeEmpty=BungeeCord porter behรธver bade en destinasjon og et nettverk. bungeeSign=Teleporter til diff --git a/src/main/resources/lang/nn-no.txt b/src/main/resources/lang/nn-no.txt new file mode 100644 index 0000000..62f27fd --- /dev/null +++ b/src/main/resources/lang/nn-no.txt @@ -0,0 +1,33 @@ +author=EpicKnarvik97 +prefix=[Stjerneport] +teleportMsg=Teleporterte +destroyMsg=Port ร˜ydelagd +invalidMsg=Ugyldig Destinasjon +blockMsg=Destinasjon Blokkert +destEmpty=Destinasjonslista Er Tom +denyMsg=Tilgang Avslรฅtt + +ecoDeduct=Frรฅtrekk %cost% +ecoRefund=Refundert %cost% +ecoObtain=Mottok %cost% frรฅ Stjerneport %portal% +ecoInFunds=Manglande Midlar + +createMsg=Port oppretta +createNetDeny=Du har ikkje tilgang til det nettverket +createGateDeny=Du har ikkje tilgang til den portutforminga +createPersonal=Opprettar port pรฅ personleg nettverk +createNameLength=Namnet er for kort eller for langt. +createExists=Ein port med det namnet eksisterar allereie +createFull=Dette nettverket er fullt +createWorldDeny=Du har ikkje tilgang til den verda +createConflict=Port er i konflikt med ein eksisterande port + +signRightClick=Hรธgreklikk +signToUse=for รฅ bruke port +signRandom=Tilfeldig +signDisconnected=Kopla frรฅ + +bungeeDisabled=BungeeCord stรธtte er slรฅtt av. +bungeeDeny=Du har ikkje lรธyve til รฅ opprette BungeeCord portar. +bungeeEmpty=BungeeCord portar treng bade ein destinasjon og eit nettverk. +bungeeSign=Teleportar til diff --git a/src/main/resources/lang/pt-br.txt b/src/main/resources/lang/pt-br.txt index 5022e25..594e96c 100644 --- a/src/main/resources/lang/pt-br.txt +++ b/src/main/resources/lang/pt-br.txt @@ -17,7 +17,7 @@ createNetDeny=Voce nao tem acesso a essa rede. createGateDeny=Voce nao tem acesso a esse portal layout. createPersonal=Criando portal em rede pessoal. createNameLength=Nome muito curto ou muito grande. -createExists=Jแ existe um portal com esse nome. +createExists=Jรก existe um portal com esse nome. createFull=Esta rede esta cheia. createWorldDeny=Voce nao tem acesso a esse mundo. createConflict=Portal em conflito com um portal ja existente. diff --git a/src/main/resources/lang/ru.txt b/src/main/resources/lang/ru.txt index 6431462..afef3c7 100644 --- a/src/main/resources/lang/ru.txt +++ b/src/main/resources/lang/ru.txt @@ -1,4 +1,4 @@ -๏ปฟauthor=ckr@jk +author=ckr@jk prefix=[ะŸะพั€ั‚ะฐะป] teleportMsg=ะ’ั‹ ะฟะตั€ะตะผะตั‰ะตะฝั‹ destroyMsg=ะŸะพั€ั‚ะฐะป ัƒะฝะธั‡ั‚ะพะถะตะฝ From 4f5cb84d02da8cd44da904061e058e9bb9931b63 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 05:10:10 +0100 Subject: [PATCH 013/378] Improves error handling when unable to load a language and always uses english as backup language to make sure the plugin won't crash when an invalid language is chosen --- .../knarcraft/stargate/LanguageLoader.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index 326ca3a..6fb7c08 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -65,7 +65,7 @@ public class LanguageLoader { loadedStringTranslations = load(chosenLanguage); // We have a default hashMap used for when new text is added. - InputStream inputStream = getClass().getResourceAsStream("/lang/" + chosenLanguage + ".txt"); + InputStream inputStream = getClass().getResourceAsStream("/lang/en.txt"); if (inputStream != null) { loadedBackupStrings = load("en", inputStream); } else { @@ -89,10 +89,17 @@ public class LanguageLoader { * @return

The string in the user's preferred language

*/ public String getString(String name) { - String val = loadedStringTranslations.get(name); - if (val == null && loadedBackupStrings != null) val = loadedBackupStrings.get(name); - if (val == null) return ""; - return val; + String value = null; + if (loadedStringTranslations != null) { + value = loadedStringTranslations.get(name); + } + if (value == null && loadedBackupStrings != null) { + value = loadedBackupStrings.get(name); + } + if (value == null) { + return ""; + } + return value; } /** @@ -115,7 +122,14 @@ public class LanguageLoader { Map currentLanguageValues = load(language); InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); - if (inputStream == null) return; + if (inputStream == null) { + Stargate.log.info("The language " + language + " is not available. You can add a custom language " + + "by creating a new text file in the lang directory."); + if (Stargate.debug) { + Stargate.log.info("Ubabke to load /lang/" + language + ".txt"); + } + return; + } boolean updated = false; FileOutputStream fileOutputStream = null; @@ -238,6 +252,9 @@ public class LanguageLoader { } readLanguageFile(inputStreamReader, strings); } catch (Exception e) { + if (Stargate.debug) { + Stargate.log.info("Unable to load chosen language"); + } return null; } finally { if (fileInputStream != null) { From f97cb3246668eca6cf1ad57f6a6278de974116f7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 14:27:53 +0100 Subject: [PATCH 014/378] Improves messages for the language loader --- .../java/net/knarcraft/stargate/LanguageLoader.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index 6fb7c08..6544b1f 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -59,7 +59,9 @@ public class LanguageLoader { File tmp = new File(languageFolder, chosenLanguage + ".txt"); if (!tmp.exists()) { - tmp.getParentFile().mkdirs(); + if (tmp.getParentFile().mkdirs() && Stargate.debug) { + Stargate.log.info("[stargate] Created language folder"); + } } updateLanguage(chosenLanguage); @@ -123,10 +125,10 @@ public class LanguageLoader { InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); if (inputStream == null) { - Stargate.log.info("The language " + language + " is not available. You can add a custom language " + - "by creating a new text file in the lang directory."); + Stargate.log.info("[stargate] The language " + language + " is not available. Falling back to " + + "english, You can add a custom language by creating a new text file in the lang directory."); if (Stargate.debug) { - Stargate.log.info("Ubabke to load /lang/" + language + ".txt"); + Stargate.log.info("[stargate] Unable to load /lang/" + language + ".txt"); } return; } From e702a0d734759ea58e8e8463dfa4f0e9e2fb0a5b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Feb 2021 14:30:14 +0100 Subject: [PATCH 015/378] Tidies up and comments the economy handler and removes the depreciated method of getting an offline player by username --- .../knarcraft/stargate/EconomyHandler.java | 120 +++++++++++------- .../java/net/knarcraft/stargate/Stargate.java | 18 +-- 2 files changed, 77 insertions(+), 61 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/EconomyHandler.java index 0d4c94f..b8bf120 100644 --- a/src/main/java/net/knarcraft/stargate/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/EconomyHandler.java @@ -9,25 +9,28 @@ import org.bukkit.plugin.RegisteredServiceProvider; import java.util.UUID; -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . +/* + stargate - A portal plugin for Bukkit + Copyright (C) 2011, 2012 Steven "Drakia" Scott + Copyright (C) 2021 Kristian Knarvik +

+ This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +

+ This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. +

+ You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ +/** + * This handler handles economy actions such as payment for using a gate + */ public class EconomyHandler { public static boolean economyEnabled = false; public static Economy economy = null; @@ -40,65 +43,94 @@ public class EconomyHandler { public static boolean chargeFreeDestination = true; public static boolean freeGatesGreen = false; + /** + * Gets the balance (money) of the given player + * @param player

The player to get balance for

+ * @return

The current balance of the player. Returns 0 if economy is disabled

+ */ public static double getBalance(Player player) { - if (!economyEnabled) return 0; - return economy.getBalance(player); - } - - public static boolean chargePlayer(Player player, String target, double amount) { - if (!economyEnabled) return true; - if (player.getName().equals(target)) return true; - if (economy != null) { - if (!economy.has(player, amount)) return false; - economy.withdrawPlayer(player, amount); - economy.depositPlayer(target, amount); + if (economyEnabled) { + return economy.getBalance(player); + } else { + return 0; } - return true; } + /** + * Charges a player, giving the charge to a target + * @param player

The player to charge

+ * @param target

The UUID of the player to pay

+ * @param amount

The amount to charge

+ * @return

True if the payment succeeded, or if no payment was necessary

+ */ public static boolean chargePlayer(Player player, UUID target, double amount) { - if (!economyEnabled) return true; - if (player.getUniqueId().compareTo(target) == 0) return true; - if (economy != null) { - if (!economy.has(player, amount)) return false; + if (economyEnabled && player.getUniqueId().compareTo(target) != 0 && economy != null) { + if (!economy.has(player, amount)) { + return false; + } economy.withdrawPlayer(player, amount); economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); } return true; } + /** + * Charges a player + * @param player

The player to charge

+ * @param amount

The amount to charge

+ * @return

True if the payment succeeded, or if no payment was necessary

+ */ public static boolean chargePlayer(Player player, double amount) { - if (!economyEnabled) return true; - if (economy != null) { - if (!economy.has(player, amount)) return false; + if (economyEnabled && economy != null) { + if (!economy.has(player, amount)) { + return false; + } economy.withdrawPlayer(player, amount); } return true; } - public static String format(int amt) { + /** + * Gets a formatted string for an amount, adding the name of the currency + * @param amount

The amount to display

+ * @return

A formatted text string describing the amount

+ */ + public static String format(int amount) { if (economyEnabled) { - return economy.format(amt); + return economy.format(amount); + } else { + return ""; } - return ""; } - public static boolean setupEconomy(PluginManager pm) { - if (!economyEnabled) return false; + /** + * Sets up economy by initializing vault and the vault economy provider + * @param pluginManager

The plugin manager to get plugins from

+ * @return

True if economy was enabled

+ */ + public static boolean setupEconomy(PluginManager pluginManager) { + if (!economyEnabled) { + return false; + } // Check for Vault - Plugin p = pm.getPlugin("Vault"); - if (p != null && p.isEnabled()) { + Plugin vault = pluginManager.getPlugin("Vault"); + if (vault != null && vault.isEnabled()) { RegisteredServiceProvider economyProvider = Stargate.server.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); if (economyProvider != null) { economy = economyProvider.getProvider(); - vault = p; + EconomyHandler.vault = vault; return true; } } + Stargate.log.info("[stargate] Economy is enabled but vault could not be loaded. Economy disabled"); economyEnabled = false; return false; } + /** + * Gets whether to use economy + * @return

True if the user has turned on economy and economy is available

+ */ public static boolean useEconomy() { return economyEnabled && economy != null; } diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 9079b37..a533912 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -542,18 +542,6 @@ public class Stargate extends JavaPlugin { return portal.isOwner(player) && hasPerm(player, "stargate.destroy.personal"); } - /* - * Charge player for {action} if required, true on success, false if can't afford - */ - public static boolean chargePlayer(Player player, String target, int cost) { - // If cost is 0 - if (cost == 0) return true; - // Economy is disabled - if (!EconomyHandler.useEconomy()) return true; - // Charge player - return EconomyHandler.chargePlayer(player, target, cost); - } - /* * Charge player for {action} if required, true on success, false if can't afford */ @@ -817,11 +805,7 @@ public class Stargate extends JavaPlugin { if (cost > 0) { boolean success; if (portal.getGate().getToOwner()) { - if (portal.getOwnerUUID() == null) { - success = Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = Stargate.chargePlayer(player, portal.getOwnerName(), cost); - } + success = portal.getOwnerUUID() != null && Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); } else { success = Stargate.chargePlayer(player, cost); } From b9cbe9ee4cdd67e6623b4bc879fdc88f7b2992f1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 18:46:30 +0100 Subject: [PATCH 016/378] Makes Vault a soft dependency --- src/main/resources/plugin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2cbb296..9abb4e8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,6 +5,7 @@ description: Stargate mod for Bukkit author: EpicKnarvik97 website: https://knarcraft.net api-version: 1.16 +softdepend: [Vault] commands: sg: description: Used to reload the plugin. Console use only. From 3521257cb2eb208f725d55f42e466478055386c1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 18:46:55 +0100 Subject: [PATCH 017/378] Adds some vault related strings to the english language file --- src/main/resources/lang/en.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/lang/en.txt b/src/main/resources/lang/en.txt index 5227ba7..07a0d07 100644 --- a/src/main/resources/lang/en.txt +++ b/src/main/resources/lang/en.txt @@ -10,6 +10,8 @@ ecoDeduct=Deducted %cost% ecoRefund=Refunded %cost% ecoObtain=Obtained %cost% from Stargate %portal% ecoInFunds=Insufficient Funds +ecoLoadError=Economy is enabled but vault could not be loaded. Economy disabled +vaultLoaded=Vault v%version% found createMsg=Gate Created createNetDeny=You do not have access to that network From 5a8e8a219e39bb64c657a70eb67b78e041ccd04c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 18:47:54 +0100 Subject: [PATCH 018/378] Replaces several static strings with strings from the language files --- .../net/knarcraft/stargate/BungeeCordListener.java | 4 ++-- .../net/knarcraft/stargate/EconomyHandler.java | 2 +- src/main/java/net/knarcraft/stargate/Portal.java | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/BungeeCordListener.java index b4e4c43..2737a34 100644 --- a/src/main/java/net/knarcraft/stargate/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/BungeeCordListener.java @@ -40,7 +40,7 @@ public class BungeeCordListener implements PluginMessageListener { Portal destinationPortal = Portal.getBungeeGate(destination); // Specified an invalid gate. For now we'll just let them connect at their current location if (destinationPortal == null) { - Stargate.log.info("[stargate] Bungee gate " + destination + " does not exist"); + Stargate.log.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); return; } destinationPortal.teleport(player, destinationPortal, null); @@ -63,7 +63,7 @@ public class BungeeCordListener implements PluginMessageListener { data = new byte[dataLength]; dataInputStream.readFully(data); } catch (IOException ex) { - Stargate.log.severe("[stargate] Error receiving BungeeCord message"); + Stargate.log.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); ex.printStackTrace(); return null; } diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/EconomyHandler.java index b8bf120..bb593e5 100644 --- a/src/main/java/net/knarcraft/stargate/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/EconomyHandler.java @@ -122,7 +122,7 @@ public class EconomyHandler { return true; } } - Stargate.log.info("[stargate] Economy is enabled but vault could not be loaded. Economy disabled"); + Stargate.log.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); economyEnabled = false; return false; } diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index 7eac5d9..52b996e 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -556,7 +556,7 @@ public class Portal { int back = (isBackwards()) ? -1 : 1; loc = exit.modRelativeLoc(0D, 0D, 1D, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); } else { - Stargate.log.log(Level.WARNING, "[stargate] Missing destination point in .gate file " + gate.getFilename()); + Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); } if (loc != null) { @@ -711,7 +711,7 @@ public class Portal { public final void drawSign() { BlockState state = id.getBlock().getState(); if (!(state instanceof Sign)) { - Stargate.log.warning("[stargate] Sign block is not a Sign object"); + Stargate.log.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); Stargate.debug("Portal::drawSign", "Block: " + id.getBlock().getType() + " @ " + id.getBlock().getLocation()); return; } @@ -1357,7 +1357,7 @@ public class Portal { } String[] split = line.split(":"); if (split.length < 8) { - Stargate.log.info("[stargate] Invalid line - " + l); + Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + l); continue; } String name = split[0]; @@ -1369,7 +1369,7 @@ public class Portal { BlockLocation topLeft = new BlockLocation(world, split[6]); Gate gate = Gate.getGateByName(split[7]); if (gate == null) { - Stargate.log.info("[stargate] Gate layout on line " + l + " does not exist [" + split[7] + "]"); + Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + l + " does not exist [" + split[7] + "]"); continue; } @@ -1427,7 +1427,7 @@ public class Portal { } portal.unregister(false); iter.remove(); - Stargate.log.info("[stargate] Destroying stargate at " + portal.toString()); + Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal.toString()); continue; } } @@ -1439,14 +1439,14 @@ public class Portal { OpenCount++; } } - Stargate.log.info("[stargate] {" + world.getName() + "} Loaded " + portalCount + " stargates with " + OpenCount + " set as always-on"); + Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} Loaded " + portalCount + " stargates with " + OpenCount + " set as always-on"); return true; } catch (Exception e) { Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + db.getName() + ": " + l); e.printStackTrace(); } } else { - Stargate.log.info("[stargate] {" + world.getName() + "} No stargates for world "); + Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); } return false; } From 9ace568047fc08fc6eabd6779c7d361a38b6ecec Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 20:07:56 +0100 Subject: [PATCH 019/378] Fixes garbled text caused by writing, but not reading language files as UTF-8 --- src/main/java/net/knarcraft/stargate/LanguageLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index 6544b1f..b539696 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -189,7 +189,7 @@ public class LanguageLoader { Map currentLanguageValues) throws IOException { boolean updated = false; // Input stuff - InputStreamReader inputStreamReader = new InputStreamReader(inputStream); + InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String line = bufferedReader.readLine(); From cdae2d8f3581ba36bb44efb5dd57dcf4c6146765 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 20:08:40 +0100 Subject: [PATCH 020/378] Adds language strings related to loading Vault --- src/main/resources/lang/en.txt | 3 ++- src/main/resources/lang/nb-no.txt | 3 +++ src/main/resources/lang/nn-no.txt | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/resources/lang/en.txt b/src/main/resources/lang/en.txt index 07a0d07..b2250d5 100644 --- a/src/main/resources/lang/en.txt +++ b/src/main/resources/lang/en.txt @@ -10,7 +10,8 @@ ecoDeduct=Deducted %cost% ecoRefund=Refunded %cost% ecoObtain=Obtained %cost% from Stargate %portal% ecoInFunds=Insufficient Funds -ecoLoadError=Economy is enabled but vault could not be loaded. Economy disabled +ecoLoadError=Vault was loaded, but no economy plugin could be hooked into +vaultLoadError=Economy is enabled but Vault could not be loaded. Economy disabled vaultLoaded=Vault v%version% found createMsg=Gate Created diff --git a/src/main/resources/lang/nb-no.txt b/src/main/resources/lang/nb-no.txt index 22b0d15..72b9320 100644 --- a/src/main/resources/lang/nb-no.txt +++ b/src/main/resources/lang/nb-no.txt @@ -11,6 +11,9 @@ ecoDeduct=Fratrekk %cost% ecoRefund=Refundert %cost% ecoObtain=Fikk %cost% fra Stjerneport %portal% ecoInFunds=Manglende Midler +ecoLoadError=Vault ble lastet inn men ingen brukbar รธkonomi-utvidelse ble funnet +vaultLoadError=ร˜konomi er skrudd pรฅ, men Vault kunne ikke lastes inn. ร˜konomi er skrudd av +vaultLoaded=Vault v%version% funnet createMsg=Port opprettet createNetDeny=Du har ikke tilgang til det nettverket diff --git a/src/main/resources/lang/nn-no.txt b/src/main/resources/lang/nn-no.txt index 62f27fd..98e981b 100644 --- a/src/main/resources/lang/nn-no.txt +++ b/src/main/resources/lang/nn-no.txt @@ -11,6 +11,9 @@ ecoDeduct=Frรฅtrekk %cost% ecoRefund=Refundert %cost% ecoObtain=Mottok %cost% frรฅ Stjerneport %portal% ecoInFunds=Manglande Midlar +ecoLoadError=Vault vart lasta inn men inga brukbar รธkonomi-utviding vart funnen +vaultLoadError=ร˜konomi er skrudd pรฅ, men Vault kunne ikkje lastas inn. ร˜konomi er skrudd av +vaultLoaded=Vault v%version% funnen createMsg=Port oppretta createNetDeny=Du har ikkje tilgang til det nettverket From af6a2537b87dae96c61be21ae1e8e73bff27b0de Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 20:09:49 +0100 Subject: [PATCH 021/378] Adds more information regarding why economy could not be enabled --- src/main/java/net/knarcraft/stargate/EconomyHandler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/EconomyHandler.java index bb593e5..1d7f984 100644 --- a/src/main/java/net/knarcraft/stargate/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/EconomyHandler.java @@ -120,9 +120,12 @@ public class EconomyHandler { economy = economyProvider.getProvider(); EconomyHandler.vault = vault; return true; + } else { + Stargate.log.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); } + } else { + Stargate.log.info(Stargate.getString("prefix") + Stargate.getString("vaultLoadError")); } - Stargate.log.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); economyEnabled = false; return false; } From a5cf1a7cd3cf4bf0cd3e844a103aa8e6dd6dbf50 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 20:10:17 +0100 Subject: [PATCH 022/378] Improves translation rate of info and error strings --- .../java/net/knarcraft/stargate/Stargate.java | 63 +++++++++++++------ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index a533912..39c571e 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -179,8 +179,11 @@ public class Stargate extends JavaPlugin { // Check to see if Economy is loaded yet. if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) - log.info("[stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); + if (EconomyHandler.economy != null) { + String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + log.info(Stargate.getString("prefix") + + replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + } } getServer().getScheduler().scheduleSyncRepeatingTask(this, new StarGateThread(), 0L, 100L); @@ -220,7 +223,7 @@ public class Stargate extends JavaPlugin { try { signColor = ChatColor.valueOf(sc.toUpperCase()); } catch (Exception ignore) { - log.warning("[stargate] You have specified an invalid color in your config.yml. Defaulting to BLACK"); + log.warning(Stargate.getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); signColor = ChatColor.BLACK; } // Debug @@ -247,7 +250,7 @@ public class Stargate extends JavaPlugin { public void loadGates() { Gate.loadGates(gateFolder); - log.info("[stargate] Loaded " + Gate.getGateCount() + " gate layouts"); + log.info(Stargate.getString("prefix") + "Loaded " + Gate.getGateCount() + " gate layouts"); } public void loadAllPortals() { @@ -618,21 +621,38 @@ public class Stargate extends JavaPlugin { private Plugin checkPlugin(Plugin plugin) { if (plugin != null && plugin.isEnabled()) { - log.info("[stargate] Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")"); + log.info(Stargate.getString("prefix") + "Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")"); return plugin; } return null; } - /* - * Parse a given text string and replace the variables + /** + * Replaces a list of variables in a string in the order they are given + * @param input

The input containing the variables

+ * @param search

The variables to replace

+ * @param values

The replacement values

+ * @return

The input string with the search values replaced with the given values

*/ - public static String replaceVars(String format, String[] search, String[] replace) { - if (search.length != replace.length) return ""; - for (int i = 0; i < search.length; i++) { - format = format.replace(search[i], replace[i]); + public static String replaceVars(String input, String[] search, String[] values) { + if (search.length != values.length) { + throw new IllegalArgumentException("The number of search values and replace values do not match."); } - return format; + for (int i = 0; i < search.length; i++) { + input = replaceVars(input, search[i], values[i]); + } + return input; + } + + /** + * Replaces a variable in a string + * @param input

The input containing the variables

+ * @param search

The variable to replace

+ * @param value

The replacement value

+ * @return

The input string with the search replaced with value

+ */ + public static String replaceVars(String input, String search, String value) { + return input.replace(search, value); } private class vListener implements Listener { @@ -860,7 +880,7 @@ public class Stargate extends JavaPlugin { msgData.writeBytes(msg); // Data player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); } catch (IOException ex) { - Stargate.log.severe("[stargate] Error sending BungeeCord teleport packet"); + Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); ex.printStackTrace(); return; } @@ -875,7 +895,7 @@ public class Stargate extends JavaPlugin { player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); bao.reset(); } catch (IOException ex) { - Stargate.log.severe("[stargate] Error sending BungeeCord connect packet"); + Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); ex.printStackTrace(); return; } @@ -1018,7 +1038,7 @@ public class Stargate extends JavaPlugin { if (!Stargate.canDestroy(player, portal)) { denyMsg = "Permission Denied"; // TODO: Change to stargate.getString() deny = true; - Stargate.log.info("[stargate] " + player.getName() + " tried to destroy gate"); + Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); } int cost = Stargate.getDestroyCost(player, portal.getGate()); @@ -1154,14 +1174,16 @@ public class Stargate extends JavaPlugin { @EventHandler public void onPluginEnable(PluginEnableEvent event) { if (EconomyHandler.setupEconomy(getServer().getPluginManager())) { - log.info("[stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); + String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + log.info(Stargate.getString("prefix") + + replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } } @EventHandler public void onPluginDisable(PluginDisableEvent event) { if (event.getPlugin().equals(EconomyHandler.vault)) { - log.info("[stargate] Vault plugin lost."); + log.info(Stargate.getString("prefix") + "Vault plugin lost."); } } } @@ -1233,8 +1255,11 @@ public class Stargate extends JavaPlugin { // Load Economy support if enabled/clear if disabled if (EconomyHandler.economyEnabled && EconomyHandler.economy == null) { if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) - log.info("[stargate] Vault v" + EconomyHandler.vault.getDescription().getVersion() + " found"); + 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) { From 5a9d70f82708be7ab079ae102882a8313bd7f0f9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 20:38:50 +0100 Subject: [PATCH 023/378] Adds a warning against treating BlockLocation as a Location --- src/main/java/net/knarcraft/stargate/BlockLocation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index e8f969b..49d9db2 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -33,7 +33,9 @@ import org.bukkit.block.data.type.WallSign; /** * This class represents a block location * - *

The BlockLocation class is basically a Location with some extra functionality.

+ *

The BlockLocation class is basically a Location with some extra functionality. + * Warning: Because of differences in the equals methods between Location and BlockLocation, a BlockLocation which + * equals another BlockLocation does not necessarily equal the name BlockLocation if treated as a Location.

*/ public class BlockLocation extends Location { From 2bd5bb36cf3b3005aed7c5faf95dff3a73f22003 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 20:40:48 +0100 Subject: [PATCH 024/378] Updates README to account for recent changes --- README.md | 294 +++++++++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index 0d68aad..546f3cc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ Create gates that allow for instant-teleportation between large distances. Gates ## Background This was originally TheDgtl's Bukkit port of the Stargate plugin for hMod by Dinnerbone. -This fork updates it for modern versions of Spigot. +This is a fork of [PseudoKnight's fork](https://github.com/PseudoKnight/Stargate-Bukkit). +This fork's main purpose is to create a clean version of Stargate compliant with Spigot 1.16, even if it means changing the entire project's previous structure. # Permissions ``` @@ -74,9 +75,9 @@ This is the default gate configuration. See the Custom Gate Layout section on ho ### Sign Layout: - Line 1: Gate Name (Max 12 characters) -- Line 2: Destination Name [Optional] (Max 12 characters, used for fixed-gates only) -- Line 3: Network name [Optional] (Max 12 characters) -- Line 4: Options [Optional] : +- Line 2: Destination Name \[Optional] (Max 12 characters, used for fixed-gates only) +- Line 3: Network name \[Optional] (Max 12 characters) +- Line 4: Options \[Optional] : - 'A' for always-on fixed gate - 'H' for hidden networked gate - 'P' for a private gate @@ -170,16 +171,11 @@ permdebug: Whether to show massive permission debug output ``` # Message Customization -It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/chosenLanguage/en.txt. +It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/lang/chosenLanguage.txt. -If a string is removed, or left blank, it will not be shown when the user does the action associated with it. -There are three special cases when it comes to messages, these are: -``` -ecoDeduct=Spent %cost% -ecoRefund=Refunded %cost% -ecoObtain=Obtained %cost% from Stargate %portal% -``` -As you can see, these three strings have %cost% and %portal% variables in them. These variables are fairly self-explanatory. +If a string is removed, or left blank, it will default to the default english string. +There are some special cases when it comes to messages. +When you see %variableName%, you need to keep this part in your string, as it will be replaced with relevant values. The full list of strings is as follows: ``` @@ -188,73 +184,99 @@ teleportMsg=Teleported destroyMsg=Gate Destroyed invalidMsg=Invalid Destination blockMsg=Destination Blocked -denyMsg=Access Denied destEmpty=Destination List Empty +denyMsg=Access Denied ecoDeduct=Deducted %cost% -ecoRefund=Redunded %cost% +ecoRefund=Refunded %cost% ecoObtain=Obtained %cost% from Stargate %portal% ecoInFunds=Insufficient Funds +ecoLoadError=Vault was loaded, but no economy plugin could be hooked into +vaultLoadError=Economy is enabled but Vault could not be loaded. Economy disabled +vaultLoaded=Vault v%version% found createMsg=Gate Created createNetDeny=You do not have access to that network +createGateDeny=You do not have access to that gate layout createPersonal=Creating gate on personal network createNameLength=Name too short or too long. createExists=A gate by that name already exists createFull=This network is full createWorldDeny=You do not have access to that world createConflict=Gate conflicts with existing gate + +signRightClick=Right click +signToUse=to use gate +signRandom=Random +signDisconnected=Disconnected + +bungeeDisabled=BungeeCord support is disabled. +bungeeDeny=You do not have permission to create BungeeCord gates. +bungeeEmpty=BungeeCord gates require both a destination and network. +bungeeSign=Teleport to ``` # Changes -#### [Version 0.8.0.3] PseudoKnight fork +#### \[Version 0.9.0.0] (WIP) EpicKnarvik97 fork + - Changes entire path structure to a more modern and maven-compliant one + - Changes package structure to net.knarcaft.stargate.* + - Moves language files into the resources folder + - Fixes some bugs caused by language files not being read as UTF-8 + - Makes Blox into BlockLocation which now extends Location + - Adds JavaDoc to a lot of the code + - Adds Norwegian translation for both Norwegian languages + - Adds missing dependency information to plugin.yml + - Uses text from the language files in more places + - Changes how backup language works, causing english strings to be shown if not available from the chosen language + - Removes some pre-UUID code +#### \[Version 0.8.0.3] PseudoKnight fork - Fix economy - Add custom buttons -#### [Version 0.8.0.2] PseudoKnight fork +#### \[Version 0.8.0.2] PseudoKnight fork - Fix player relative yaw when exiting portal - - Add color code support in chosenLanguage files -#### [Version 0.8.0.1] PseudoKnight fork + - Add color code support in lang files +#### \[Version 0.8.0.1] PseudoKnight fork - Fix slab check for portal exits - Improve material checks for gate configuration -#### [Version 0.8.0.0] PseudoKnight fork +#### \[Version 0.8.0.0] PseudoKnight fork - Update for 1.13/1.14 compatibility. This changes gate layouts to use new material names instead of numeric ids. You need to update your gate layout configs. - Adds "verifyPortals" config option, which sets whether an old stargate's blocks are verified when loaded. - Adds UUID support. (falls back to player names) -#### [Version 0.7.9.11] PseudoKnight fork +#### \[Version 0.7.9.11] PseudoKnight fork - Removed iConomy support. Updated Vault support. Changed setting from "useiconomy" to "useeconomy". - Updated to support Metrics for 1.7.10 -#### [Version 0.7.9.10] +#### \[Version 0.7.9.10] - Fix personal gate permission check for players with mixed-case names -#### [Version 0.7.9.9] +#### \[Version 0.7.9.9] - Remove "Permissions" support, we now only support SuperPerms handlers. -#### [Version 0.7.9.8] +#### \[Version 0.7.9.8] - Make sure buttons stay where they should -#### [Version 0.7.9.7] +#### \[Version 0.7.9.7] - Do the Bungee check after the gate layout check. -#### [Version 0.7.9.6] +#### \[Version 0.7.9.6] - Actually remove the player from the BungeeQueue when they connect. Oops :) - Implement stargate.server nodes - Improve the use of negation. You can now negate networks/worlds/servers while using stargate.use permissions. -#### [Version 0.7.9.5] +#### \[Version 0.7.9.5] - Fixed an issue with portal material not showing up (Oh, that code WAS useful) -#### [Version 0.7.9.4] +#### \[Version 0.7.9.4] - Fixed an issue where water gates broke, oops -#### [Version 0.7.9.3] +#### \[Version 0.7.9.3] - Update BungeeCord integration for b152+ -#### [Version 0.7.9.2] +#### \[Version 0.7.9.2] - Remove my custom sign class. Stupid Bukkit team. - Will work with CB 1.4.5 builds, but now will break randomly due to Bukkit screwup - Update MetricsLite to R6 -#### [Version 0.7.9.1] +#### \[Version 0.7.9.1] - Optimize gate lookup in onPlayerMove - Resolve issue where Stargates would teleport players to the nether -#### [Version 0.7.9.0] +#### \[Version 0.7.9.0] - Added BungeeCord multi-server support (Requires Stargate-Bungee for BungeeCord) - Updated Spanish language file - Added basic plugin metrics via http://mcstats.org/ - Resolve issue where language updating overwrote custom strings -#### [Version 0.7.8.1] +#### \[Version 0.7.8.1] - Resolve issue of language file being overwritten as ANSI instead of UTF8 -#### [Version 0.7.8.0] +#### \[Version 0.7.8.0] - Updated languages to include sign text (Please update any languages you are able!) - Resolved NPE due to Bukkit bug with signs - Resolved issue regarding new getTargetBlock code throwing an exception @@ -263,303 +285,303 @@ createConflict=Gate conflicts with existing gate - Language now has a fallback to English for missing lines (It's the only language I can personally update on release) - Added Spanish (Thanks Manuestaire) and Hungarian (Thanks HPoltergeist) - Added portal.setOwner(String) API -#### [Version 0.7.7.5] +#### \[Version 0.7.7.5] - Resolve issue of right clicking introduced in 1.3.1/2 -#### [Version 0.7.7.4] +#### \[Version 0.7.7.4] - Removed try/catch, it was still segfaulting. - Built against 1.3.1 -#### [Version 0.7.7.3] +#### \[Version 0.7.7.3] - Wrap sign changing in try/catch. Stupid Bukkit -#### [Version 0.7.7.2] +#### \[Version 0.7.7.2] - Load chunk before trying to draw signs - Implement a workaround for BUKKIT-1033 -#### [Version 0.7.7.1] +#### \[Version 0.7.7.1] - Permission checking for 'R'andom gates. - Random now implies AlwaysOn - Added all languages to JAR -#### [Version 0.7.7.0] +#### \[Version 0.7.7.0] - Added 'R'andom option - This still follows the permission rules defined for normal gate usage - Added a bit more debug output -#### [Version 0.7.6.8] +#### \[Version 0.7.6.8] - Hopefully fix backwards gate exiting -#### [Version 0.7.6.7] +#### \[Version 0.7.6.7] - Reload all gates on world unload, this stops gates with invalid destinations being in memory. -#### [Version 0.7.6.6] +#### \[Version 0.7.6.6] - Check move/portal/interact/signchange events for cancellation -#### [Version 0.7.6.5] +#### \[Version 0.7.6.5] - Resolve issue with buttons on glass gates falling off - /sg reload can now be used ingame (stargate.admin.reload permission) -#### [Version 0.7.6.4] +#### \[Version 0.7.6.4] - Move blockBreak to HIGHEST priority, this resolves issues with region protection plugins -#### [Version 0.7.6.3] +#### \[Version 0.7.6.3] - Fixed issue with displaying iConomy prices - iConomy is now hooked on "sg reload" if not already hooked and enabled - iConomy is now unhooked on "sg reload" if hooked and disabled -#### [Version 0.7.6.2] +#### \[Version 0.7.6.2] - Button now activates if gate is opened, allowing redstone interaction - Fixed issue with sign line lengths. All sign text should now fit with color codes. -#### [Version 0.7.6.1] +#### \[Version 0.7.6.1] - Update API for StargateCommand - Resolved issue with block data on explosion - Added signColor option - Added protectEntrance option -#### [Version 0.7.6] +#### \[Version 0.7.6] - Moved gate opening/closing to a Queue/Runnable system to resolve server lag issues with very large gates -#### [Version 0.7.5.11] +#### \[Version 0.7.5.11] - PEX now returns accurate results without requiring use of the bridge. -#### [Version 0.7.5.10] +#### \[Version 0.7.5.10] - Added sortLists options -#### [Version 0.7.5.9] +#### \[Version 0.7.5.9] - Quick event fix for latest dev builds - Fix for sign ClassCastException -#### [Version 0.7.5.8] +#### \[Version 0.7.5.8] - Fixed an exploit with pistons to destroy gates -#### [Version 0.7.5.7] +#### \[Version 0.7.5.7] - Removed SignPost class - Resolved issues with signs in 1.2 -#### [Version 0.7.5.6] +#### \[Version 0.7.5.6] - Quick update to the custom event code, works with R5+ now. -#### [Version 0.7.5.5] +#### \[Version 0.7.5.5] - PEX is built of fail, if we have it, use bridge instead. -#### [Version 0.7.5.4] +#### \[Version 0.7.5.4] - Fix issue with private gates for players with long names -#### [Version 0.7.5.3] +#### \[Version 0.7.5.3] - Added another check for Perm bridges. -#### [Version 0.7.5.2] +#### \[Version 0.7.5.2] - Make sure our timer is stopped on disable - Move Event reg before loading gates to stop portal material vanishing -#### [Version 0.7.5.1] +#### \[Version 0.7.5.1] - Don't create button on failed creation -#### [Version 0.7.5.0] +#### \[Version 0.7.5.0] - Refactored creation code a bit - Added StargateCreateEvent, see Stargate-API for usage. - Added StargateDestroyEvent, see Stargate-API for usage. - Updated Event API to the new standard, please see: http://wiki.bukkit.org/Introduction_to_the_New_Event_System - Added handleVehicles option. - Added 'N'o Network option (Hides the network from the sign) -#### [Version 0.7.4.4] +#### \[Version 0.7.4.4] - Changed the implementation of StargateAccessEvent. - Disable Permissions if version is 2.7.2 (Common version used between bridges) - Fix long-standing bug with hasPermDeep check. Oops. -#### [Version 0.7.4.3] +#### \[Version 0.7.4.3] - Implement StargateAccessEvent, used for bypassing permission checks/denying access to gates. -#### [Version 0.7.4.2] +#### \[Version 0.7.4.2] - stargate.create.personal permission now also allows user to use personal gates -#### [Version 0.7.4.1] +#### \[Version 0.7.4.1] - Quick API update to add player to the activate event -#### [Version 0.7.4.0] +#### \[Version 0.7.4.0] - Fixed issue with non-air closed portal blocks - Added StargatePortalEvent/onStargatePortal event -#### [Version 0.7.3.3] +#### \[Version 0.7.3.3] - Added "ignoreEntrance" option to not check entrance to gate on integrity check (Workaround for snowmen until event is pulled) -#### [Version 0.7.3.2] +#### \[Version 0.7.3.2] - Actually fixed "><" issue with destMemory -#### [Version 0.7.3.1] +#### \[Version 0.7.3.1] - Hopefully fixed "><" issue with destMemory -#### [Version 0.7.3] +#### \[Version 0.7.3] - Lava and water gates no longer destroy on reload - "sg reload" now closes gates before reloading - Added Vault support - Added missing "useiConomy" option in config -#### [Version 0.7.2.1] +#### \[Version 0.7.2.1] - Quick fix for an NPE -#### [Version 0.7.2] +#### \[Version 0.7.2] - Make it so you can still destroy gates in Survival mode -#### [Version 0.7.1] +#### \[Version 0.7.1] - Added destMemory option - Switched to sign.update() as Bukkit implemented my fix - Threw in a catch for a null from location for portal events -#### [Version 0.7.0] +#### \[Version 0.7.0] - Minecraft 1.0.0 support - New FileConfiguration implemented - Stop gates being destroyed on right-click in Creative mode - Fixed signs not updating with a hackish workaround until Bukkit is fixed -#### [Version 0.6.10] +#### \[Version 0.6.10] - Added Register support as opposed to iConomy -#### [Version 0.6.9] - - Added UTF8 support for chosenLanguage files (With or without BOM) -#### [Version 0.6.8] +#### \[Version 0.6.9] + - Added UTF8 support for lang files (With or without BOM) +#### \[Version 0.6.8] - Fixed unmanned carts losing velocity through gates - /sg reload now properly switches languages -#### [Version 0.6.7] - - Added chosenLanguage option +#### \[Version 0.6.7] + - Added lang option - Removed language debug output - - Added German language (chosenLanguage=de) -- Thanks EduardBaer -#### [Version 0.6.6] + - Added German language (lang=de) -- Thanks EduardBaer +#### \[Version 0.6.6] - Added %cost% and %portal% to all eco* messages - Fixed an issue when creating a gate on a network you don't have access to -#### [Version 0.6.5] +#### \[Version 0.6.5] - Moved printed message config to a seperate file - Added permdebug option - Hopefully fix path issues some people were having - Fixed iConomy creation cost - Added 'S'how option for Always-On gates - Added 'stargate.create.gate' permissions -#### [Version 0.6.4] +#### \[Version 0.6.4] - Fixed iConomy handling -#### [Version 0.6.3] +#### \[Version 0.6.3] - Fixed (Not Connected) showing on inter-world gate loading - Added the ability to negate Network/World permissions (Use, Create and Destroy) - Fixed Lockette compatibility - More stringent verification checks -#### [Version 0.6.2] +#### \[Version 0.6.2] - Fixed an issue with private gates - Added default permissions -#### [Version 0.6.1] +#### \[Version 0.6.1] - Stop destruction of open gates on startup -#### [Version 0.6.0] +#### \[Version 0.6.0] - Completely re-wrote Permission handling (REREAD/REDO YOUR PERMISSIONS!!!!!!!!) - Added custom Stargate events (See Stargate-DHD code for use) - Fixed portal event cancellation - Umm... Lots of other small things. -#### [Version 0.5.5] +#### \[Version 0.5.5] - Added 'B'ackwards option - Fixed opening of gates with a fixed gate as a destination - Added block metadata support to gates -#### [Version 0.5.1] +#### \[Version 0.5.1] - Take into account world/network restrictions for Vehicles - Properly teleport empty vehicles between worlds - Properly teleport StoreageMinecarts between worlds - Take into account vehicle type when teleporting -#### [Version 0.5.0] +#### \[Version 0.5.0] - Updated the teleport method - Remove always-open gates from lists - Hopefully stop Stargate and Nether interference -#### [Version 0.4.9] +#### \[Version 0.4.9] - Left-click to scroll signs up - Show "(Not Connected)" on fixed-gates with a non-existant destination - Added "maxgates" option - Removed debug message - Started work on disabling damage for lava gates, too much work to finish with the current implementation of EntityDamageByBlock -#### [Version 0.4.8] +#### \[Version 0.4.8] - Added chargefreedestination option - Added freegatesgreen option -#### [Version 0.4.7] +#### \[Version 0.4.7] - Added debug option - Fixed gates will now show in the list of gates they link to. - iConomy no longer touched if not enabled in config -#### [Version 0.4.6] +#### \[Version 0.4.6] - Fixed a bug in iConomy handling. -#### [Version 0.4.5] +#### \[Version 0.4.5] - Owner of gate now isn't charged for use if target is owner - Updated for iConomy 5.x - Fixed random iConomy bugs -#### [Version 0.4.4] +#### \[Version 0.4.4] - Added a check for stargate.network.*/stargate.world.* on gate creation - Check for stargate.world.*/stargate.network.* on gate entrance - Warp player outside of gate on access denied -#### [Version 0.4.3] +#### \[Version 0.4.3] - Made some errors more user-friendly - Properly take into account portal-closed material -#### [Version 0.4.2] +#### \[Version 0.4.2] - Gates can't be created on existing gate blocks -#### [Version 0.4.1] +#### \[Version 0.4.1] - Sign option permissions - Per-gate iconomy target - /sg reload command - Other misc fixes -#### [Version 0.4.0] +#### \[Version 0.4.0] - Carts with no player can now go through gates. - You can set gates to send their cost to their owner. - Per-gate layout option for "toOwner". - Cleaned up the iConomy code a bit, messages should only be shown on actual deduction now. - Created separate 'stargate.free.{use/create/destroy}' permissions. -#### [Version 0.3.5] +#### \[Version 0.3.5] - Added 'stargate.world.*' permissions - Added 'stargate.network.*' permissions - Added 'networkfilter' config option - Added 'worldfilter' config option -#### [Version 0.3.4] +#### \[Version 0.3.4] - Added 'stargate.free' permission - Added iConomy cost into .gate files -#### [Version 0.3.3] +#### \[Version 0.3.3] - Moved sign update into a schedule event, should fix signs -#### [Version 0.3.2] +#### \[Version 0.3.2] - Updated to latest RB - Implemented proper vehicle handling - Added iConomy to vehicle handling - Can now set cost to go to creator on use -#### [Version 0.3.1] +#### \[Version 0.3.1] - Changed version numbering. - Changed how plugins are hooked into. -#### [Version 0.30] +#### \[Version 0.30] - Fixed a bug in iConomy checking. -#### [Version 0.29] +#### \[Version 0.29] - Added iConomy support. Currently only works with iConomy 4.4 until Niji fixes 4.5 - Thanks @Jonbas for the base iConomy implementation -#### [Version 0.28] +#### \[Version 0.28] - Fixed an issue with removing stargates during load -#### [Version 0.27] +#### \[Version 0.27] - Fixed portal count on load -#### [Version 0.26] +#### \[Version 0.26] - Added stargate.create.personal for personal stargate networks - Fixed a bug with destroying stargates by removing sign/button -#### [Version 0.25] +#### \[Version 0.25] - Fixed a bug with worlds in subfolders - Fixed gates being destroyed with explosions - Added stargate.destroy.owner -#### [Version 0.24] +#### \[Version 0.24] - Fixed a loading bug in which invalid gates caused file truncation -#### [Version 0.23] +#### \[Version 0.23] - Added a check to make sure "nethergate.gate" exists, otherwise create it -#### [Version 0.22] +#### \[Version 0.22] - Fixed multi-world stargates causing an NPE -#### [Version 0.21] +#### \[Version 0.21] - Code cleanup - Added a few more errors when a gate can't be loaded - Hopefully fixed path issue on some Linux installs -#### [Version 0.20] +#### \[Version 0.20] - Fixed the bug SIGN_CHANGE exception when using plugins such as Lockette -#### [Version 0.19] +#### \[Version 0.19] - Set button facing on new gates, fixes weirdass button glitch - Beginning of very buggy multi-world support -#### [Version 0.18] +#### \[Version 0.18] - Small permissions handling update. -#### [Version 0.17] +#### \[Version 0.17] - Core GM support removed, depends on FakePermissions if you use GM. -#### [Version 0.16] +#### \[Version 0.16] - Fixed Permissions, will work with GroupManager, Permissions 2.0, or Permissions 2.1 - Left-clicking to activate a stargate works again -#### [Version 0.15] +#### \[Version 0.15] - Built against b424jnks -- As such nothing lower is supported at the moment. - Moved gate destruction code to onBlockBreak since onBlockDamage no longer handles breaking blocks. - Removed long constructor. -#### [Version 0.14] +#### \[Version 0.14] - Fixed infinite loop in fixed gates. - Fixed gate destination will not open when dialed into. -#### [Version 0.13] +#### \[Version 0.13] - Fixed gates no longer show in destination list. -#### [Version 0.12] +#### \[Version 0.12] - Implemented fixed destination block using * in .gate file. This is the recommended method of doing an exit point for custom gates, as the automatic method doesn't work in a lot of cases. - Split networks up in memory, can now use same name in different networks. As a result, fixed gates must now specify a network. - Added the ability to have a private gate, which only you can activate. Use the 'P' option to create. - Fixed but not AlwaysOn gates now open the destination gate. - Fixed gates now show their network. Existing fixed gates are added to the default network (Sorry! It had to be done) -#### [Version 0.11] +#### \[Version 0.11] - Fuuuu- Some code got undid and broke everything. Fixed. -#### [Version 0.10] +#### \[Version 0.10] - Hopefully fixed the "No position found" bug. - If dest > origin, any blocks past origin.size will drop you at dest[0] - Switched to scheduler instead of our own thread for closing gates and deactivating signs - No longer depend on Permissions, use it as an option. isOp() used as defaults. -#### [Version 0.09] +#### \[Version 0.09] - Gates can now be any shape -#### [Version 0.08] +#### \[Version 0.08] - Gates can now consist of any material. - You can left or right click the button to open a gate - Gates are now initialized on sign placement, not more right clicking! -#### [Version 0.07] +#### \[Version 0.07] - Fixed where the default gate is saved to. -#### [Version 0.06] +#### \[Version 0.06] - Forgot to make gates load from new location, oops -#### [Version 0.05] +#### \[Version 0.05] - Moved Stargate files into the plugins/Stargate/ folder - Added migration code so old gates/portals are ported to new folder structure - Create default config.yml if it doesn't exist - Fixed removing a gate, it is now completely removed -#### [Version 0.04] +#### \[Version 0.04] - Updated to multi-world Bukkit -#### [Version 0.03] - - Changed package to net.knarcraft.* +#### \[Version 0.03] + - Changed package to net.TheDgtl.* - Everything now uses Blox instead of Block objects - - Started on vehicle code, but it's still buggy + - Started on vehicle code, but it's still buggy \ No newline at end of file From 68f3bca04f56c876ee938b77c5c5f286209f6a8f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 21:11:22 +0100 Subject: [PATCH 025/378] Adds MockBukkit and JUnit dependencies for testing --- pom.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8c6a88e..26dfd7b 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,19 @@ VaultAPI 1.7 - + + org.junit.jupiter + junit-jupiter-api + RELEASE + test + + + com.github.seeseemelk + MockBukkit-v1.16 + 0.24.0 + test + + src/main/java From b6d18a421770618b6bc467d66ab53ded3eae5616 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 21:12:04 +0100 Subject: [PATCH 026/378] Adds an extra constructor to Stargate required for testing --- .../java/net/knarcraft/stargate/Stargate.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 39c571e..441c24d 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -45,6 +45,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPluginLoader; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; @@ -128,6 +129,21 @@ public class Stargate extends JavaPlugin { // World names that contain stargates public static HashSet managedWorlds = new HashSet<>(); + public Stargate() { + super(); + } + + /** + * Special constructor used for MockBukkit + * @param loader

The plugin loader to be used.

+ * @param descriptionFile

The description file to be used.

+ * @param dataFolder

The data folder to be used.

+ * @param file

The file to be used

+ */ + protected Stargate(JavaPluginLoader loader, PluginDescriptionFile descriptionFile, File dataFolder, File file) { + super(loader, descriptionFile, dataFolder, file); + } + @Override public void onDisable() { Portal.closeAllGates(); From 32410a82ba7917bf7a0c9325400c72a28139eeeb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 21:12:43 +0100 Subject: [PATCH 027/378] Adds some tests for the equals method of BlockLocationTest --- .../knarcraft/stargate/BlockLocationTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/test/java/net/knarcraft/stargate/BlockLocationTest.java diff --git a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java new file mode 100644 index 0000000..bc603f6 --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java @@ -0,0 +1,62 @@ +package net.knarcraft.stargate; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.WorldMock; +import org.bukkit.Material; +import org.junit.After; +import org.junit.Before; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class BlockLocationTest { + private WorldMock mockWorld; + + @Before + public void setUp() { + mockWorld = new WorldMock(Material.DIRT, 5); + } + + @After + public void tearDown() + { + MockBukkit.unmock(); + } + + @Test + public void equalsTest() { + BlockLocation location1 = new BlockLocation(mockWorld, 1, 3, 4); + BlockLocation location2 = new BlockLocation(mockWorld, 1, 3, 4); + assertEquals(location1, location2); + } + + @Test + public void notEqualsTest1() { + BlockLocation location1 = new BlockLocation(mockWorld, 1, 3, 4); + BlockLocation location2 = new BlockLocation(mockWorld, 2, 3, 4); + assertNotEquals(location1, location2); + } + + @Test + public void notEqualsTest2() { + BlockLocation location1 = new BlockLocation(mockWorld, 1, 3, 4); + BlockLocation location2 = new BlockLocation(mockWorld, 1, 5, 4); + assertNotEquals(location1, location2); + } + + @Test + public void notEqualsTest3() { + BlockLocation location1 = new BlockLocation(mockWorld, 1, 3, 4); + BlockLocation location2 = new BlockLocation(mockWorld, 1, 3, 7); + assertNotEquals(location1, location2); + } + + @Test + public void notEqualsTest4() { + BlockLocation location1 = new BlockLocation(mockWorld, 1, 3, 4); + BlockLocation location2 = new BlockLocation(new WorldMock(Material.DIRT, 4), 1, 3, 4); + assertNotEquals(location1, location2); + } + +} From f0a7ff8c474cb4bf73801c7c463e2e575486db8a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Feb 2021 23:25:52 +0100 Subject: [PATCH 028/378] Adds more BlockLocation tests --- .../knarcraft/stargate/BlockLocationTest.java | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java index bc603f6..72b64c9 100644 --- a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java +++ b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java @@ -4,7 +4,7 @@ import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.WorldMock; import org.bukkit.Material; import org.junit.After; -import org.junit.Before; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -13,14 +13,13 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; public class BlockLocationTest { private WorldMock mockWorld; - @Before + @BeforeEach public void setUp() { mockWorld = new WorldMock(Material.DIRT, 5); } @After - public void tearDown() - { + public void tearDown() { MockBukkit.unmock(); } @@ -59,4 +58,27 @@ public class BlockLocationTest { assertNotEquals(location1, location2); } + @Test + public void makeRelativeTest() { + BlockLocation location = new BlockLocation(mockWorld, 3, 7, 19); + BlockLocation newLocation = location.makeRelative(34, 65, 75); + assertEquals(37, newLocation.getBlockX()); + assertEquals(72, newLocation.getBlockY()); + assertEquals(94, newLocation.getBlockZ()); + } + + @Test + public void materialTest() { + BlockLocation location = new BlockLocation(mockWorld, 0, 0, 0); + assertNotEquals(Material.BOOKSHELF, location.getType()); + location.setType(Material.BOOKSHELF); + assertEquals(Material.BOOKSHELF, location.getType()); + } + + @Test + public void toStringTest() { + BlockLocation location = new BlockLocation(mockWorld, 56, 87, 34); + assertEquals("56,87,34", location.toString()); + } + } From a8c0574f3b5feb950bb56a45fa29ef006128d4ef Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 02:17:49 +0100 Subject: [PATCH 029/378] Adds other authors to plugin.yml --- src/main/resources/plugin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9abb4e8..106637f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,6 +3,7 @@ main: net.knarcraft.stargate.Stargate version: 0.9.0.0 description: Stargate mod for Bukkit author: EpicKnarvik97 +authors: [Drakia, PseudoKnight, EpicKnarvik97] website: https://knarcraft.net api-version: 1.16 softdepend: [Vault] From e49b94cf9a977e6f581777ff2fa9270f87ad5d9d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 02:19:48 +0100 Subject: [PATCH 030/378] Adds a class for helping to decide if a material is a wall coral (dead or alive) --- .../knarcraft/stargate/MaterialHelper.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/MaterialHelper.java diff --git a/src/main/java/net/knarcraft/stargate/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/MaterialHelper.java new file mode 100644 index 0000000..808c774 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/MaterialHelper.java @@ -0,0 +1,25 @@ +package net.knarcraft.stargate; + +import org.bukkit.Material; +import org.bukkit.Tag; + +/** + * This class helps decide properties of materials not already present in the Spigot API + */ +public class MaterialHelper { + + /** + * Checks whether the given material is a dead or alive wall coral + * @param material

The material to check

+ * @return

True if the material is a wall coral

+ */ + public static boolean isWallCoral(Material material) { + return Tag.WALL_CORALS.isTagged(material) || + material.equals(Material.DEAD_BRAIN_CORAL_WALL_FAN) || + material.equals(Material.DEAD_BUBBLE_CORAL_WALL_FAN) || + material.equals(Material.DEAD_FIRE_CORAL_WALL_FAN) || + material.equals(Material.DEAD_HORN_CORAL_WALL_FAN) || + material.equals(Material.DEAD_TUBE_CORAL_WALL_FAN); + } + +} From 7b9f5a6de515bebd0491be0e3a6ec51fa8dbe393 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 02:20:50 +0100 Subject: [PATCH 031/378] Adds underwater portal support using any wall coral as a button replacement --- .../java/net/knarcraft/stargate/Gate.java | 52 ++- .../stargate/PlayerEventsListener.java | 303 ++++++++++++++++++ .../java/net/knarcraft/stargate/Portal.java | 70 ++-- .../java/net/knarcraft/stargate/Stargate.java | 280 +--------------- 4 files changed, 397 insertions(+), 308 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/PlayerEventsListener.java diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index 30b4812..4a41ae5 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -7,7 +7,6 @@ import org.bukkit.block.Block; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; -import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -400,7 +399,7 @@ public class Gate { return null; } - if (!Tag.BUTTONS.isTagged(gate.button)) { + if (!Tag.BUTTONS.isTagged(gate.button) && !MaterialHelper.isWallCoral(gate.button)) { Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gate button must be a type of button."); return null; } @@ -435,28 +434,39 @@ public class Gate { return def; } + /** + * Loads all gates inside the given folder + * @param gateFolder

The folder containing the gates

+ */ public static void loadGates(String gateFolder) { - File dir = new File(gateFolder); + File directory = new File(gateFolder); File[] files; - if (dir.exists()) { - files = dir.listFiles(new StargateFilenameFilter()); + if (directory.exists()) { + files = directory.listFiles((file) -> file.isFile() && file.getName().endsWith(".gate")); } else { files = new File[0]; } if (files == null || files.length == 0) { - if (dir.mkdir()) { + //The gates folder was not found. Assume this is the first run + if (directory.mkdir()) { populateDefaults(gateFolder); } } else { for (File file : files) { Gate gate = loadGate(file); - if (gate != null) registerGate(gate); + if (gate != null) { + registerGate(gate); + } } } } + /** + * Writes the default gate specification to the given folder + * @param gateFolder

The folder containing gate config files

+ */ public static void populateDefaults(String gateFolder) { Character[][] layout = new Character[][]{ {' ', 'X', 'X', ' '}, @@ -485,32 +495,46 @@ public class Gate { Gate[] result = new Gate[0]; ArrayList lookup = controlBlocks.get(type); - if (lookup != null) result = lookup.toArray(result); + if (lookup != null) { + result = lookup.toArray(result); + } return result; } + /** + * Gets a portal by its name (filename before .gate) + * @param name

The name of the gate to get

+ * @return

The gate with the given name

+ */ public static Gate getGateByName(String name) { return gates.get(name); } + /** + * Gets the number of loaded gate configurations + * @return

The number of loaded gate configurations

+ */ public static int getGateCount() { return gates.size(); } + /** + * Checks whether the given material is used for the frame of any portals + * @param type

The material type to check

+ * @return

True if the material is used for the frame of at least one portal

+ */ public static boolean isGateBlock(Material type) { return frameBlocks.contains(type); } - static class StargateFilenameFilter implements FilenameFilter { - public boolean accept(File dir, String name) { - return name.endsWith(".gate"); - } - } - + /** + * Clears all loaded gates + */ public static void clearGates() { gates.clear(); controlBlocks.clear(); frameBlocks.clear(); } + } diff --git a/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java new file mode 100644 index 0000000..8360047 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java @@ -0,0 +1,303 @@ +package net.knarcraft.stargate; + +import org.bukkit.GameMode; +import org.bukkit.Tag; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class PlayerEventsListener implements Listener { + + private static long eventTime; + private static PlayerInteractEvent previousEvent; + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (!Stargate.enableBungee) { + return; + } + + Player player = event.getPlayer(); + String destination = Stargate.bungeeQueue.remove(player.getName().toLowerCase()); + if (destination == null) { + return; + } + + Portal portal = Portal.getBungeeGate(destination); + if (portal == null) { + Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); + return; + } + portal.teleport(player, portal, null); + } + + @EventHandler + 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()) + && Portal.getByAdjacentEntrance(event.getFrom()) != null) { + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + 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()) { + return; + } + + Player player = event.getPlayer(); + Portal portal = Portal.getByEntrance(event.getTo()); + // No portal or not open + if (portal == null || !portal.isOpen()) return; + + // Not open for this player + if (!portal.isOpenFor(player)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + portal.teleport(player, portal, event); + return; + } + + Portal destination = portal.getDestination(player); + if (!portal.isBungee() && destination == null) return; + + boolean deny = false; + // Check if player has access to this server for Bungee gates + if (portal.isBungee()) { + if (!Stargate.canAccessServer(player, portal.getNetwork())) { + deny = true; + } + } else { + // Check if player has access to this network + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + // Check if player has access to destination world + if (!Stargate.canAccessWorld(player, destination.getWorld().getName())) { + deny = true; + } + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + portal.teleport(player, portal, event); + portal.close(false); + return; + } + + int cost = Stargate.getUseCost(player, portal, destination); + if (cost > 0) { + boolean success; + if (portal.getGate().getToOwner()) { + success = portal.getOwnerUUID() != null && Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); + } else { + success = Stargate.chargePlayer(player, cost); + } + if (!success) { + // Insufficient Funds + Stargate.sendMessage(player, Stargate.getString("inFunds")); + portal.close(false); + return; + } + String deductMsg = Stargate.getString("ecoDeduct"); + deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); + Stargate.sendMessage(player, deductMsg, false); + if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) { + Player p; + if (portal.getOwnerUUID() != null) { + p = Stargate.server.getPlayer(portal.getOwnerUUID()); + } else { + p = Stargate.server.getPlayer(portal.getOwnerName()); + } + if (p != null) { + String obtainedMsg = Stargate.getString("ecoObtain"); + obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); + Stargate.sendMessage(p, obtainedMsg, false); + } + } + } + + Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + + // BungeeCord Support + if (portal.isBungee()) { + if (!Stargate.enableBungee) { + player.sendMessage(Stargate.getString("bungeeDisabled")); + portal.close(false); + return; + } + + // Teleport the player back to this gate, for sanity's sake + portal.teleport(player, portal, 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() + "#@#" + portal.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(portal.getNetwork()); // Server + msgData.writeUTF("SGBungee"); // Channel + msgData.writeShort(msg.length()); // Data Length + msgData.writeBytes(msg); // Data + player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray()); + } catch (IOException ex) { + Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); + ex.printStackTrace(); + return; + } + + // Connect player to new server + try { + ByteArrayOutputStream bao = new ByteArrayOutputStream(); + DataOutputStream msgData = new DataOutputStream(bao); + msgData.writeUTF("Connect"); + msgData.writeUTF(portal.getNetwork()); + + player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray()); + bao.reset(); + } catch (IOException ex) { + Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); + ex.printStackTrace(); + return; + } + + // Close portal if required (Should never be) + portal.close(false); + return; + } + + destination.teleport(player, portal, event); + portal.close(false); + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + + if (block == null) { + return; + } + + // Right click + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (block.getBlockData() instanceof WallSign) { + Portal portal = Portal.getByBlock(block); + if (portal == null) { + return; + } + // Cancel item use + event.setUseItemInHand(Event.Result.DENY); + event.setUseInteractedBlock(Event.Result.DENY); + + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + if ((!portal.isOpen()) && (!portal.isFixed())) { + portal.cycleDestination(player); + } + return; + } + + // Implement right-click to toggle a stargate, gets around spawn protection problem. + if (Tag.BUTTONS.isTagged(block.getType()) || MaterialHelper.isWallCoral(block.getType())) { + + if (MaterialHelper.isWallCoral(block.getType())) { + if (previousEvent != null && + event.getPlayer() == previousEvent.getPlayer() && eventTime + 10 > System.currentTimeMillis()) { + previousEvent = null; + eventTime = 0; + return; + } + previousEvent = event; + eventTime = System.currentTimeMillis(); + } + + Portal portal = Portal.getByBlock(block); + if (portal == null) { + return; + } + + // Cancel item use + event.setUseItemInHand(Event.Result.DENY); + event.setUseInteractedBlock(Event.Result.DENY); + + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + Stargate.openPortal(player, portal); + if (portal.isOpenFor(player)) { + event.setUseInteractedBlock(Event.Result.ALLOW); + } + } + return; + } + + // Left click + if (event.getAction() == Action.LEFT_CLICK_BLOCK) { + // Check if we're scrolling a sign + if (block.getBlockData() instanceof WallSign) { + Portal portal = Portal.getByBlock(block); + if (portal == null) return; + + event.setUseInteractedBlock(Event.Result.DENY); + // Only cancel event in creative mode + if (player.getGameMode().equals(GameMode.CREATIVE)) { + event.setCancelled(true); + } + + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + if ((!portal.isOpen()) && (!portal.isFixed())) { + portal.cycleDestination(player, -1); + } + } + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index 52b996e..c6f665d 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -911,7 +911,9 @@ public class Portal { return null; } - if (Gate.getGatesByControlBlock(idParent).length == 0) return null; + if (Gate.getGatesByControlBlock(idParent).length == 0) { + return null; + } if (Portal.getByBlock(idParent) != null) { Stargate.debug("createPortal", "idParent belongs to existing gate"); @@ -924,6 +926,7 @@ public class Portal { String destName = 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); @@ -935,14 +938,30 @@ public class Portal { boolean bungee = (options.indexOf('u') != -1); // Check permissions for options. - if (hidden && !Stargate.canOption(player, "hidden")) hidden = false; - if (alwaysOn && !Stargate.canOption(player, "alwayson")) alwaysOn = false; - if (priv && !Stargate.canOption(player, "private")) priv = false; - if (free && !Stargate.canOption(player, "free")) free = false; - if (backwards && !Stargate.canOption(player, "backwards")) backwards = false; - if (show && !Stargate.canOption(player, "show")) show = false; - if (noNetwork && !Stargate.canOption(player, "nonetwork")) noNetwork = false; - if (random && !Stargate.canOption(player, "random")) random = false; + if (hidden && !Stargate.canOption(player, "hidden")) { + hidden = false; + } + if (alwaysOn && !Stargate.canOption(player, "alwayson")) { + alwaysOn = false; + } + if (priv && !Stargate.canOption(player, "private")) { + priv = false; + } + if (free && !Stargate.canOption(player, "free")) { + free = false; + } + if (backwards && !Stargate.canOption(player, "backwards")) { + backwards = false; + } + if (show && !Stargate.canOption(player, "show")) { + show = false; + } + if (noNetwork && !Stargate.canOption(player, "nonetwork")) { + noNetwork = false; + } + if (random && !Stargate.canOption(player, "random")) { + random = false; + } // Can not create a non-fixed always-on gate. if (alwaysOn && destName.length() == 0) { @@ -995,28 +1014,29 @@ public class Portal { RelativeBlockVector buttonVector = null; for (Gate possibility : possibleGates) { - if ((gate == null) && (buttonVector == null)) { - RelativeBlockVector[] vectors = possibility.getControls(); - RelativeBlockVector otherControl = null; + if (gate != null || buttonVector != null) { + break; + } + RelativeBlockVector[] vectors = possibility.getControls(); + RelativeBlockVector otherControl = null; - for (RelativeBlockVector vector : vectors) { - BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); + for (RelativeBlockVector vector : vectors) { + BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); - if (gate == null) { - if (possibility.matches(tl, modX, modZ, true)) { - gate = possibility; - topleft = tl; + if (gate == null) { + if (possibility.matches(tl, modX, modZ, true)) { + gate = possibility; + topleft = tl; - if (otherControl != null) { - buttonVector = otherControl; - } + if (otherControl != null) { + buttonVector = otherControl; } - } else if (otherControl != null) { - buttonVector = vector; } - - otherControl = vector; + } else if (otherControl != null) { + buttonVector = vector; } + + otherControl = vector; } } diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 441c24d..68c98ca 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -4,7 +4,6 @@ import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.event.StargateDestroyEvent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.Tag; @@ -20,11 +19,9 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; -import org.bukkit.event.Event.Result; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockPhysicsEvent; @@ -32,10 +29,6 @@ import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.event.vehicle.VehicleMoveEvent; @@ -47,10 +40,7 @@ import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; import java.io.File; -import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -170,7 +160,7 @@ public class Stargate extends JavaPlugin { log.info(pdfFile.getName() + " v." + pdfFile.getVersion() + " is enabled."); // Register events before loading gates to stop weird things happening. - pm.registerEvents(new pListener(), this); + pm.registerEvents(new PlayerEventsListener(), this); pm.registerEvents(new bListener(), this); pm.registerEvents(new vListener(), this); @@ -759,273 +749,25 @@ public class Stargate extends JavaPlugin { } } - private class pListener implements Listener { - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - if (!enableBungee) return; - Player player = event.getPlayer(); - String destination = bungeeQueue.remove(player.getName().toLowerCase()); - if (destination == null) return; - - Portal portal = Portal.getBungeeGate(destination); - if (portal == null) { - Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); - return; - } - portal.teleport(player, portal, null); - } - - @EventHandler - 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()) - && Portal.getByAdjacentEntrance(event.getFrom()) != null) { - event.setCancelled(true); - } - } - - @EventHandler - public void onPlayerMove(PlayerMoveEvent event) { - 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()) { - return; - } - - Player player = event.getPlayer(); - Portal portal = Portal.getByEntrance(event.getTo()); - // No portal or not open - if (portal == null || !portal.isOpen()) return; - - // Not open for this player - if (!portal.isOpenFor(player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.teleport(player, portal, event); - return; - } - - Portal destination = portal.getDestination(player); - if (!portal.isBungee() && destination == null) return; - - boolean deny = false; - // Check if player has access to this server for Bungee gates - if (portal.isBungee()) { - if (!canAccessServer(player, portal.getNetwork())) { - deny = true; - } - } else { - // Check if player has access to this network - if (!canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - // Check if player has access to destination world - if (!canAccessWorld(player, destination.getWorld().getName())) { - deny = true; - } - } - - if (!canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.teleport(player, portal, event); - portal.close(false); - return; - } - - int cost = Stargate.getUseCost(player, portal, destination); - if (cost > 0) { - boolean success; - if (portal.getGate().getToOwner()) { - success = portal.getOwnerUUID() != null && Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = Stargate.chargePlayer(player, cost); - } - if (!success) { - // Insufficient Funds - Stargate.sendMessage(player, Stargate.getString("inFunds")); - portal.close(false); - return; - } - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) { - Player p; - if (portal.getOwnerUUID() != null) { - p = server.getPlayer(portal.getOwnerUUID()); - } else { - p = server.getPlayer(portal.getOwnerName()); - } - if (p != null) { - String obtainedMsg = Stargate.getString("ecoObtain"); - obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); - Stargate.sendMessage(p, obtainedMsg, false); - } - } - } - - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - - // BungeeCord Support - if (portal.isBungee()) { - if (!enableBungee) { - player.sendMessage(Stargate.getString("bungeeDisabled")); - portal.close(false); - return; - } - - // Teleport the player back to this gate, for sanity's sake - portal.teleport(player, portal, 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() + "#@#" + portal.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(portal.getNetwork()); // Server - msgData.writeUTF("SGBungee"); // Channel - msgData.writeShort(msg.length()); // Data Length - msgData.writeBytes(msg); // Data - player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); - } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); - ex.printStackTrace(); - return; - } - - // Connect player to new server - try { - ByteArrayOutputStream bao = new ByteArrayOutputStream(); - DataOutputStream msgData = new DataOutputStream(bao); - msgData.writeUTF("Connect"); - msgData.writeUTF(portal.getNetwork()); - - player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray()); - bao.reset(); - } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); - ex.printStackTrace(); - return; - } - - // Close portal if required (Should never be) - portal.close(false); - return; - } - - destination.teleport(player, portal, event); - portal.close(false); - } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - Player player = event.getPlayer(); - Block block = event.getClickedBlock(); - - if (block == null) return; - - // Right click - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (block.getBlockData() instanceof WallSign) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; - // Cancel item use - event.setUseItemInHand(Result.DENY); - event.setUseInteractedBlock(Result.DENY); - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - if ((!portal.isOpen()) && (!portal.isFixed())) { - portal.cycleDestination(player); - } - return; - } - - // Implement right-click to toggle a stargate, gets around spawn protection problem. - if (Tag.BUTTONS.isTagged(block.getType())) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; - - // Cancel item use - event.setUseItemInHand(Result.DENY); - event.setUseInteractedBlock(Result.DENY); - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - openPortal(player, portal); - if (portal.isOpenFor(player)) { - event.setUseInteractedBlock(Result.ALLOW); - } - } - return; - } - - // Left click - if (event.getAction() == Action.LEFT_CLICK_BLOCK) { - // Check if we're scrolling a sign - if (block.getBlockData() instanceof WallSign) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; - - event.setUseInteractedBlock(Result.DENY); - // Only cancel event in creative mode - if (player.getGameMode().equals(GameMode.CREATIVE)) { - event.setCancelled(true); - } - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - if ((!portal.isOpen()) && (!portal.isFixed())) { - portal.cycleDestination(player, -1); - } - } - } - } - } private class bListener implements Listener { @EventHandler public void onSignChange(SignChangeEvent event) { - if (event.isCancelled()) return; + if (event.isCancelled()) { + return; + } Player player = event.getPlayer(); Block block = event.getBlock(); - if (!(block.getBlockData() instanceof WallSign)) return; + if (!(block.getBlockData() instanceof WallSign)) { + return; + } final Portal portal = Portal.createPortal(event, player); // Not creating a gate, just placing a sign - if (portal == null) return; + if (portal == null) { + return; + } Stargate.sendMessage(player, Stargate.getString("createMsg"), false); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); @@ -1104,7 +846,7 @@ public class Stargate extends JavaPlugin { // Handle keeping portal material and buttons around if (block.getType() == Material.NETHER_PORTAL) { portal = Portal.getByEntrance(block); - } else if (Tag.BUTTONS.isTagged(block.getType())) { + } else if (Tag.BUTTONS.isTagged(block.getType()) || MaterialHelper.isWallCoral(block.getType())) { portal = Portal.getByControl(block); } if (portal != null) event.setCancelled(true); From 095e59c65ee4d80113a3b0dec12b169d7a710808 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 03:29:28 +0100 Subject: [PATCH 032/378] Makes it easier to use any compatible block as a button --- README.md | 13 ++++++++++++- src/main/java/net/knarcraft/stargate/Gate.java | 3 +-- .../java/net/knarcraft/stargate/MaterialHelper.java | 10 ++++++++++ .../knarcraft/stargate/PlayerEventsListener.java | 3 +-- src/main/java/net/knarcraft/stargate/Stargate.java | 3 +-- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 546f3cc..210888a 100644 --- a/README.md +++ b/README.md @@ -138,11 +138,21 @@ X*.X XX ``` The keys `portal-open` and `portal-closed` are used to define the material in the gate when it is open or closed. -The key `button` is used to define the type of button that is generated for this gate. It must be a button material. +The key `button` is used to define the type of button that is generated for this gate. It can be a button (of any type), +a type of wall coral (dead or alive), a type of shulker box or a chest. `X` and `-` are used to define block types for the layout (Any single-character can be used, such as `#`). In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will teleport in front of. +# Underwater Portals +You can add a custom portal which will work underwater. You need to use `WATER`, not `AIR`, for the `portal-closed` material. + +The button must be a type of wall coral, like `BRAIN_CORAL_WALL_FAN` or `DEAD_BRAIN_CORAL_WALL_FAN`. + +Using `KELP_PLANT` as `portal-open` looks the part, but there are no particular restrictions. + +Any solid block can be used for the frame. + # Configuration ``` default-gate-network - The default gate network @@ -228,6 +238,7 @@ bungeeSign=Teleport to - Uses text from the language files in more places - Changes how backup language works, causing english strings to be shown if not available from the chosen language - Removes some pre-UUID code + - Adds underwater portals #### \[Version 0.8.0.3] PseudoKnight fork - Fix economy - Add custom buttons diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index 4a41ae5..8ca6ddd 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -1,7 +1,6 @@ package net.knarcraft.stargate; import org.bukkit.Material; -import org.bukkit.Tag; import org.bukkit.block.Block; import java.io.BufferedWriter; @@ -399,7 +398,7 @@ public class Gate { return null; } - if (!Tag.BUTTONS.isTagged(gate.button) && !MaterialHelper.isWallCoral(gate.button)) { + if (!MaterialHelper.isButtonCompatible(gate.button)) { Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gate button must be a type of button."); return null; } diff --git a/src/main/java/net/knarcraft/stargate/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/MaterialHelper.java index 808c774..8a2e149 100644 --- a/src/main/java/net/knarcraft/stargate/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/MaterialHelper.java @@ -22,4 +22,14 @@ public class MaterialHelper { material.equals(Material.DEAD_TUBE_CORAL_WALL_FAN); } + /** + * Checks whether the given material can be used as a button + * @param material

The material to check

+ * @return

True if the material can be used as a button

+ */ + public static boolean isButtonCompatible(Material material) { + return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || Tag.SHULKER_BOXES.isTagged(material) || + material == Material.CHEST; + } + } diff --git a/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java index 8360047..44216b5 100644 --- a/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java @@ -1,7 +1,6 @@ package net.knarcraft.stargate; import org.bukkit.GameMode; -import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -230,7 +229,7 @@ public class PlayerEventsListener implements Listener { } // Implement right-click to toggle a stargate, gets around spawn protection problem. - if (Tag.BUTTONS.isTagged(block.getType()) || MaterialHelper.isWallCoral(block.getType())) { + if (MaterialHelper.isButtonCompatible(block.getType())) { if (MaterialHelper.isWallCoral(block.getType())) { if (previousEvent != null && diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 68c98ca..01ceb9e 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -6,7 +6,6 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Server; -import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.EndGateway; @@ -846,7 +845,7 @@ public class Stargate extends JavaPlugin { // Handle keeping portal material and buttons around if (block.getType() == Material.NETHER_PORTAL) { portal = Portal.getByEntrance(block); - } else if (Tag.BUTTONS.isTagged(block.getType()) || MaterialHelper.isWallCoral(block.getType())) { + } else if (MaterialHelper.isButtonCompatible(block.getType())) { portal = Portal.getByControl(block); } if (portal != null) event.setCancelled(true); From d472eab21b259826d9979a5d6f22c19a26a7b15e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 14:30:30 +0100 Subject: [PATCH 033/378] Adds two gate types to resources --- src/main/resources/gates/nethergate.gate | 24 ++++++++++++++++++++++++ src/main/resources/gates/watergate.gate | 12 ++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/main/resources/gates/nethergate.gate create mode 100644 src/main/resources/gates/watergate.gate diff --git a/src/main/resources/gates/nethergate.gate b/src/main/resources/gates/nethergate.gate new file mode 100644 index 0000000..b74cc4d --- /dev/null +++ b/src/main/resources/gates/nethergate.gate @@ -0,0 +1,24 @@ +#This is the default gate type. You can copy this and make as many .gate files as you need. +#The portal-open block can be most blocks which do not fill the entire block or otherwise prevent the player from +#entering the portal, but NETHER_PORTAL, AIR, WATER, LAVA, KELP_PLANT, OAK_FENCE, IRON_BARS, CHAIN, BAMBOO, SUGAR_CANE, +#COBWEB and VINE gives an impression of which blocks will work. +portal-open=NETHER_PORTAL +#The portal-closed block can be any of the blocks used for portal-open, but also any solid, full-size block such as DIRT. +portal-closed=AIR +#The button can be the following: A chest (CHEST), any type of button (STONE_BUTTON, OAK_BUTTON), any type of shulker +#box (LIME_SHULKER_BOX), or any wall coral (DEAD_TUBE_CORAL_WALL_FAN, TUBE_CORAL_WALL_FAN, DEAD_BRAIN_CORAL_WALL_FAN, +#BRAIN_CORAL_WALL_FAN, etc.) +button=STONE_BUTTON +#Whether payment for entry should go to this gate's owner +toowner=false +#The material to use for the normal frame +X=OBSIDIAN +#The material to use for the sign and button blocks of the frame +-=OBSIDIAN +#The description of the required portal blocks. X = Frame block. - = Sign/button position. . = Empty blocks. * = Exit + + XX +X..X +-..- +X*.X + XX diff --git a/src/main/resources/gates/watergate.gate b/src/main/resources/gates/watergate.gate new file mode 100644 index 0000000..72db218 --- /dev/null +++ b/src/main/resources/gates/watergate.gate @@ -0,0 +1,12 @@ +portal-open=KELP_PLANT +portal-closed=WATER +button=BRAIN_CORAL_WALL_FAN +toowner=false +X=SEA_LANTERN +-=SEA_LANTERN + + XX +X..X +-..- +X*.X + XX From c41429b6e03cc0a1478b2ee183141dc1e6956201 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 14:32:01 +0100 Subject: [PATCH 034/378] Makes default gates load from files rather than being defined in code --- .../java/net/knarcraft/stargate/Gate.java | 133 ++++++++++++------ 1 file changed, 88 insertions(+), 45 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index 8ca6ddd..84c2681 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -303,6 +303,20 @@ public class Gate { public static Gate loadGate(File file) { Scanner scanner = null; + try { + scanner = new Scanner(file); + return loadGate(file.getName(), file.getParent(), scanner); + } catch (Exception ex) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + return null; + } finally { + if (scanner != null) { + scanner.close(); + } + } + } + + public static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { boolean designing = false; ArrayList> design = new ArrayList<>(); HashMap types = new HashMap<>(); @@ -316,8 +330,6 @@ public class Gate { types.put(ANYTHING, Material.AIR); try { - scanner = new Scanner(file); - while (scanner.hasNextLine()) { String line = scanner.nextLine(); @@ -330,7 +342,7 @@ public class Gate { for (Character symbol : line.toCharArray()) { if ((symbol.equals('?')) || (!types.containsKey(symbol))) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Unknown symbol '" + symbol + "' in diagram"); + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); return null; } row.add(symbol); @@ -338,9 +350,7 @@ public class Gate { design.add(row); } else { - if ((line.isEmpty()) || (!line.contains("="))) { - designing = true; - } else { + if (!line.isEmpty() && !line.startsWith("#")) { String[] split = line.split("="); String key = split[0].trim(); String value = split[1].trim(); @@ -356,14 +366,18 @@ public class Gate { } else { config.put(key, value); } + } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { + designing = true; } } } } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); return null; } finally { - if (scanner != null) scanner.close(); + if (scanner != null) { + scanner.close(); + } } Character[][] layout = new Character[design.size()][cols]; @@ -383,58 +397,70 @@ public class Gate { layout[y] = result; } - Gate gate = new Gate(file.getName(), layout, types); + Gate gate = new Gate(fileName, layout, types); - gate.portalBlockOpen = readConfig(config, gate, file, "portal-open", gate.portalBlockOpen); - gate.portalBlockClosed = readConfig(config, gate, file, "portal-closed", gate.portalBlockClosed); - gate.button = readConfig(config, gate, file, "button", gate.button); - gate.useCost = readConfig(config, gate, file, "usecost", -1); - gate.destroyCost = readConfig(config, gate, file, "destroycost", -1); - gate.createCost = readConfig(config, gate, file, "createcost", -1); + gate.portalBlockOpen = readConfig(config, fileName, "portal-open", gate.portalBlockOpen); + gate.portalBlockClosed = readConfig(config, fileName, "portal-closed", gate.portalBlockClosed); + gate.button = readConfig(config, fileName, "button", gate.button); + gate.useCost = readConfig(config, fileName, "usecost", -1); + gate.destroyCost = readConfig(config, fileName, "destroycost", -1); + gate.createCost = readConfig(config, fileName, "createcost", -1); gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); if (gate.getControls().length != 2) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gates must have exactly 2 control points."); + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); return null; } if (!MaterialHelper.isButtonCompatible(gate.button)) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gate button must be a type of button."); + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); return null; } // Merge frame types, add open mat to list frameBlocks.addAll(frameTypes); - gate.save(file.getParent() + "/"); // Updates format for version changes + gate.save(parentFolder + "/"); // Updates format for version changes return gate; } - private static int readConfig(HashMap config, Gate gate, File file, String key, int def) { + private static int readConfig(HashMap config, String fileName, String key, int defaultInteger) { if (config.containsKey(key)) { try { return Integer.parseInt(config.get(key)); } catch (NumberFormatException ex) { - Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), file, key)); + Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); } } - return def; + return defaultInteger; } - private static Material readConfig(HashMap config, Gate gate, File file, String key, Material def) { + + /** + * Gets the material defined in the config + * + * @param config

The config to read

+ * @param fileName

The config file the config belongs to

+ * @param key

The config key to read

+ * @param defaultMaterial

The default material to use, in case the config is invalid

+ * @return

The material to use

+ */ + private static Material readConfig(HashMap config, String fileName, String key, Material defaultMaterial) { if (config.containsKey(key)) { - Material mat = Material.getMaterial(config.get(key)); - if (mat != null) { - return mat; + Material material = Material.getMaterial(config.get(key)); + if (material != null) { + return material; + } else { + Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, key)); } - Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", file, key)); } - return def; + return defaultMaterial; } /** * Loads all gates inside the given folder + * * @param gateFolder

The folder containing the gates

*/ public static void loadGates(String gateFolder) { @@ -463,33 +489,47 @@ public class Gate { } /** - * Writes the default gate specification to the given folder + * Writes the default gate specifications to the given folder + * * @param gateFolder

The folder containing gate config files

*/ public static void populateDefaults(String gateFolder) { - Character[][] layout = new Character[][]{ - {' ', 'X', 'X', ' '}, - {'X', '.', '.', 'X'}, - {'-', '.', '.', '-'}, - {'X', '*', '.', 'X'}, - {' ', 'X', 'X', ' '}, - }; - HashMap types = new HashMap<>(); - types.put(ENTRANCE, Material.AIR); - types.put(EXIT, Material.AIR); - types.put(ANYTHING, Material.AIR); - types.put('X', Material.OBSIDIAN); - types.put('-', Material.OBSIDIAN); - - Gate gate = new Gate("nethergate.gate", layout, types); - gate.save(gateFolder); - registerGate(gate); + loadGateFromJar("nethergate.gate", gateFolder); + loadGateFromJar("watergate.gate", gateFolder); } + /** + * Loads the given gate file from within the Jar's resources directory + * @param gateFile

The name of the gate file

+ * @param gateFolder

The folder containing gates

+ */ + private static void loadGateFromJar(String gateFile, String gateFolder) { + Scanner scanner = new Scanner(Gate.class.getResourceAsStream("/gates/" + gateFile)); + Gate gate = loadGate(gateFile, gateFolder, scanner); + if (gate != null) { + registerGate(gate); + } + } + + /** + * Gets the gates with the given control block + * + *

The control block is the block type where the sign should be placed. It is used to decide whether a user + * is creating a new portal.

+ * + * @param block

The control block to check

+ * @return

A list of gates using the given control block

+ */ public static Gate[] getGatesByControlBlock(Block block) { return getGatesByControlBlock(block.getType()); } + /** + * Gets the gates with the given control block + * + * @param type

The type of the control block to check

+ * @return

A list of gates using the given material for control block

+ */ public static Gate[] getGatesByControlBlock(Material type) { Gate[] result = new Gate[0]; ArrayList lookup = controlBlocks.get(type); @@ -503,6 +543,7 @@ public class Gate { /** * Gets a portal by its name (filename before .gate) + * * @param name

The name of the gate to get

* @return

The gate with the given name

*/ @@ -512,6 +553,7 @@ public class Gate { /** * Gets the number of loaded gate configurations + * * @return

The number of loaded gate configurations

*/ public static int getGateCount() { @@ -520,6 +562,7 @@ public class Gate { /** * Checks whether the given material is used for the frame of any portals + * * @param type

The material type to check

* @return

True if the material is used for the frame of at least one portal

*/ From ff8f762ea87ace1e7ce045f09cc598cf593c7521 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 15:05:41 +0100 Subject: [PATCH 035/378] Fixes information about water gates and adds a list of all valid buttons --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 210888a..f1703d6 100644 --- a/README.md +++ b/README.md @@ -144,14 +144,61 @@ a type of wall coral (dead or alive), a type of shulker box or a chest. In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will teleport in front of. +
+ The entire list of button types is as follows: + +Normal: +``` +STONE_BUTTON +OAK_BUTTON +SPRUCE_BUTTON +BIRCH_BUTTON +JUNGLE_BUTTON +ACACIA_BUTTON +DARK_OAK_BUTTON +CRIMSON_BUTTON +WARPED_BUTTON +POLISHED_BLACKSTONE_BUTTON +``` +Waterproof: +``` +CHEST +SHULKER_BOX +WHITE_SHULKER_BOX +ORANGE_SHULKER_BOX +MAGENTA_SHULKER_BOX +LIGHT_BLUE_SHULKER_BOX +YELLOW_SHULKER_BOX +LIME_SHULKER_BOX +PINK_SHULKER_BOX +GRAY_SHULKER_BOX +LIGHT_GRAY_SHULKER_BOX +CYAN_SHULKER_BOX +PURPLE_SHULKER_BOX +BLUE_SHULKER_BOX +BROWN_SHULKER_BOX +GREEN_SHULKER_BOX +RED_SHULKER_BOX +BLACK_SHULKER_BOX +TUBE_CORAL_WALL_FAN +BRAIN_CORAL_WALL_FAN +BUBBLE_CORAL_WALL_FAN +FIRE_CORAL_WALL_FAN +HORN_CORAL_WALL_FAN +DEAD_TUBE_CORAL_WALL_FAN +DEAD_BRAIN_CORAL_WALL_FAN +DEAD_BUBBLE_CORAL_WALL_FAN +DEAD_FIRE_CORAL_WALL_FAN +DEAD_HORN_CORAL_WALL_FAN +``` +
+ # Underwater Portals -You can add a custom portal which will work underwater. You need to use `WATER`, not `AIR`, for the `portal-closed` material. +There is a default gate type for underwater gates. There are no real restrictions on underwater gate materials, except +normal buttons cannot be used since they'd fall off. Using wall coral fans work much better, though `CHEST` and +`SHULKER_BOX` works too. -The button must be a type of wall coral, like `BRAIN_CORAL_WALL_FAN` or `DEAD_BRAIN_CORAL_WALL_FAN`. - -Using `KELP_PLANT` as `portal-open` looks the part, but there are no particular restrictions. - -Any solid block can be used for the frame. +Using `AIR` for a closed gate looks weird, so `WATER` might be better. # Configuration ``` @@ -239,6 +286,7 @@ bungeeSign=Teleport to - Changes how backup language works, causing english strings to be shown if not available from the chosen language - Removes some pre-UUID code - Adds underwater portals + - Makes it easier to add more default gates #### \[Version 0.8.0.3] PseudoKnight fork - Fix economy - Add custom buttons From 56410a58f8c77ef63d1d227bb023342a6aca0743 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Feb 2021 15:12:48 +0100 Subject: [PATCH 036/378] Improves formatting of custom gate information --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f1703d6..4f23123 100644 --- a/README.md +++ b/README.md @@ -144,11 +144,12 @@ a type of wall coral (dead or alive), a type of shulker box or a chest. In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will teleport in front of. +## Buttons +The actual buttons cannot be used underwater, but all the other items in the button list can be.
- The entire list of button types is as follows: - -Normal: -``` + The entire list of button types is as follows: (Click to expand) + +``` STONE_BUTTON OAK_BUTTON SPRUCE_BUTTON @@ -159,9 +160,7 @@ DARK_OAK_BUTTON CRIMSON_BUTTON WARPED_BUTTON POLISHED_BLACKSTONE_BUTTON -``` -Waterproof: -``` + CHEST SHULKER_BOX WHITE_SHULKER_BOX @@ -193,7 +192,7 @@ DEAD_HORN_CORAL_WALL_FAN ```
-# Underwater Portals +## Underwater Portals There is a default gate type for underwater gates. There are no real restrictions on underwater gate materials, except normal buttons cannot be used since they'd fall off. Using wall coral fans work much better, though `CHEST` and `SHULKER_BOX` works too. From 1719e92494277a15d168e7605a825bbb21fa5fe1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 11 Feb 2021 15:53:54 +0100 Subject: [PATCH 037/378] Moves a bunch of inner classes to their own files --- .../java/net/knarcraft/stargate/Gate.java | 1 + .../java/net/knarcraft/stargate/Portal.java | 12 +- .../java/net/knarcraft/stargate/Stargate.java | 357 +----------------- .../stargate/event/StargateEvent.java | 2 +- .../stargate/listener/BlockEventListener.java | 158 ++++++++ .../{ => listener}/BungeeCordListener.java | 4 +- .../listener/EntityEventListener.java | 29 ++ .../{ => listener}/PlayerEventsListener.java | 6 +- .../listener/PluginEventListener.java | 32 ++ .../listener/VehicleEventListener.java | 100 +++++ .../stargate/listener/WorldEventListener.java | 35 ++ .../stargate/thread/BlockPopulatorThread.java | 32 ++ .../stargate/{ => thread}/StarGateThread.java | 5 +- .../{ => utility}/MaterialHelper.java | 4 +- 14 files changed, 427 insertions(+), 350 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java rename src/main/java/net/knarcraft/stargate/{ => listener}/BungeeCordListener.java (96%) create mode 100644 src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java rename src/main/java/net/knarcraft/stargate/{ => listener}/PlayerEventsListener.java (98%) create mode 100644 src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java create mode 100644 src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java create mode 100644 src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java create mode 100644 src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java rename src/main/java/net/knarcraft/stargate/{ => thread}/StarGateThread.java (90%) rename src/main/java/net/knarcraft/stargate/{ => utility}/MaterialHelper.java (94%) diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index 84c2681..83ec460 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate; +import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index c6f665d..9fbb522 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -1290,12 +1290,11 @@ public class Portal { String wName = portal.world.getName(); if (!wName.equalsIgnoreCase(world.getName())) continue; StringBuilder builder = new StringBuilder(); - BlockLocation sign = portal.id; BlockLocation button = portal.button; builder.append(portal.name); builder.append(':'); - builder.append(sign.toString()); + builder.append(portal.id.toString()); builder.append(':'); builder.append((button != null) ? button.toString() : ""); builder.append(':'); @@ -1515,10 +1514,9 @@ public class Portal { } else if (!name.equalsIgnoreCase(other.name)) return false; if (network == null) { - if (other.network != null) - return false; - } else if (!network.equalsIgnoreCase(other.network)) - return false; - return true; + return other.network == null; + } else { + return network.equalsIgnoreCase(other.network); + } } } diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 01ceb9e..4d3a0b5 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -1,38 +1,24 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.event.StargateAccessEvent; -import net.knarcraft.stargate.event.StargateDestroyEvent; +import net.knarcraft.stargate.listener.BlockEventListener; +import net.knarcraft.stargate.listener.BungeeCordListener; +import net.knarcraft.stargate.listener.EntityEventListener; +import net.knarcraft.stargate.listener.PlayerEventsListener; +import net.knarcraft.stargate.listener.PluginEventListener; +import net.knarcraft.stargate.listener.VehicleEventListener; +import net.knarcraft.stargate.listener.WorldEventListener; +import net.knarcraft.stargate.thread.BlockPopulatorThread; +import net.knarcraft.stargate.thread.StarGateThread; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.EndGateway; import org.bukkit.block.Sign; -import org.bukkit.block.data.Orientable; -import org.bukkit.block.data.type.WallSign; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.bukkit.entity.Vehicle; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockFromToEvent; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPistonRetractEvent; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.server.PluginDisableEvent; -import org.bukkit.event.server.PluginEnableEvent; -import org.bukkit.event.vehicle.VehicleMoveEvent; -import org.bukkit.event.world.WorldLoadEvent; -import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; @@ -43,7 +29,6 @@ import java.io.File; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Queue; import java.util.UUID; @@ -86,6 +71,7 @@ public class Stargate extends JavaPlugin { private static String gateFolder; private static String langFolder; private static String defNetwork = "central"; + private static boolean destroyExplosion = false; public static int maxGates = 0; private static String langName = "en"; @@ -106,7 +92,7 @@ public class Stargate extends JavaPlugin { public static boolean debug = false; public static boolean permDebug = false; - public static ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); + public static final ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); public static ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); // Used for populating gate open/closed material. @@ -160,12 +146,12 @@ public class Stargate extends JavaPlugin { // Register events before loading gates to stop weird things happening. pm.registerEvents(new PlayerEventsListener(), this); - pm.registerEvents(new bListener(), this); + pm.registerEvents(new BlockEventListener(), this); - pm.registerEvents(new vListener(), this); - pm.registerEvents(new eListener(), this); - pm.registerEvents(new wListener(), this); - pm.registerEvents(new sListener(), this); + pm.registerEvents(new VehicleEventListener(), this); + pm.registerEvents(new EntityEventListener(), this); + pm.registerEvents(new WorldEventListener(), this); + pm.registerEvents(new PluginEventListener(this), this); this.loadConfig(); @@ -195,6 +181,10 @@ public class Stargate extends JavaPlugin { getServer().getScheduler().scheduleSyncRepeatingTask(this, new BlockPopulatorThread(), 0L, 1L); } + public static boolean destroyedByExplosion() { + return destroyExplosion; + } + public static int getOpenTime() { return openTime; } @@ -660,313 +650,6 @@ public class Stargate extends JavaPlugin { return input.replace(search, value); } - private class vListener implements Listener { - @EventHandler - public void onVehicleMove(VehicleMoveEvent event) { - if (!handleVehicles) return; - List passengers = event.getVehicle().getPassengers(); - Vehicle vehicle = event.getVehicle(); - - Portal portal = Portal.getByEntrance(event.getTo()); - if (portal == null || !portal.isOpen()) return; - - // We don't support vehicles in Bungee portals - if (portal.isBungee()) return; - - if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - /* - Player player = (Player) passengers.get(0); - if (!portal.isOpenFor(player)) { - stargate.sendMessage(player, stargate.getString("denyMsg")); - return; - } - - Portal dest = portal.getDestination(player); - if (dest == null) return; - boolean deny = false; - // Check if player has access to this network - if (!canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - // Check if player has access to destination world - if (!canAccessWorld(player, dest.getWorld().getName())) { - deny = true; - } - - if (!canAccessPortal(player, portal, deny)) { - stargate.sendMessage(player, stargate.getString("denyMsg")); - portal.close(false); - return; - } - - int cost = stargate.getUseCost(player, portal, dest); - if (cost > 0) { - boolean success; - if(portal.getGate().getToOwner()) { - if(portal.getOwnerUUID() == null) { - success = stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = stargate.chargePlayer(player, portal.getOwnerName(), cost); - } - } else { - success = stargate.chargePlayer(player, cost); - } - if(!success) { - // Insufficient Funds - stargate.sendMessage(player, stargate.getString("inFunds")); - portal.close(false); - return; - } - String deductMsg = stargate.getString("ecoDeduct"); - deductMsg = stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - if (portal.getGate().getToOwner()) { - Player p; - if(portal.getOwnerUUID() != null) { - p = server.getPlayer(portal.getOwnerUUID()); - } else { - p = server.getPlayer(portal.getOwnerName()); - } - if (p != null) { - String obtainedMsg = stargate.getString("ecoObtain"); - obtainedMsg = stargate.replaceVars(obtainedMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - stargate.sendMessage(p, obtainedMsg, false); - } - } - } - - stargate.sendMessage(player, stargate.getString("teleportMsg"), false); - dest.teleport(vehicle); - portal.close(false); - */ - } else { - Portal dest = portal.getDestination(); - if (dest == null) return; - dest.teleport(vehicle); - } - } - } - - - - private class bListener implements Listener { - @EventHandler - public void onSignChange(SignChangeEvent event) { - if (event.isCancelled()) { - return; - } - Player player = event.getPlayer(); - Block block = event.getBlock(); - if (!(block.getBlockData() instanceof WallSign)) { - return; - } - - final Portal portal = Portal.createPortal(event, player); - // Not creating a gate, just placing a sign - if (portal == null) { - return; - } - - Stargate.sendMessage(player, Stargate.getString("createMsg"), false); - Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); - Stargate.server.getScheduler().scheduleSyncDelayedTask(stargate, new Runnable() { - public void run() { - portal.drawSign(); - } - }, 1); - } - - // Switch to HIGHEST priority so as to come after block protection plugins (Hopefully) - @EventHandler(priority = EventPriority.HIGHEST) - public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled()) return; - Block block = event.getBlock(); - Player player = event.getPlayer(); - - Portal portal = Portal.getByBlock(block); - if (portal == null && protectEntrance) - portal = Portal.getByEntrance(block); - if (portal == null) return; - - boolean deny = false; - String denyMsg = ""; - - if (!Stargate.canDestroy(player, portal)) { - denyMsg = "Permission Denied"; // TODO: Change to stargate.getString() - deny = true; - Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); - } - - int cost = Stargate.getDestroyCost(player, portal.getGate()); - - StargateDestroyEvent dEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); - Stargate.server.getPluginManager().callEvent(dEvent); - if (dEvent.isCancelled()) { - event.setCancelled(true); - return; - } - if (dEvent.getDeny()) { - Stargate.sendMessage(player, dEvent.getDenyReason()); - event.setCancelled(true); - return; - } - - cost = dEvent.getCost(); - - if (cost != 0) { - if (!Stargate.chargePlayer(player, cost)) { - Stargate.debug("onBlockBreak", "Insufficient Funds"); - Stargate.sendMessage(player, Stargate.getString("inFunds")); - event.setCancelled(true); - return; - } - - if (cost > 0) { - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - } else if (cost < 0) { - String refundMsg = Stargate.getString("ecoRefund"); - refundMsg = Stargate.replaceVars(refundMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(-cost), portal.getName()}); - sendMessage(player, refundMsg, false); - } - } - - portal.unregister(true); - Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); - } - - @EventHandler - public void onBlockPhysics(BlockPhysicsEvent event) { - Block block = event.getBlock(); - Portal portal = null; - - // Handle keeping portal material and buttons around - if (block.getType() == Material.NETHER_PORTAL) { - portal = Portal.getByEntrance(block); - } else if (MaterialHelper.isButtonCompatible(block.getType())) { - portal = Portal.getByControl(block); - } - if (portal != null) event.setCancelled(true); - } - - @EventHandler - public void onBlockFromTo(BlockFromToEvent event) { - Portal portal = Portal.getByEntrance(event.getBlock()); - - if (portal != null) { - event.setCancelled((event.getBlock().getY() == event.getToBlock().getY())); - } - } - - @EventHandler - public void onPistonExtend(BlockPistonExtendEvent event) { - for (Block block : event.getBlocks()) { - Portal portal = Portal.getByBlock(block); - if (portal != null) { - event.setCancelled(true); - return; - } - } - } - - @EventHandler - public void onPistonRetract(BlockPistonRetractEvent event) { - if (!event.isSticky()) return; - for (Block block : event.getBlocks()) { - Portal portal = Portal.getByBlock(block); - if (portal != null) { - event.setCancelled(true); - return; - } - } - } - } - - private class wListener implements Listener { - @EventHandler - public void onWorldLoad(WorldLoadEvent event) { - if (!managedWorlds.contains(event.getWorld().getName()) - && Portal.loadAllGates(event.getWorld())) { - managedWorlds.add(event.getWorld().getName()); - } - } - - // We need to reload all gates on world unload, boo - @EventHandler - public void onWorldUnload(WorldUnloadEvent event) { - Stargate.debug("onWorldUnload", "Reloading all Stargates"); - World w = event.getWorld(); - if (managedWorlds.contains(w.getName())) { - managedWorlds.remove(w.getName()); - Portal.clearGates(); - for (World world : server.getWorlds()) { - if (managedWorlds.contains(world.getName())) { - Portal.loadAllGates(world); - } - } - } - } - } - - private class eListener implements Listener { - @EventHandler - public void onEntityExplode(EntityExplodeEvent event) { - if (event.isCancelled()) return; - for (Block b : event.blockList()) { - Portal portal = Portal.getByBlock(b); - if (portal == null) continue; - if (destroyExplosion) { - portal.unregister(true); - } else { - event.setCancelled(true); - break; - } - } - } - } - - private class sListener implements Listener { - @EventHandler - public void onPluginEnable(PluginEnableEvent event) { - if (EconomyHandler.setupEconomy(getServer().getPluginManager())) { - String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); - log.info(Stargate.getString("prefix") + - replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); - } - } - - @EventHandler - public void onPluginDisable(PluginDisableEvent event) { - if (event.getPlugin().equals(EconomyHandler.vault)) { - log.info(Stargate.getString("prefix") + "Vault plugin lost."); - } - } - } - - private class BlockPopulatorThread implements Runnable { - public void run() { - long sTime = System.nanoTime(); - while (System.nanoTime() - sTime < 25000000) { - BloxPopulator b = Stargate.blockPopulatorQueue.poll(); - if (b == null) return; - Block blk = b.getBlockLocation().getBlock(); - blk.setType(b.getMat(), false); - if (b.getMat() == Material.END_GATEWAY && blk.getWorld().getEnvironment() == World.Environment.THE_END) { - // force a location to prevent exit gateway generation - EndGateway gateway = (EndGateway) blk.getState(); - gateway.setExitLocation(blk.getWorld().getSpawnLocation()); - gateway.setExactTeleport(true); - gateway.update(false, false); - } else if (b.getAxis() != null) { - Orientable orientable = (Orientable) blk.getBlockData(); - orientable.setAxis(b.getAxis()); - blk.setBlockData(orientable); - } - } - } - } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index d3471da..a3a40ce 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -29,7 +29,7 @@ import org.bukkit.event.Event; @SuppressWarnings("unused") public abstract class StargateEvent extends Event implements Cancellable { - protected Portal portal; + protected final Portal portal; protected boolean cancelled; public StargateEvent(String event, Portal portal) { diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java new file mode 100644 index 0000000..90b2703 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -0,0 +1,158 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.event.StargateDestroyEvent; +import net.knarcraft.stargate.utility.MaterialHelper; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPistonEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.SignChangeEvent; + +import java.util.List; + +public class BlockEventListener implements Listener { + @EventHandler + public void onSignChange(SignChangeEvent event) { + if (event.isCancelled()) { + return; + } + Player player = event.getPlayer(); + Block block = event.getBlock(); + if (!(block.getBlockData() instanceof WallSign)) { + return; + } + + final Portal portal = Portal.createPortal(event, player); + // Not creating a gate, just placing a sign + if (portal == null) { + return; + } + + Stargate.sendMessage(player, Stargate.getString("createMsg"), false); + Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> portal.drawSign(), 1); + } + + // Switch to HIGHEST priority so as to come after block protection plugins (Hopefully) + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlockBreak(BlockBreakEvent event) { + if (event.isCancelled()) return; + Block block = event.getBlock(); + Player player = event.getPlayer(); + + Portal portal = Portal.getByBlock(block); + if (portal == null && Stargate.protectEntrance) + portal = Portal.getByEntrance(block); + if (portal == null) return; + + boolean deny = false; + String denyMsg = ""; + + if (!Stargate.canDestroy(player, portal)) { + denyMsg = "Permission Denied"; // TODO: Change to stargate.getString() + deny = true; + Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); + } + + int cost = Stargate.getDestroyCost(player, portal.getGate()); + + StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); + Stargate.server.getPluginManager().callEvent(destroyEvent); + if (destroyEvent.isCancelled()) { + event.setCancelled(true); + return; + } + if (destroyEvent.getDeny()) { + Stargate.sendMessage(player, destroyEvent.getDenyReason()); + event.setCancelled(true); + return; + } + + cost = destroyEvent.getCost(); + + if (cost != 0) { + if (!Stargate.chargePlayer(player, cost)) { + Stargate.debug("onBlockBreak", "Insufficient Funds"); + Stargate.sendMessage(player, Stargate.getString("inFunds")); + event.setCancelled(true); + return; + } + + if (cost > 0) { + String deductMsg = Stargate.getString("ecoDeduct"); + deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); + Stargate.sendMessage(player, deductMsg, false); + } else { + String refundMsg = Stargate.getString("ecoRefund"); + refundMsg = Stargate.replaceVars(refundMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(-cost), portal.getName()}); + Stargate.sendMessage(player, refundMsg, false); + } + } + + portal.unregister(true); + Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); + } + + @EventHandler + public void onBlockPhysics(BlockPhysicsEvent event) { + Block block = event.getBlock(); + Portal portal = null; + + // Handle keeping portal material and buttons around + if (block.getType() == Material.NETHER_PORTAL) { + portal = Portal.getByEntrance(block); + } else if (MaterialHelper.isButtonCompatible(block.getType())) { + portal = Portal.getByControl(block); + } + if (portal != null) event.setCancelled(true); + } + + @EventHandler + public void onBlockFromTo(BlockFromToEvent event) { + Portal portal = Portal.getByEntrance(event.getBlock()); + + if (portal != null) { + event.setCancelled((event.getBlock().getY() == event.getToBlock().getY())); + } + } + + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent event) { + cancelPistonEvent(event, event.getBlocks()); + } + + @EventHandler + public void onPistonRetract(BlockPistonRetractEvent event) { + if (!event.isSticky()) { + return; + } + cancelPistonEvent(event, event.getBlocks()); + } + + /** + * Cancels a piston event if it would destroy a portal + * @param event

The event to cancel

+ * @param blocks

The blocks included in the event

+ */ + private void cancelPistonEvent(BlockPistonEvent event, List blocks) { + for (Block block : blocks) { + Portal portal = Portal.getByBlock(block); + if (portal != null) { + event.setCancelled(true); + return; + } + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java similarity index 96% rename from src/main/java/net/knarcraft/stargate/BungeeCordListener.java rename to src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java index 2737a34..51be7d5 100644 --- a/src/main/java/net/knarcraft/stargate/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java @@ -1,5 +1,7 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java new file mode 100644 index 0000000..a0f7759 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -0,0 +1,29 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; + +public class EntityEventListener implements Listener { + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (event.isCancelled()) { + return; + } + for (Block b : event.blockList()) { + Portal portal = Portal.getByBlock(b); + if (portal == null) { + continue; + } + if (Stargate.destroyedByExplosion()) { + portal.unregister(true); + } else { + event.setCancelled(true); + break; + } + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/PlayerEventsListener.java rename to src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 44216b5..36399b9 100644 --- a/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -1,5 +1,9 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.utility.MaterialHelper; +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.block.Block; diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java new file mode 100644 index 0000000..dbf96e5 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -0,0 +1,32 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.Stargate; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; + +public class PluginEventListener implements Listener { + private final Stargate stargate; + + public PluginEventListener(Stargate stargate) { + this.stargate = stargate; + } + + @EventHandler + public void onPluginEnable(PluginEnableEvent event) { + if (EconomyHandler.setupEconomy(stargate.getServer().getPluginManager())) { + String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + Stargate.log.info(Stargate.getString("prefix") + + Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + } + } + + @EventHandler + public void onPluginDisable(PluginDisableEvent event) { + if (event.getPlugin().equals(EconomyHandler.vault)) { + Stargate.log.info(Stargate.getString("prefix") + "Vault plugin lost."); + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java new file mode 100644 index 0000000..1c31b69 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -0,0 +1,100 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.vehicle.VehicleMoveEvent; + +import java.util.List; + +public class VehicleEventListener implements Listener { + @EventHandler + public void onVehicleMove(VehicleMoveEvent event) { + if (!Stargate.handleVehicles) return; + List passengers = event.getVehicle().getPassengers(); + Vehicle vehicle = event.getVehicle(); + + Portal portal = Portal.getByEntrance(event.getTo()); + if (portal == null || !portal.isOpen()) return; + + // We don't support vehicles in Bungee portals + if (portal.isBungee()) return; + + if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { + /* + Player player = (Player) passengers.get(0); + if (!portal.isOpenFor(player)) { + stargate.sendMessage(player, stargate.getString("denyMsg")); + return; + } + + Portal dest = portal.getDestination(player); + if (dest == null) return; + boolean deny = false; + // Check if player has access to this network + if (!canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + // Check if player has access to destination world + if (!canAccessWorld(player, dest.getWorld().getName())) { + deny = true; + } + + if (!canAccessPortal(player, portal, deny)) { + stargate.sendMessage(player, stargate.getString("denyMsg")); + portal.close(false); + return; + } + + int cost = stargate.getUseCost(player, portal, dest); + if (cost > 0) { + boolean success; + if(portal.getGate().getToOwner()) { + if(portal.getOwnerUUID() == null) { + success = stargate.chargePlayer(player, portal.getOwnerUUID(), cost); + } else { + success = stargate.chargePlayer(player, portal.getOwnerName(), cost); + } + } else { + success = stargate.chargePlayer(player, cost); + } + if(!success) { + // Insufficient Funds + stargate.sendMessage(player, stargate.getString("inFunds")); + portal.close(false); + return; + } + String deductMsg = stargate.getString("ecoDeduct"); + deductMsg = stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); + sendMessage(player, deductMsg, false); + if (portal.getGate().getToOwner()) { + Player p; + if(portal.getOwnerUUID() != null) { + p = server.getPlayer(portal.getOwnerUUID()); + } else { + p = server.getPlayer(portal.getOwnerName()); + } + if (p != null) { + String obtainedMsg = stargate.getString("ecoObtain"); + obtainedMsg = stargate.replaceVars(obtainedMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); + stargate.sendMessage(p, obtainedMsg, false); + } + } + } + + stargate.sendMessage(player, stargate.getString("teleportMsg"), false); + dest.teleport(vehicle); + portal.close(false); + */ + } else { + Portal dest = portal.getDestination(); + if (dest == null) return; + dest.teleport(vehicle); + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java new file mode 100644 index 0000000..e7d33be --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -0,0 +1,35 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; + +public class WorldEventListener implements Listener { + @EventHandler + public void onWorldLoad(WorldLoadEvent event) { + if (!Stargate.managedWorlds.contains(event.getWorld().getName()) + && Portal.loadAllGates(event.getWorld())) { + Stargate.managedWorlds.add(event.getWorld().getName()); + } + } + + // We need to reload all gates on world unload, boo + @EventHandler + public void onWorldUnload(WorldUnloadEvent event) { + Stargate.debug("onWorldUnload", "Reloading all Stargates"); + World w = event.getWorld(); + if (Stargate.managedWorlds.contains(w.getName())) { + Stargate.managedWorlds.remove(w.getName()); + Portal.clearGates(); + for (World world : Stargate.server.getWorlds()) { + if (Stargate.managedWorlds.contains(world.getName())) { + Portal.loadAllGates(world); + } + } + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java new file mode 100644 index 0000000..1f620e2 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java @@ -0,0 +1,32 @@ +package net.knarcraft.stargate.thread; + +import net.knarcraft.stargate.BloxPopulator; +import net.knarcraft.stargate.Stargate; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.EndGateway; +import org.bukkit.block.data.Orientable; + +public class BlockPopulatorThread implements Runnable { + public void run() { + long sTime = System.nanoTime(); + while (System.nanoTime() - sTime < 25000000) { + BloxPopulator b = Stargate.blockPopulatorQueue.poll(); + if (b == null) return; + Block blk = b.getBlockLocation().getBlock(); + blk.setType(b.getMat(), false); + if (b.getMat() == Material.END_GATEWAY && blk.getWorld().getEnvironment() == World.Environment.THE_END) { + // force a location to prevent exit gateway generation + EndGateway gateway = (EndGateway) blk.getState(); + gateway.setExitLocation(blk.getWorld().getSpawnLocation()); + gateway.setExactTeleport(true); + gateway.update(false, false); + } else if (b.getAxis() != null) { + Orientable orientable = (Orientable) blk.getBlockData(); + orientable.setAxis(b.getAxis()); + blk.setBlockData(orientable); + } + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java similarity index 90% rename from src/main/java/net/knarcraft/stargate/StarGateThread.java rename to src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 516b326..bfdedec 100644 --- a/src/main/java/net/knarcraft/stargate/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -1,4 +1,7 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.thread; + +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; import java.util.Iterator; diff --git a/src/main/java/net/knarcraft/stargate/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java similarity index 94% rename from src/main/java/net/knarcraft/stargate/MaterialHelper.java rename to src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 8a2e149..83d6e5a 100644 --- a/src/main/java/net/knarcraft/stargate/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.utility; import org.bukkit.Material; import org.bukkit.Tag; @@ -6,7 +6,7 @@ import org.bukkit.Tag; /** * This class helps decide properties of materials not already present in the Spigot API */ -public class MaterialHelper { +public final class MaterialHelper { /** * Checks whether the given material is a dead or alive wall coral From bd4586e386e8c05e0704a3d430fda4b774d9cf07 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 Feb 2021 00:24:27 +0100 Subject: [PATCH 038/378] Adds annotations to prevent warnings --- pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 26dfd7b..f7d86c3 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,13 @@ 0.24.0 test - + + org.jetbrains + annotations + 19.0.0 + compile + + src/main/java From 42fa6ed8d7ddb23322fffd0f1c9a2e5b0d77192f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 Feb 2021 00:26:47 +0100 Subject: [PATCH 039/378] Huge refactoring Splits Portal into Portal and PortalHandler Adds EconomyHelper to make messaging of economy string easier Adds a lot of missing comments Adds vehicle teleportation again, but it needs a lot of changes to work properly --- .../net/knarcraft/stargate/BlockLocation.java | 21 - .../knarcraft/stargate/EconomyHandler.java | 19 - .../java/net/knarcraft/stargate/Gate.java | 21 - .../knarcraft/stargate/LanguageLoader.java | 19 - .../java/net/knarcraft/stargate/Portal.java | 923 +++--------------- .../net/knarcraft/stargate/PortalHandler.java | 865 ++++++++++++++++ .../stargate/RelativeBlockVector.java | 34 +- .../java/net/knarcraft/stargate/Stargate.java | 40 +- .../java/net/knarcraft/stargate/TwoTuple.java | 39 + .../stargate/event/StargateAccessEvent.java | 46 +- .../stargate/event/StargateActivateEvent.java | 21 +- .../stargate/event/StargateCloseEvent.java | 21 +- .../stargate/event/StargateCreateEvent.java | 21 +- .../event/StargateDeactivateEvent.java | 21 +- .../stargate/event/StargateDestroyEvent.java | 60 +- .../stargate/event/StargateEvent.java | 20 +- .../stargate/event/StargateOpenEvent.java | 21 +- .../stargate/event/StargatePortalEvent.java | 21 +- .../stargate/listener/BlockEventListener.java | 126 ++- .../stargate/listener/BungeeCordListener.java | 6 +- .../listener/EntityEventListener.java | 20 +- .../listener/PlayerEventsListener.java | 88 +- .../listener/VehicleEventListener.java | 146 ++- .../stargate/listener/WorldEventListener.java | 7 +- .../stargate/utility/EconomyHelper.java | 113 +++ 25 files changed, 1470 insertions(+), 1269 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/PortalHandler.java create mode 100644 src/main/java/net/knarcraft/stargate/TwoTuple.java create mode 100644 src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index 49d9db2..59d6c62 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -9,27 +9,6 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Sign; import org.bukkit.block.data.type.WallSign; -/* - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - /** * This class represents a block location * diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/EconomyHandler.java index 1d7f984..83bd86c 100644 --- a/src/main/java/net/knarcraft/stargate/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/EconomyHandler.java @@ -9,25 +9,6 @@ import org.bukkit.plugin.RegisteredServiceProvider; import java.util.UUID; -/* - stargate - A portal plugin for Bukkit - Copyright (C) 2011, 2012 Steven "Drakia" Scott - Copyright (C) 2021 Kristian Knarvik -

- This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -

- This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. -

- You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . - */ - /** * This handler handles economy actions such as payment for using a gate */ diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index 83ec460..a499453 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -15,27 +15,6 @@ import java.util.Map; import java.util.Scanner; import java.util.logging.Level; -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - public class Gate { private static final Character ANYTHING = ' '; diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index b539696..bc74785 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -18,25 +18,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -/* - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - /** * This class is responsible for loading all strings which are translated into several languages */ diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index 9fbb522..4b9db19 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -2,81 +2,36 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; -import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateOpenEvent; import net.knarcraft.stargate.event.StargatePortalEvent; import org.bukkit.Axis; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.OfflinePlayer; import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Directional; import org.bukkit.block.data.Powerable; -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.entity.minecart.StorageMinecart; -import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.util.Vector; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Random; -import java.util.Scanner; import java.util.UUID; import java.util.logging.Level; -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - public class Portal { - // Static variables used to store portal lists - private static final HashMap lookupBlocks = new HashMap<>(); - private static final HashMap lookupEntrances = new HashMap<>(); - private static final HashMap lookupControls = new HashMap<>(); - private static final ArrayList allPortals = new ArrayList<>(); - private static final HashMap> allPortalsNet = new HashMap<>(); - private static final HashMap> lookupNamesNet = new HashMap<>(); - - // A list of Bungee gates - private static final HashMap bungeePortals = new HashMap<>(); - // Gate location block info private final BlockLocation topLeft; private final int modX; @@ -93,11 +48,11 @@ public class Portal { // Gate information private String name; private String destination; - private String lastDest = ""; + private String lastDestination = ""; private String network; private final Gate gate; - private String ownerName = ""; - private UUID ownerUUID = null; + private String ownerName; + private UUID ownerUUID; private final World world; private boolean verified; private boolean fixed; @@ -105,7 +60,7 @@ public class Portal { // Options private boolean hidden = false; private boolean alwaysOn = false; - private boolean priv = false; + private boolean isPrivate = false; private boolean free = false; private boolean backwards = false; private boolean show = false; @@ -120,11 +75,45 @@ public class Portal { private boolean isOpen = false; private long openTime; - private Portal(BlockLocation topLeft, int modX, int modZ, - float rotX, BlockLocation id, BlockLocation button, - String dest, String name, - boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, - boolean hidden, boolean alwaysOn, boolean priv, boolean free, boolean backwards, boolean show, boolean noNetwork, boolean random, boolean bungee) { + Portal(BlockLocation topLeft, int modX, int modZ, float rotX, BlockLocation id, BlockLocation button, + String dest, String name, boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName) { + this.topLeft = topLeft; + this.modX = modX; + this.modZ = modZ; + this.rotX = rotX; + this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; + this.id = id; + this.destination = dest; + this.button = button; + this.verified = verified; + this.network = network; + this.name = name; + this.gate = gate; + this.ownerUUID = ownerUUID; + this.ownerName = ownerName; + this.world = topLeft.getWorld(); + this.fixed = dest.length() > 0 || this.random || this.bungee; + + if (this.isAlwaysOn() && !this.isFixed()) { + this.alwaysOn = false; + Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); + } + + if (this.random && !this.isAlwaysOn()) { + this.alwaysOn = true; + Stargate.debug("Portal", "Gate marked as random, set to always-on"); + } + + if (verified) { + this.drawSign(); + } + } + + Portal(BlockLocation topLeft, int modX, int modZ, + float rotX, BlockLocation id, BlockLocation button, + String dest, String name, + boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, + boolean hidden, boolean alwaysOn, boolean isPrivate, boolean free, boolean backwards, boolean show, boolean noNetwork, boolean random, boolean bungee) { this.topLeft = topLeft; this.modX = modX; this.modZ = modZ; @@ -141,7 +130,7 @@ public class Portal { this.ownerName = ownerName; this.hidden = hidden; this.alwaysOn = alwaysOn; - this.priv = priv; + this.isPrivate = isPrivate; this.free = free; this.backwards = backwards; this.show = show; @@ -182,7 +171,7 @@ public class Portal { } public boolean isPrivate() { - return priv; + return isPrivate; } public boolean isFree() { @@ -209,36 +198,54 @@ public class Portal { return bungee; } - public void setAlwaysOn(boolean alwaysOn) { + public Portal setAlwaysOn(boolean alwaysOn) { this.alwaysOn = alwaysOn; + return this; } - public void setHidden(boolean hidden) { + public Portal setHidden(boolean hidden) { this.hidden = hidden; + return this; } - public void setPrivate(boolean priv) { - this.priv = priv; + public Portal setPrivate(boolean priv) { + this.isPrivate = priv; + return this; } - public void setFree(boolean free) { + public Portal setFree(boolean free) { this.free = free; + return this; } - public void setBackwards(boolean backwards) { + public Portal setBackwards(boolean backwards) { this.backwards = backwards; + return this; } - public void setShown(boolean show) { + public Portal setShown(boolean show) { this.show = show; + return this; } - public void setNoNetwork(boolean noNetwork) { + + public Portal setNoNetwork(boolean noNetwork) { this.noNetwork = noNetwork; + return this; } - public void setRandom(boolean random) { + public Portal setRandom(boolean random) { this.random = random; + return this; + } + + public Portal setBungee(boolean bungee) { + this.bungee = bungee; + return this; + } + + public void setFixed(boolean fixed) { + this.fixed = fixed; } /** @@ -280,15 +287,15 @@ public class Portal { public Portal getDestination(Player player) { if (isRandom()) { - destinations = getDestinations(player, getNetwork()); + destinations = PortalHandler.getDestinations(player, getNetwork()); if (destinations.size() == 0) { return null; } String dest = destinations.get((new Random()).nextInt(destinations.size())); destinations.clear(); - return Portal.getByName(dest, getNetwork()); + return PortalHandler.getByName(dest, getNetwork()); } - return Portal.getByName(destination, getNetwork()); + return PortalHandler.getByName(destination, getNetwork()); } public Portal getDestination() { @@ -374,10 +381,6 @@ public class Portal { this.button = button; } - public static ArrayList getNetwork(String network) { - return allPortalsNet.get(network.toLowerCase()); - } - public boolean open(boolean force) { return open(null, force); } @@ -513,7 +516,8 @@ public class Portal { } public void teleport(final Vehicle vehicle) { - Location traveller = new Location(this.world, vehicle.getLocation().getX(), vehicle.getLocation().getY(), vehicle.getLocation().getZ()); + Location traveller = new Location(this.world, vehicle.getLocation().getX(), vehicle.getLocation().getY(), + vehicle.getLocation().getZ()); Location exit = getExit(traveller); double velocity = vehicle.getVelocity().length(); @@ -526,25 +530,33 @@ public class Portal { newVelocity.multiply(velocity); List passengers = vehicle.getPassengers(); + World vehicleWorld = exit.getWorld(); + if (vehicleWorld == null) { + 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 Vehicle v = exit.getWorld().spawn(exit, vehicle.getClass()); final Entity passenger = passengers.get(0); vehicle.eject(); vehicle.remove(); passenger.eject(); passenger.teleport(exit); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> { - v.addPassenger(passenger); - v.setVelocity(newVelocity); + mineCart.addPassenger(passenger); + mineCart.setVelocity(newVelocity); }, 1); } else { - Vehicle mc = exit.getWorld().spawn(exit, vehicle.getClass()); - if (mc instanceof StorageMinecart) { - StorageMinecart smc = (StorageMinecart) mc; - smc.getInventory().setContents(((StorageMinecart) vehicle).getInventory().getContents()); + if (mineCart instanceof StorageMinecart) { + StorageMinecart storageMinecart = (StorageMinecart) mineCart; + storageMinecart.getInventory().setContents(((StorageMinecart) vehicle).getInventory().getContents()); } - mc.setVelocity(newVelocity); + Stargate.log.info(Stargate.getString("prefix") + "Teleported minecart to " + mineCart.getLocation()); vehicle.remove(); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> { + mineCart.setVelocity(newVelocity); + }, 1); } } @@ -575,6 +587,26 @@ public class Portal { return getWorld().isChunkLoaded(topLeft.getBlock().getChunk()); } + public BlockLocation getId() { + return this.id; + } + + public int getModX() { + return this.modX; + } + + public int getModZ() { + return this.modZ; + } + + public float getRotX() { + return this.rotX; + } + + public BlockLocation getTopLeft() { + return this.topLeft; + } + public boolean isVerified() { verified = true; if (!Stargate.verifyPortals) { @@ -600,46 +632,18 @@ public class Portal { return gate.matches(topLeft, modX, modZ); } - public ArrayList getDestinations(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(getName())) continue; - // Check if dest is a fixed gate not pointing to this gate - if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(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; - // Visible to this player. - if (Stargate.canSee(player, portal)) { - destinations.add(portal.getName()); - } - } - return destinations; - } - public boolean activate(Player player) { destinations.clear(); destination = ""; Stargate.activeList.add(this); activePlayer = player; String network = getNetwork(); - destinations = getDestinations(player, network); + destinations = PortalHandler.getDestinations(player, network); if (Stargate.sortLists) { Collections.sort(destinations); } - if (Stargate.destMemory && !lastDest.isEmpty() && destinations.contains(lastDest)) { - destination = lastDest; + if (Stargate.destMemory && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { + destination = lastDestination; } StargateActivateEvent event = new StargateActivateEvent(this, player, destinations, destination); @@ -684,7 +688,7 @@ public class Portal { if (!activate(player)) { return; } - Stargate.debug("cycleDestination", "Network Size: " + allPortalsNet.get(network.toLowerCase()).size()); + Stargate.debug("cycleDestination", "Network Size: " + PortalHandler.getNetwork(network).size()); Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); activate = true; } @@ -694,7 +698,7 @@ public class Portal { return; } - if (!Stargate.destMemory || !activate || lastDest.isEmpty()) { + if (!Stargate.destMemory || !activate || lastDestination.isEmpty()) { int index = destinations.indexOf(destination); index += dir; if (index >= destinations.size()) @@ -702,7 +706,7 @@ public class Portal { else if (index < 0) index = destinations.size() - 1; destination = destinations.get(index); - lastDest = destination; + lastDestination = destination; } openTime = System.currentTimeMillis() / 1000; drawSign(); @@ -743,7 +747,7 @@ public class Portal { } else { Stargate.setLine(sign, ++done, "(" + network + ")"); } - Portal dest = Portal.getByName(destination, network); + Portal dest = PortalHandler.getByName(destination, network); if (dest == null && !isRandom()) { Stargate.setLine(sign, ++done, Stargate.getString("signDisconnected")); } else { @@ -753,7 +757,7 @@ public class Portal { int index = destinations.indexOf(destination); if ((index == max) && (max > 1) && (++done <= 3)) { if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index - 2), network); + Portal dest = PortalHandler.getByName(destinations.get(index - 2), network); boolean green = Stargate.isFree(activePlayer, this, dest); Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 2)); } else { @@ -762,7 +766,7 @@ public class Portal { } if ((index > 0) && (++done <= 3)) { if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index - 1), network); + Portal dest = PortalHandler.getByName(destinations.get(index - 1), network); boolean green = Stargate.isFree(activePlayer, this, dest); Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 1)); } else { @@ -771,7 +775,7 @@ public class Portal { } if (++done <= 3) { if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destination, network); + Portal dest = PortalHandler.getByName(destination, network); boolean green = Stargate.isFree(activePlayer, this, dest); Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + ">" + destination + "<"); } else { @@ -780,7 +784,7 @@ public class Portal { } if ((max >= index + 1) && (++done <= 3)) { if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index + 1), network); + Portal dest = PortalHandler.getByName(destinations.get(index + 1), network); boolean green = Stargate.isFree(activePlayer, this, dest); Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 1)); } else { @@ -789,7 +793,7 @@ public class Portal { } if ((max >= index + 2) && (++done <= 3)) { if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = Portal.getByName(destinations.get(index + 2), network); + Portal dest = PortalHandler.getByName(destinations.get(index + 2), network); boolean green = Stargate.isFree(activePlayer, this, dest); Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 2)); } else { @@ -806,683 +810,20 @@ public class Portal { sign.update(); } - public void unregister(boolean removeAll) { - Stargate.debug("Unregister", "Unregistering gate " + getName()); - close(true); - - for (BlockLocation block : getFrame()) { - lookupBlocks.remove(block); - } - // Include the sign and button - lookupBlocks.remove(id); - if (button != null) { - lookupBlocks.remove(button); - } - - lookupControls.remove(id); - if (button != null) - lookupControls.remove(button); - - for (BlockLocation entrance : getEntrances()) { - lookupEntrances.remove(entrance); - } - - if (removeAll) - allPortals.remove(this); - - if (bungee) { - bungeePortals.remove(getName().toLowerCase()); - } else { - lookupNamesNet.get(getNetwork().toLowerCase()).remove(getName().toLowerCase()); - allPortalsNet.get(getNetwork().toLowerCase()).remove(getName().toLowerCase()); - - for (String originName : allPortalsNet.get(getNetwork().toLowerCase())) { - Portal origin = Portal.getByName(originName, getNetwork()); - if (origin == null) continue; - if (!origin.getDestinationName().equalsIgnoreCase(getName())) continue; - if (!origin.isVerified()) continue; - if (origin.isFixed()) origin.drawSign(); - if (origin.isAlwaysOn()) origin.close(true); - } - } - - if (id.getBlock().getBlockData() instanceof WallSign) { - Sign sign = (Sign) id.getBlock().getState(); - sign.setLine(0, getName()); - sign.setLine(1, ""); - sign.setLine(2, ""); - sign.setLine(3, ""); - sign.update(); - } - - saveAllGates(getWorld()); - } - - private BlockLocation getBlockAt(RelativeBlockVector vector) { + BlockLocation getBlockAt(RelativeBlockVector vector) { return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); } - private void register() { - fixed = destination.length() > 0 || random || bungee; - - // Bungee gates are stored in their own list - if (isBungee()) { - bungeePortals.put(getName().toLowerCase(), this); - } else { - // Check if network exists in our network list - if (!lookupNamesNet.containsKey(getNetwork().toLowerCase())) { - Stargate.debug("register", "Network " + getNetwork() + " not in lookupNamesNet, adding"); - lookupNamesNet.put(getNetwork().toLowerCase(), new HashMap<>()); - } - lookupNamesNet.get(getNetwork().toLowerCase()).put(getName().toLowerCase(), this); - - // Check if this network exists - if (!allPortalsNet.containsKey(getNetwork().toLowerCase())) { - Stargate.debug("register", "Network " + getNetwork() + " not in allPortalsNet, adding"); - allPortalsNet.put(getNetwork().toLowerCase(), new ArrayList<>()); - } - allPortalsNet.get(getNetwork().toLowerCase()).add(getName().toLowerCase()); - } - - for (BlockLocation block : getFrame()) { - lookupBlocks.put(block, this); - } - // Include the sign and button - lookupBlocks.put(id, this); - if (button != null) { - lookupBlocks.put(button, this); - } - - lookupControls.put(id, this); - if (button != null) - lookupControls.put(button, this); - - for (BlockLocation entrance : getEntrances()) { - lookupEntrances.put(entrance, this); - } - - allPortals.add(this); - } - - public static Portal createPortal(SignChangeEvent event, Player player) { - BlockLocation id = new BlockLocation(event.getBlock()); - Block idParent = id.getParent(); - if (idParent == null) { - return null; - } - - if (Gate.getGatesByControlBlock(idParent).length == 0) { - return null; - } - - if (Portal.getByBlock(idParent) != null) { - Stargate.debug("createPortal", "idParent belongs to existing gate"); - return null; - } - - BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); - BlockLocation topleft = null; - String name = filterName(event.getLine(0)); - String destName = 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 free = (options.indexOf('f') != -1); - boolean backwards = (options.indexOf('b') != -1); - boolean show = (options.indexOf('s') != -1); - boolean noNetwork = (options.indexOf('n') != -1); - boolean random = (options.indexOf('r') != -1); - boolean bungee = (options.indexOf('u') != -1); - - // Check permissions for options. - if (hidden && !Stargate.canOption(player, "hidden")) { - hidden = false; - } - if (alwaysOn && !Stargate.canOption(player, "alwayson")) { - alwaysOn = false; - } - if (priv && !Stargate.canOption(player, "private")) { - priv = false; - } - if (free && !Stargate.canOption(player, "free")) { - free = false; - } - if (backwards && !Stargate.canOption(player, "backwards")) { - backwards = false; - } - if (show && !Stargate.canOption(player, "show")) { - show = false; - } - if (noNetwork && !Stargate.canOption(player, "nonetwork")) { - noNetwork = false; - } - if (random && !Stargate.canOption(player, "random")) { - random = false; - } - - // Can not create a non-fixed always-on gate. - if (alwaysOn && destName.length() == 0) { - alwaysOn = false; - } - - // Show isn't useful if A is false - if (show && !alwaysOn) { - show = false; - } - - // Random gates are always on and can't be shown - if (random) { - alwaysOn = true; - show = false; - } - - // Bungee gates are always on and don't support Random - if (bungee) { - alwaysOn = true; - random = false; - } - - // Moved the layout check so as to avoid invalid messages when not making a gate - int modX = 0; - int modZ = 0; - float rotX = 0f; - BlockFace buttonfacing = BlockFace.DOWN; - - if (idParent.getX() > id.getBlock().getX()) { - modZ -= 1; - rotX = 90f; - buttonfacing = BlockFace.WEST; - } else if (idParent.getX() < id.getBlock().getX()) { - modZ += 1; - rotX = 270f; - buttonfacing = BlockFace.EAST; - } else if (idParent.getZ() > id.getBlock().getZ()) { - modX += 1; - rotX = 180f; - buttonfacing = BlockFace.NORTH; - } else if (idParent.getZ() < id.getBlock().getZ()) { - modX -= 1; - rotX = 0f; - buttonfacing = BlockFace.SOUTH; - } - - Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); - Gate gate = null; - RelativeBlockVector buttonVector = null; - - for (Gate possibility : possibleGates) { - if (gate != null || buttonVector != null) { - break; - } - RelativeBlockVector[] vectors = possibility.getControls(); - RelativeBlockVector otherControl = null; - - for (RelativeBlockVector vector : vectors) { - BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); - - if (gate == null) { - if (possibility.matches(tl, modX, modZ, true)) { - gate = possibility; - topleft = tl; - - if (otherControl != null) { - buttonVector = otherControl; - } - } - } else if (otherControl != null) { - buttonVector = vector; - } - - otherControl = vector; - } - } - - if ((gate == null) || (buttonVector == null)) { - Stargate.debug("createPortal", "Could not find matching gate layout"); - return null; - } - - // If the player is trying to create a Bungee gate without permissions, drop out here - // Do this after the gate layout check, in the least - if (bungee) { - if (!Stargate.enableBungee) { - Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); - return null; - } else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { - Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); - return null; - } else if (destName.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); - - if (!bungee && (network.length() < 1 || network.length() > 11)) { - network = Stargate.getDefaultNetwork(); - } - - boolean deny = false; - String denyMsg = ""; - - // Check if the player can create gates on this network - if (!bungee && !Stargate.canCreate(player, network)) { - Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); - if (Stargate.canCreatePersonal(player)) { - network = player.getName(); - if (network.length() > 11) network = network.substring(0, 11); - Stargate.debug("createPortal", "Creating personal portal"); - Stargate.sendMessage(player, Stargate.getString("createPersonal")); - } else { - Stargate.debug("createPortal", "Player does not have access to network"); - deny = true; - denyMsg = Stargate.getString("createNetDeny"); - //return null; - } - } - - // Check if the player can create this gate layout - String gateName = gate.getFilename(); - gateName = gateName.substring(0, gateName.indexOf('.')); - if (!deny && !Stargate.canCreateGate(player, gateName)) { - Stargate.debug("createPortal", "Player does not have access to gate layout"); - deny = true; - denyMsg = Stargate.getString("createGateDeny"); - } - - // Check if the user can create gates to this world. - if (!bungee && !deny && destName.length() > 0) { - Portal p = Portal.getByName(destName, network); - if (p != null) { - String world = p.getWorld().getName(); - if (!Stargate.canAccessWorld(player, world)) { - Stargate.debug("canCreate", "Player does not have access to destination world"); - deny = true; - denyMsg = Stargate.getString("createWorldDeny"); - } - } - } - - // 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); - if (Portal.getByBlock(b.getBlock()) != null) { - Stargate.debug("createPortal", "Gate conflicts with existing gate"); - Stargate.sendMessage(player, Stargate.getString("createConflict")); - return null; - } - } - - 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); - - int cost = Stargate.getCreateCost(player, gate); - - // Call StargateCreateEvent - StargateCreateEvent cEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); - Stargate.server.getPluginManager().callEvent(cEvent); - if (cEvent.isCancelled()) { - return null; - } - if (cEvent.getDeny()) { - Stargate.sendMessage(player, cEvent.getDenyReason()); - return null; - } - - cost = cEvent.getCost(); - - // Name & Network can be changed in the event, so do these checks here. - if (portal.getName().length() < 1 || portal.getName().length() > 11) { - Stargate.debug("createPortal", "Name length error"); - Stargate.sendMessage(player, Stargate.getString("createNameLength")); - return null; - } - - // Don't do network checks for bungee gates - if (portal.isBungee()) { - if (bungeePortals.get(portal.getName().toLowerCase()) != null) { - Stargate.debug("createPortal::Bungee", "Gate Exists"); - Stargate.sendMessage(player, Stargate.getString("createExists")); - return null; - } - } else { - if (getByName(portal.getName(), portal.getNetwork()) != null) { - Stargate.debug("createPortal", "Name Error"); - Stargate.sendMessage(player, Stargate.getString("createExists")); - return null; - } - - // Check if there are too many gates in this network - ArrayList netList = allPortalsNet.get(portal.getNetwork().toLowerCase()); - if (Stargate.maxGates > 0 && netList != null && netList.size() >= Stargate.maxGates) { - Stargate.sendMessage(player, Stargate.getString("createFull")); - return null; - } - } - - if (cost > 0) { - if (!Stargate.chargePlayer(player, cost)) { - String inFundMsg = Stargate.getString("ecoInFunds"); - inFundMsg = Stargate.replaceVars(inFundMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), name}); - Stargate.sendMessage(player, inFundMsg); - Stargate.debug("createPortal", "Insufficient Funds"); - return null; - } - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), name}); - Stargate.sendMessage(player, deductMsg, false); - } - - // No button on an always-open gate. - if (!alwaysOn) { - button = topleft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); - Directional buttondata = (Directional) Bukkit.createBlockData(gate.getButton()); - buttondata.setFacing(buttonfacing); - button.getBlock().setBlockData(buttondata); - portal.setButton(button); - } - - portal.register(); - portal.drawSign(); - // Open always on gate - if (portal.isRandom() || portal.isBungee()) { - portal.open(true); - } else if (portal.isAlwaysOn()) { - Portal dest = Portal.getByName(destName, portal.getNetwork()); - if (dest != null) { - portal.open(true); - dest.drawSign(); - } - // Set the inside of the gate to its closed material - } else { - for (BlockLocation inside : portal.getEntrances()) { - inside.setType(portal.getGate().getPortalBlockClosed()); - } - } - - // Don't do network stuff for bungee gates - if (!portal.isBungee()) { - // Open any always on gate pointing at this gate - for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { - Portal origin = Portal.getByName(originName, portal.getNetwork()); - if (origin == null) continue; - if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; - if (!origin.isVerified()) continue; - if (origin.isFixed()) origin.drawSign(); - if (origin.isAlwaysOn()) origin.open(true); - } - } - - saveAllGates(portal.getWorld()); - - return portal; - } - - public static Portal getByName(String name, String network) { - if (!lookupNamesNet.containsKey(network.toLowerCase())) return null; - return lookupNamesNet.get(network.toLowerCase()).get(name.toLowerCase()); - - } - - public static Portal getByEntrance(Location location) { - return lookupEntrances.get(new BlockLocation(location.getWorld(), location.getBlockX(), location.getBlockY(), - location.getBlockZ())); - } - - public static Portal getByEntrance(Block block) { - return lookupEntrances.get(new BlockLocation(block)); - } - - public static Portal getByAdjacentEntrance(Location loc) { - int centerX = loc.getBlockX(); - int centerY = loc.getBlockY(); - int centerZ = loc.getBlockZ(); - World world = loc.getWorld(); - Portal portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX + 1, centerY, centerZ)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX - 1, centerY, centerZ)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ + 1)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ - 1)); - if (portal != null) { - return portal; - } - return null; - } - - public static Portal getByControl(Block block) { - return lookupControls.get(new BlockLocation(block)); - } - - public static Portal getByBlock(Block block) { - return lookupBlocks.get(new BlockLocation(block)); - } - - public static Portal getBungeeGate(String name) { - return bungeePortals.get(name.toLowerCase()); - } - - public static void saveAllGates(World world) { - Stargate.managedWorlds.add(world.getName()); - String loc = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; - - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(loc, false)); - - for (Portal portal : allPortals) { - String wName = portal.world.getName(); - if (!wName.equalsIgnoreCase(world.getName())) continue; - StringBuilder builder = new StringBuilder(); - BlockLocation button = portal.button; - - builder.append(portal.name); - builder.append(':'); - builder.append(portal.id.toString()); - builder.append(':'); - builder.append((button != null) ? button.toString() : ""); - builder.append(':'); - builder.append(portal.modX); - builder.append(':'); - builder.append(portal.modZ); - builder.append(':'); - builder.append(portal.rotX); - builder.append(':'); - builder.append(portal.topLeft.toString()); - builder.append(':'); - builder.append(portal.gate.getFilename()); - builder.append(':'); - builder.append(portal.isFixed() ? portal.getDestinationName() : ""); - builder.append(':'); - builder.append(portal.getNetwork()); - builder.append(':'); - UUID owner = portal.getOwnerUUID(); - if (owner != null) { - builder.append(portal.getOwnerUUID().toString()); - } else { - builder.append(portal.getOwnerName()); - } - builder.append(':'); - builder.append(portal.isHidden()); - builder.append(':'); - builder.append(portal.isAlwaysOn()); - builder.append(':'); - builder.append(portal.isPrivate()); - builder.append(':'); - builder.append(portal.world.getName()); - builder.append(':'); - builder.append(portal.isFree()); - builder.append(':'); - builder.append(portal.isBackwards()); - builder.append(':'); - builder.append(portal.isShown()); - builder.append(':'); - builder.append(portal.isNoNetwork()); - builder.append(':'); - builder.append(portal.isRandom()); - builder.append(':'); - builder.append(portal.isBungee()); - - bw.append(builder.toString()); - bw.newLine(); - } - - bw.close(); - } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); - } - } - - public static void clearGates() { - lookupBlocks.clear(); - lookupNamesNet.clear(); - lookupEntrances.clear(); - lookupControls.clear(); - allPortals.clear(); - allPortalsNet.clear(); - } - - public static boolean loadAllGates(World world) { - String location = Stargate.getSaveLocation(); - - File db = new File(location, world.getName() + ".db"); - - if (db.exists()) { - int l = 0; - int portalCount = 0; - try { - Scanner scanner = new Scanner(db); - while (scanner.hasNextLine()) { - l++; - String line = scanner.nextLine().trim(); - if (line.startsWith("#") || line.isEmpty()) { - continue; - } - String[] split = line.split(":"); - if (split.length < 8) { - Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + l); - continue; - } - String name = split[0]; - BlockLocation sign = new BlockLocation(world, split[1]); - BlockLocation button = (split[2].length() > 0) ? new BlockLocation(world, split[2]) : null; - int modX = Integer.parseInt(split[3]); - int modZ = Integer.parseInt(split[4]); - float rotX = Float.parseFloat(split[5]); - BlockLocation topLeft = new BlockLocation(world, split[6]); - Gate gate = Gate.getGateByName(split[7]); - if (gate == null) { - Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + l + " does not exist [" + split[7] + "]"); - continue; - } - - String dest = (split.length > 8) ? split[8] : ""; - String network = (split.length > 9) ? split[9] : Stargate.getDefaultNetwork(); - if (network.isEmpty()) network = Stargate.getDefaultNetwork(); - String ownerString = (split.length > 10) ? split[10] : ""; - boolean hidden = (split.length > 11) && split[11].equalsIgnoreCase("true"); - boolean alwaysOn = (split.length > 12) && split[12].equalsIgnoreCase("true"); - boolean priv = (split.length > 13) && split[13].equalsIgnoreCase("true"); - boolean free = (split.length > 15) && split[15].equalsIgnoreCase("true"); - boolean backwards = (split.length > 16) && split[16].equalsIgnoreCase("true"); - boolean show = (split.length > 17) && split[17].equalsIgnoreCase("true"); - boolean noNetwork = (split.length > 18) && split[18].equalsIgnoreCase("true"); - boolean random = (split.length > 19) && split[19].equalsIgnoreCase("true"); - boolean bungee = (split.length > 20) && split[20].equalsIgnoreCase("true"); - - // Attempt to get owner as UUID - UUID ownerUUID = null; - String ownerName; - if (ownerString.length() > 16) { - try { - ownerUUID = UUID.fromString(ownerString); - OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); - ownerName = offlineOwner.getName(); - } catch (IllegalArgumentException ex) { - // neither name nor UUID, so keep it as-is - ownerName = ownerString; - Stargate.debug("loadAllGates", "Invalid stargate owner string: " + ownerString); - } - } else { - ownerName = ownerString; - } - - Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, dest, name, false, network, gate, ownerUUID, ownerName, hidden, alwaysOn, priv, free, backwards, show, noNetwork, random, bungee); - portal.register(); - portal.close(true); - } - scanner.close(); - - // Open any always-on gates. Do this here as it should be more efficient than in the loop. - int OpenCount = 0; - for (Iterator iter = allPortals.iterator(); iter.hasNext(); ) { - Portal portal = iter.next(); - if (portal == null) continue; - - // Verify portal integrity/register portal - if (!portal.wasVerified()) { - if (!portal.isVerified() || !portal.checkIntegrity()) { - // DEBUG - for (RelativeBlockVector control : portal.getGate().getControls()) { - if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { - Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); - } - } - portal.unregister(false); - iter.remove(); - Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal.toString()); - continue; - } - } - portalCount++; - - if (portal.isFixed() && (Stargate.enableBungee && portal.isBungee() - || portal.getDestination() != null && portal.isAlwaysOn())) { - portal.open(true); - OpenCount++; - } - } - Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} Loaded " + portalCount + " stargates with " + OpenCount + " set as always-on"); - return true; - } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + db.getName() + ": " + l); - e.printStackTrace(); - } - } else { - Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); - } - return false; - } - - public static void closeAllGates() { - Stargate.log.info("Closing all stargates."); - for (Portal p : allPortals) { - if (p == null) continue; - p.close(true); - } - } - + /** + * Removes the special characters |, : and # from a portal name + * @param input

The name to filter

+ * @return

The filtered name

+ */ public static String filterName(String input) { if (input == null) { return ""; } - return input.replaceAll("[\\|:#]", "").trim(); + return input.replaceAll("[|:#]", "").trim(); } @Override diff --git a/src/main/java/net/knarcraft/stargate/PortalHandler.java b/src/main/java/net/knarcraft/stargate/PortalHandler.java new file mode 100644 index 0000000..d20aaa3 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/PortalHandler.java @@ -0,0 +1,865 @@ +package net.knarcraft.stargate; + +import net.knarcraft.stargate.event.StargateCreateEvent; +import net.knarcraft.stargate.utility.EconomyHelper; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.Player; +import org.bukkit.event.block.SignChangeEvent; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.UUID; +import java.util.logging.Level; + +public class PortalHandler { + // Static variables used to store portal lists + private static final Map lookupBlocks = new HashMap<>(); + private static final Map lookupEntrances = new HashMap<>(); + private static final Map lookupControls = new HashMap<>(); + private static final List allPortals = new ArrayList<>(); + private static final HashMap> allPortalsNet = new HashMap<>(); + private static final HashMap> lookupNamesNet = new HashMap<>(); + + // A list of Bungee gates + private static final Map bungeePortals = new HashMap<>(); + + public static List getNetwork(String network) { + return allPortalsNet.get(network.toLowerCase()); + } + + /** + * Gets all destinations in the network viewable by the given player + * @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) { + 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; + // 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; + // Visible to this player. + if (Stargate.canSee(player, portal)) { + destinations.add(portal.getName()); + } + } + return destinations; + } + + /** + * Un-registers the given portal + * @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) { + Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); + portal.close(true); + + for (BlockLocation block : portal.getFrame()) { + lookupBlocks.remove(block); + } + // Include the sign and button + lookupBlocks.remove(portal.getId()); + lookupControls.remove(portal.getId()); + if (portal.getButton() != null) { + lookupBlocks.remove(portal.getButton()); + lookupControls.remove(portal.getButton()); + } + + for (BlockLocation entrance : portal.getEntrances()) { + lookupEntrances.remove(entrance); + } + + if (removeAll) { + allPortals.remove(portal); + } + + if (portal.isBungee()) { + bungeePortals.remove(portal.getName().toLowerCase()); + } else { + lookupNamesNet.get(portal.getNetwork().toLowerCase()).remove(portal.getName().toLowerCase()); + allPortalsNet.get(portal.getNetwork().toLowerCase()).remove(portal.getName().toLowerCase()); + + for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { + Portal origin = getByName(originName, portal.getNetwork()); + if (origin == null) continue; + if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; + if (!origin.isVerified()) continue; + if (origin.isFixed()) origin.drawSign(); + if (origin.isAlwaysOn()) origin.close(true); + } + } + + if (portal.getId().getBlock().getBlockData() instanceof WallSign) { + Sign sign = (Sign) portal.getId().getBlock().getState(); + sign.setLine(0, portal.getName()); + sign.setLine(1, ""); + sign.setLine(2, ""); + sign.setLine(3, ""); + sign.update(); + } + + saveAllGates(portal.getWorld()); + } + + /** + * Registers a portal + * @param portal

The portal to register

+ */ + static void register(Portal portal) { + portal.setFixed(portal.getDestinationName().length() > 0 || portal.isRandom() || portal.isBungee()); + + // Bungee gates are stored in their own list + if (portal.isBungee()) { + bungeePortals.put(portal.getName().toLowerCase(), portal); + } else { + // Check if network exists in our network list + if (!lookupNamesNet.containsKey(portal.getNetwork().toLowerCase())) { + Stargate.debug("register", "Network " + portal.getNetwork() + " not in lookupNamesNet, adding"); + lookupNamesNet.put(portal.getNetwork().toLowerCase(), new HashMap<>()); + } + lookupNamesNet.get(portal.getNetwork().toLowerCase()).put(portal.getName().toLowerCase(), portal); + + // Check if this network exists + if (!allPortalsNet.containsKey(portal.getNetwork().toLowerCase())) { + Stargate.debug("register", "Network " + portal.getNetwork() + " not in allPortalsNet, adding"); + allPortalsNet.put(portal.getNetwork().toLowerCase(), new ArrayList<>()); + } + allPortalsNet.get(portal.getNetwork().toLowerCase()).add(portal.getName().toLowerCase()); + } + + for (BlockLocation block : portal.getFrame()) { + lookupBlocks.put(block, portal); + } + // Include the sign and button + lookupBlocks.put(portal.getId(), portal); + lookupControls.put(portal.getId(), portal); + if (portal.getButton() != null) { + lookupBlocks.put(portal.getButton(), portal); + lookupControls.put(portal.getButton(), portal); + } + + + for (BlockLocation entrance : portal.getEntrances()) { + lookupEntrances.put(entrance, portal); + } + + allPortals.add(portal); + } + + /** + * Creates a new portal + * @param event

The sign change event which initialized the creation

+ * @param player

The player who's creating the portal

+ * @return

The created portal

+ */ + public static Portal createPortal(SignChangeEvent event, Player player) { + BlockLocation id = new BlockLocation(event.getBlock()); + Block idParent = id.getParent(); + if (idParent == null) { + return null; + } + + if (Gate.getGatesByControlBlock(idParent).length == 0) { + return null; + } + + if (getByBlock(idParent) != null) { + Stargate.debug("createPortal", "idParent belongs to existing gate"); + return null; + } + + BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); + BlockLocation topleft = null; + String name = filterName(event.getLine(0)); + String destName = 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 free = (options.indexOf('f') != -1); + boolean backwards = (options.indexOf('b') != -1); + boolean show = (options.indexOf('s') != -1); + boolean noNetwork = (options.indexOf('n') != -1); + boolean random = (options.indexOf('r') != -1); + boolean bungee = (options.indexOf('u') != -1); + + // Check permissions for options. + if (hidden && !Stargate.canOption(player, "hidden")) { + hidden = false; + } + if (alwaysOn && !Stargate.canOption(player, "alwayson")) { + alwaysOn = false; + } + if (priv && !Stargate.canOption(player, "private")) { + priv = false; + } + if (free && !Stargate.canOption(player, "free")) { + free = false; + } + if (backwards && !Stargate.canOption(player, "backwards")) { + backwards = false; + } + if (show && !Stargate.canOption(player, "show")) { + show = false; + } + if (noNetwork && !Stargate.canOption(player, "nonetwork")) { + noNetwork = false; + } + if (random && !Stargate.canOption(player, "random")) { + random = false; + } + + // Can not create a non-fixed always-on gate. + if (alwaysOn && destName.length() == 0) { + alwaysOn = false; + } + + // Show isn't useful if A is false + if (show && !alwaysOn) { + show = false; + } + + // Random gates are always on and can't be shown + if (random) { + alwaysOn = true; + show = false; + } + + // Bungee gates are always on and don't support Random + if (bungee) { + alwaysOn = true; + random = false; + } + + // Moved the layout check so as to avoid invalid messages when not making a gate + int modX = 0; + int modZ = 0; + float rotX = 0f; + BlockFace buttonfacing = BlockFace.DOWN; + + if (idParent.getX() > id.getBlock().getX()) { + modZ -= 1; + rotX = 90f; + buttonfacing = BlockFace.WEST; + } else if (idParent.getX() < id.getBlock().getX()) { + modZ += 1; + rotX = 270f; + buttonfacing = BlockFace.EAST; + } else if (idParent.getZ() > id.getBlock().getZ()) { + modX += 1; + rotX = 180f; + buttonfacing = BlockFace.NORTH; + } else if (idParent.getZ() < id.getBlock().getZ()) { + modX -= 1; + rotX = 0f; + buttonfacing = BlockFace.SOUTH; + } + + Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); + Gate gate = null; + RelativeBlockVector buttonVector = null; + + for (Gate possibility : possibleGates) { + if (gate != null || buttonVector != null) { + break; + } + RelativeBlockVector[] vectors = possibility.getControls(); + RelativeBlockVector otherControl = null; + + for (RelativeBlockVector vector : vectors) { + BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); + + if (gate == null) { + if (possibility.matches(tl, modX, modZ, true)) { + gate = possibility; + topleft = tl; + + if (otherControl != null) { + buttonVector = otherControl; + } + } + } else if (otherControl != null) { + buttonVector = vector; + } + + otherControl = vector; + } + } + + if ((gate == null) || (buttonVector == null)) { + Stargate.debug("createPortal", "Could not find matching gate layout"); + return null; + } + + // If the player is trying to create a Bungee gate without permissions, drop out here + // Do this after the gate layout check, in the least + if (bungee) { + if (!Stargate.enableBungee) { + Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); + return null; + } else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { + Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); + return null; + } else if (destName.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); + + if (!bungee && (network.length() < 1 || network.length() > 11)) { + network = Stargate.getDefaultNetwork(); + } + + boolean deny = false; + String denyMsg = ""; + + // Check if the player can create gates on this network + if (!bungee && !Stargate.canCreate(player, network)) { + Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); + if (Stargate.canCreatePersonal(player)) { + network = player.getName(); + if (network.length() > 11) network = network.substring(0, 11); + Stargate.debug("createPortal", "Creating personal portal"); + Stargate.sendMessage(player, Stargate.getString("createPersonal")); + } else { + Stargate.debug("createPortal", "Player does not have access to network"); + deny = true; + denyMsg = Stargate.getString("createNetDeny"); + //return null; + } + } + + // Check if the player can create this gate layout + String gateName = gate.getFilename(); + gateName = gateName.substring(0, gateName.indexOf('.')); + if (!deny && !Stargate.canCreateGate(player, gateName)) { + Stargate.debug("createPortal", "Player does not have access to gate layout"); + deny = true; + denyMsg = Stargate.getString("createGateDeny"); + } + + // Check if the user can create gates to this world. + if (!bungee && !deny && destName.length() > 0) { + Portal p = getByName(destName, network); + if (p != null) { + String world = p.getWorld().getName(); + if (!Stargate.canAccessWorld(player, world)) { + Stargate.debug("canCreate", "Player does not have access to destination world"); + deny = true; + denyMsg = Stargate.getString("createWorldDeny"); + } + } + } + + // 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); + if (getByBlock(b.getBlock()) != null) { + Stargate.debug("createPortal", "Gate conflicts with existing gate"); + Stargate.sendMessage(player, Stargate.getString("createConflict")); + return null; + } + } + + 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); + + int cost = Stargate.getCreateCost(player, gate); + + // Call StargateCreateEvent + StargateCreateEvent cEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); + Stargate.server.getPluginManager().callEvent(cEvent); + if (cEvent.isCancelled()) { + return null; + } + if (cEvent.getDeny()) { + Stargate.sendMessage(player, cEvent.getDenyReason()); + return null; + } + + cost = cEvent.getCost(); + + // Name & Network can be changed in the event, so do these checks here. + if (portal.getName().length() < 1 || portal.getName().length() > 11) { + Stargate.debug("createPortal", "Name length error"); + Stargate.sendMessage(player, Stargate.getString("createNameLength")); + return null; + } + + // Don't do network checks for bungee gates + if (portal.isBungee()) { + if (bungeePortals.get(portal.getName().toLowerCase()) != null) { + Stargate.debug("createPortal::Bungee", "Gate Exists"); + Stargate.sendMessage(player, Stargate.getString("createExists")); + return null; + } + } else { + if (getByName(portal.getName(), portal.getNetwork()) != null) { + Stargate.debug("createPortal", "Name Error"); + Stargate.sendMessage(player, Stargate.getString("createExists")); + return null; + } + + // Check if there are too many gates in this network + List netList = allPortalsNet.get(portal.getNetwork().toLowerCase()); + if (Stargate.maxGates > 0 && netList != null && netList.size() >= Stargate.maxGates) { + Stargate.sendMessage(player, Stargate.getString("createFull")); + return null; + } + } + + if (cost > 0) { + if (!Stargate.chargePlayer(player, cost)) { + EconomyHelper.sendInsufficientFundsMessage(name, player, cost); + Stargate.debug("createPortal", "Insufficient Funds"); + return null; + } + EconomyHelper.sendDeductMessage(name, player, cost); + } + + // No button on an always-open gate. + if (!alwaysOn) { + button = topleft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); + Directional buttondata = (Directional) Bukkit.createBlockData(gate.getButton()); + buttondata.setFacing(buttonfacing); + button.getBlock().setBlockData(buttondata); + portal.setButton(button); + } + + register(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()); + if (dest != null) { + portal.open(true); + dest.drawSign(); + } + // Set the inside of the gate to its closed material + } else { + for (BlockLocation inside : portal.getEntrances()) { + inside.setType(portal.getGate().getPortalBlockClosed()); + } + } + + // Don't do network stuff for bungee gates + if (!portal.isBungee()) { + // Open any always on gate pointing at this gate + for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { + Portal origin = getByName(originName, portal.getNetwork()); + if (origin == null) continue; + if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; + if (!origin.isVerified()) continue; + if (origin.isFixed()) origin.drawSign(); + if (origin.isAlwaysOn()) origin.open(true); + } + } + + saveAllGates(portal.getWorld()); + + return portal; + } + + /** + * Gets a portal given its name + * @param name

The name of the portal

+ * @param network

The network the portal is connected to

+ * @return

The portal with the given name or null

+ */ + public static Portal getByName(String name, String network) { + if (!lookupNamesNet.containsKey(network.toLowerCase())) { + return null; + } + return lookupNamesNet.get(network.toLowerCase()).get(name.toLowerCase()); + + } + + /** + * Gets a portal given its entrance + * @param location

The location of the portal's entrance

+ * @return

The portal at the given location

+ */ + public static Portal getByEntrance(Location location) { + return lookupEntrances.get(new BlockLocation(location.getWorld(), location.getBlockX(), location.getBlockY(), + location.getBlockZ())); + } + + /** + * Gets a portal given its entrance + * @param block

The block at the portal's entrance

+ * @return

The portal at the given block's location

+ */ + public static Portal getByEntrance(Block block) { + return lookupEntrances.get(new BlockLocation(block)); + } + + /** + * Gets a portal given a location adjacent to its entrance + * @param loc

A location adjacent to the portal's entrance

+ * @return

The portal adjacent to the given location

+ */ + public static Portal getByAdjacentEntrance(Location loc) { + int centerX = loc.getBlockX(); + int centerY = loc.getBlockY(); + int centerZ = loc.getBlockZ(); + World world = loc.getWorld(); + Portal portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX + 1, centerY, centerZ)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX - 1, centerY, centerZ)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ + 1)); + if (portal != null) { + return portal; + } + portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ - 1)); + if (portal != null) { + return portal; + } + return null; + } + + /** + * Gets a portal given its control block (the block type used for the sign and button) + * @param block

The portal's control block

+ * @return

The gate with the given control block

+ */ + public static Portal getByControl(Block block) { + return lookupControls.get(new BlockLocation(block)); + } + + /** + * Gets a portal given a block + * @param block

One of the loaded lookup blocks

+ * @return

The portal corresponding to the block

+ */ + public static Portal getByBlock(Block block) { + return lookupBlocks.get(new BlockLocation(block)); + } + + /** + * Gets a bungee gate given its name + * @param name

The name of the bungee gate to get

+ * @return

A bungee gate

+ */ + public static Portal getBungeeGate(String name) { + return bungeePortals.get(name.toLowerCase()); + } + + /** + * Saves all gates for the given world + * @param world

The world to save gates for

+ */ + public static void saveAllGates(World world) { + Stargate.managedWorlds.add(world.getName()); + String loc = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; + + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(loc, false)); + + for (Portal portal : allPortals) { + String wName = portal.getWorld().getName(); + if (!wName.equalsIgnoreCase(world.getName())) continue; + StringBuilder builder = new StringBuilder(); + BlockLocation button = portal.getButton(); + + builder.append(portal.getName()); + builder.append(':'); + builder.append(portal.getId().toString()); + builder.append(':'); + builder.append((button != null) ? button.toString() : ""); + builder.append(':'); + builder.append(portal.getModX()); + builder.append(':'); + builder.append(portal.getModZ()); + builder.append(':'); + builder.append(portal.getRotX()); + builder.append(':'); + builder.append(portal.getTopLeft().toString()); + builder.append(':'); + builder.append(portal.getGate().getFilename()); + builder.append(':'); + builder.append(portal.isFixed() ? portal.getDestinationName() : ""); + builder.append(':'); + builder.append(portal.getNetwork()); + builder.append(':'); + UUID owner = portal.getOwnerUUID(); + if (owner != null) { + builder.append(portal.getOwnerUUID().toString()); + } else { + builder.append(portal.getOwnerName()); + } + builder.append(':'); + builder.append(portal.isHidden()); + builder.append(':'); + builder.append(portal.isAlwaysOn()); + builder.append(':'); + builder.append(portal.isPrivate()); + builder.append(':'); + builder.append(portal.getWorld().getName()); + builder.append(':'); + builder.append(portal.isFree()); + builder.append(':'); + builder.append(portal.isBackwards()); + builder.append(':'); + builder.append(portal.isShown()); + builder.append(':'); + builder.append(portal.isNoNetwork()); + builder.append(':'); + builder.append(portal.isRandom()); + builder.append(':'); + builder.append(portal.isBungee()); + + bw.append(builder.toString()); + bw.newLine(); + } + + bw.close(); + } catch (Exception e) { + Stargate.log.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); + } + } + + /** + * Clears all loaded gates and gate data + */ + public static void clearGates() { + lookupBlocks.clear(); + lookupNamesNet.clear(); + lookupEntrances.clear(); + lookupControls.clear(); + allPortals.clear(); + allPortalsNet.clear(); + } + + /** + * Loads all gates for the given world + * @param world

The world to load gates for

+ * @return

True if gates could be loaded

+ */ + public static boolean loadAllGates(World world) { + String location = Stargate.getSaveLocation(); + + File database = new File(location, world.getName() + ".db"); + + if (database.exists()) { + return loadGates(world, database); + } else { + Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); + } + return false; + } + + /** + * Loads all the given gates + * @param world

The world to load gates for

+ * @param database

The database file containing the gates

+ * @return

True if the gates were loaded successfully

+ */ + private static boolean loadGates(World world, File database) { + int l = 0; + try { + Scanner scanner = new Scanner(database); + while (scanner.hasNextLine()) { + l++; + String line = scanner.nextLine().trim(); + if (line.startsWith("#") || line.isEmpty()) { + continue; + } + String[] portalData = line.split(":"); + if (portalData.length < 8) { + Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + l); + continue; + } + String name = portalData[0]; + BlockLocation sign = new BlockLocation(world, portalData[1]); + BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; + int modX = Integer.parseInt(portalData[3]); + int modZ = Integer.parseInt(portalData[4]); + float rotX = Float.parseFloat(portalData[5]); + BlockLocation topLeft = new BlockLocation(world, portalData[6]); + Gate gate = Gate.getGateByName(portalData[7]); + if (gate == null) { + Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + l + " does not exist [" + portalData[7] + "]"); + continue; + } + + String destination = (portalData.length > 8) ? portalData[8] : ""; + String network = (portalData.length > 9) ? portalData[9] : Stargate.getDefaultNetwork(); + if (network.isEmpty()) network = Stargate.getDefaultNetwork(); + String ownerString = (portalData.length > 10) ? portalData[10] : ""; + + // Attempt to get owner as UUID + UUID ownerUUID = null; + String ownerName; + if (ownerString.length() > 16) { + try { + ownerUUID = UUID.fromString(ownerString); + OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); + ownerName = offlineOwner.getName(); + } catch (IllegalArgumentException ex) { + // neither name nor UUID, so keep it as-is + ownerName = ownerString; + Stargate.debug("loadAllGates", "Invalid stargate owner string: " + ownerString); + } + } else { + ownerName = ownerString; + } + + //Creates the new portal + Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, destination, name, false, network, + gate, ownerUUID, ownerName); + loadPortalOptions(portal, portalData); + + register(portal); + portal.close(true); + } + scanner.close(); + + // Open any always-on gates. Do this here as it should be more efficient than in the loop. + TwoTuple portalCounts = openAlwaysOpenGates(); + + Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} Loaded " + portalCounts.getSecondValue() + " stargates with " + portalCounts.getFirstValue() + " set as always-on"); + return true; + } catch (Exception e) { + Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + l); + e.printStackTrace(); + } + return false; + } + + /** + * Loads all portal options and updates the given portal + * @param portal

The portal to apply the options to

+ * @param portalData

The string list containing all information about a portal

+ */ + private static void loadPortalOptions(Portal portal, String[] portalData) { + boolean hidden = (portalData.length > 11) && portalData[11].equalsIgnoreCase("true"); + boolean alwaysOn = (portalData.length > 12) && portalData[12].equalsIgnoreCase("true"); + boolean isPrivate = (portalData.length > 13) && portalData[13].equalsIgnoreCase("true"); + boolean free = (portalData.length > 15) && portalData[15].equalsIgnoreCase("true"); + boolean backwards = (portalData.length > 16) && portalData[16].equalsIgnoreCase("true"); + boolean show = (portalData.length > 17) && portalData[17].equalsIgnoreCase("true"); + boolean noNetwork = (portalData.length > 18) && portalData[18].equalsIgnoreCase("true"); + boolean random = (portalData.length > 19) && portalData[19].equalsIgnoreCase("true"); + boolean bungee = (portalData.length > 20) && portalData[20].equalsIgnoreCase("true"); + portal.setHidden(hidden).setAlwaysOn(alwaysOn).setPrivate(isPrivate).setFree(free).setBungee(bungee); + portal.setBackwards(backwards).setShown(show).setNoNetwork(noNetwork).setRandom(random); + } + + /** + * Opens all always open gates + * @return

A TwoTuple where the first value is the number of always open gates and the second value is the total number of gates

+ */ + private static TwoTuple openAlwaysOpenGates() { + int portalCount = 0; + int openCount = 0; + for (Iterator iterator = allPortals.iterator(); iterator.hasNext(); ) { + Portal portal = iterator.next(); + if (portal == null) { + continue; + } + + // Verify portal integrity/register portal + if (!portal.wasVerified() && (!portal.isVerified() || !portal.checkIntegrity())) { + destroyInvalidStarGate(portal); + iterator.remove(); + continue; + } + portalCount++; + + //Open the gate if it's set as always open or if it's a bungee gate + if (portal.isFixed() && (Stargate.enableBungee && portal.isBungee() || portal.getDestination() != null && + portal.isAlwaysOn())) { + portal.open(true); + openCount++; + } + } + return new TwoTuple<>(openCount, portalCount); + } + + /** + * Destroys a star gate which has failed its integrity test + * @param portal

The portal of the star gate

+ */ + private static void destroyInvalidStarGate(Portal portal) { + // DEBUG + for (RelativeBlockVector control : portal.getGate().getControls()) { + if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { + Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); + } + } + PortalHandler.unregister(portal, false); + Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal.toString()); + } + + /** + * Closes all star gate portals + */ + public static void closeAllGates() { + Stargate.log.info("Closing all stargates."); + for (Portal portal : allPortals) { + if (portal != null) { + portal.close(true); + } + } + } + + /** + * Removes the special characters |, : and # from a portal name + * @param input

The name to filter

+ * @return

The filtered name

+ */ + public static String filterName(String input) { + if (input == null) { + return ""; + } + return input.replaceAll("[|:#]", "").trim(); + } +} diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index c3e40f3..3078f2e 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -1,32 +1,22 @@ package net.knarcraft.stargate; /** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . + * This stores a block location as a vector in an alternate coordinate system + * + *

*/ - public class RelativeBlockVector { - private int right = 0; - private int depth = 0; - private int distance = 0; + private int right; + private int depth; + private int distance; + /** + * 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

+ */ public RelativeBlockVector(int right, int depth, int distance) { this.right = right; this.depth = depth; diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 4d3a0b5..6f1b808 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -24,6 +24,7 @@ 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; @@ -36,27 +37,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; import java.util.logging.Logger; -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011 Shaun (sturmeh) - * Copyright (C) 2011 Dinnerbone - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - @SuppressWarnings("unused") public class Stargate extends JavaPlugin { @@ -121,8 +101,8 @@ public class Stargate extends JavaPlugin { @Override public void onDisable() { - Portal.closeAllGates(); - Portal.clearGates(); + PortalHandler.closeAllGates(); + PortalHandler.clearGates(); managedWorlds.clear(); getServer().getScheduler().cancelTasks(this); } @@ -251,7 +231,7 @@ public class Stargate extends JavaPlugin { public void loadAllPortals() { for (World world : getServer().getWorlds()) { if (!managedWorlds.contains(world.getName())) { - Portal.loadAllGates(world); + PortalHandler.loadAllGates(world); managedWorlds.add(world.getName()); } } @@ -261,11 +241,15 @@ public class Stargate extends JavaPlugin { // Only migrate if new file doesn't exist. File newPortalDir = new File(portalFolder); if (!newPortalDir.exists()) { - newPortalDir.mkdirs(); + if (!newPortalDir.mkdirs()) { + log.severe("Unable to create portal directory"); + } } File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); if (!newFile.exists()) { - newFile.getParentFile().mkdirs(); + if (!newFile.getParentFile().mkdirs()) { + log.severe("Unable to create portal directory"); + } } } @@ -652,7 +636,7 @@ public class Stargate extends JavaPlugin { @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + 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; @@ -680,7 +664,7 @@ public class Stargate extends JavaPlugin { activeList.clear(); openList.clear(); managedWorlds.clear(); - Portal.clearGates(); + PortalHandler.clearGates(); Gate.clearGates(); // Store the old Bungee enabled value diff --git a/src/main/java/net/knarcraft/stargate/TwoTuple.java b/src/main/java/net/knarcraft/stargate/TwoTuple.java new file mode 100644 index 0000000..f2a8593 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/TwoTuple.java @@ -0,0 +1,39 @@ +package net.knarcraft.stargate; + +/** + * This class allows storing two values of any type + * @param

The first type

+ * @param

The second type

+ */ +public class TwoTuple { + + private K firstValue; + private L secondValue; + + /** + * Instantiate a new TwoTuple + * @param firstValue

The first value

+ * @param secondValue

The second value

+ */ + public TwoTuple(K firstValue, L secondValue) { + this.firstValue = firstValue; + this.secondValue = secondValue; + } + + /** + * Gets the first value + * @return

The first value

+ */ + public K getFirstValue() { + return firstValue; + } + + /** + * Gets the second value + * @return

The second value

+ */ + public L getSecondValue() { + return secondValue; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 07d58a3..919ff6d 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -4,26 +4,6 @@ import net.knarcraft.stargate.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; -/* - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - - @SuppressWarnings("unused") public class StargateAccessEvent extends StargateEvent { @@ -32,15 +12,21 @@ public class StargateAccessEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); - @Override - public HandlerList getHandlers() { - return handlers; - } + /** + * Gets a handler-list containing all event handlers + * @return

A handler-list with all event handlers

+ */ public static HandlerList getHandlerList() { return handlers; } - + + /** + * Instantiates a new stargate access event + * @param player

The player involved in the vent

+ * @param portal

The portal involved in the event

+ * @param deny

Whether the event should be denied

+ */ public StargateAccessEvent(Player player, Portal portal, boolean deny) { super("StargateAccessEvent", portal); @@ -63,9 +49,17 @@ public class StargateAccessEvent extends StargateEvent { public void setDeny(boolean deny) { this.deny = deny; } - + + /** + * Gets the player involved in this stargate access event + * @return

The player involved in this event

+ */ public Player getPlayer() { return this.player; } + @Override + public @org.jetbrains.annotations.NotNull HandlerList getHandlers() { + return handlers; + } } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index c66a65f..085c622 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -3,28 +3,10 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - public class StargateActivateEvent extends StargateEvent { private final Player player; @@ -33,6 +15,7 @@ public class StargateActivateEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index 89d586e..070a4b3 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -2,25 +2,7 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.event.HandlerList; - -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ +import org.jetbrains.annotations.NotNull; public class StargateCloseEvent extends StargateEvent { @@ -28,6 +10,7 @@ public class StargateCloseEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java index eed8d74..bba2060 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -3,25 +3,7 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; - -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ +import org.jetbrains.annotations.NotNull; public class StargateCreateEvent extends StargateEvent { @@ -33,6 +15,7 @@ public class StargateCreateEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index 41b061e..922e68f 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -2,30 +2,13 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.event.HandlerList; - -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ +import org.jetbrains.annotations.NotNull; public class StargateDeactivateEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index 227e0c5..9d4f965 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -3,26 +3,11 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; /** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . + * This event represents an event where a star gate is destroyed or attempted to be destroyed */ - public class StargateDestroyEvent extends StargateEvent { private final Player player; @@ -32,14 +17,27 @@ public class StargateDestroyEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } + /** + * Gets a handler-list containing all event handlers + * @return

A handler-list with all event handlers

+ */ public static HandlerList getHandlerList() { return handlers; } + /** + * Instantiates a new Stargate Destroy Event + * @param portal

The portal destroyed

+ * @param player

The player destroying the portal

+ * @param deny

Whether the event should be denied (cancelled)

+ * @param denyMsg

The message to display if the event is denied

+ * @param cost

The cost of destroying the portal

+ */ public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { super("StargateDestroyEvent", portal); this.player = player; @@ -48,30 +46,58 @@ public class StargateDestroyEvent extends StargateEvent { this.cost = cost; } + /** + * Gets the player causing the destroy event + * @return

The player causing the destroy event

+ */ public Player getPlayer() { return player; } + /** + * Gets whether this event should be denied + * @return

Whether this event should be denied

+ */ public boolean getDeny() { return deny; } + /** + * Sets whether this event should be denied + * @param deny

Whether this event should be denied

+ */ public void setDeny(boolean deny) { this.deny = deny; } + /** + * Gets the reason the event was denied + * @return

The reason the event was denied

+ */ public String getDenyReason() { return denyReason; } + /** + * Sets the reason the event was denied + * @param denyReason

The reason the event was denied

+ */ public void setDenyReason(String denyReason) { this.denyReason = denyReason; } + /** + * Gets the cost of destroying the portal + * @return

The cost of destroying the portal

+ */ public int getCost() { return cost; } + /** + * Sets the cost of destroying the portal + * @param cost

The cost of destroying the portal

+ */ public void setCost(int cost) { this.cost = cost; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index a3a40ce..1dbc915 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -4,25 +4,6 @@ import net.knarcraft.stargate.Portal; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; -/* - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - /** * An abstract event describing any stargate event */ @@ -37,6 +18,7 @@ public abstract class StargateEvent extends Event implements Cancellable { this.cancelled = false; } + public Portal getPortal() { return portal; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index 180b700..75a3bf4 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -3,25 +3,7 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; - -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ +import org.jetbrains.annotations.NotNull; public class StargateOpenEvent extends StargateEvent { @@ -30,6 +12,7 @@ public class StargateOpenEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java index 2a3a537..3b46461 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java @@ -4,25 +4,7 @@ import net.knarcraft.stargate.Portal; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; - -/** - * stargate - A portal plugin for Bukkit - * Copyright (C) 2011, 2012 Steven "Drakia" Scott - * Copyright (C) 2021 Kristian Knarvik - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *

- * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ +import org.jetbrains.annotations.NotNull; public class StargatePortalEvent extends StargateEvent { @@ -32,6 +14,7 @@ public class StargatePortalEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); + @NotNull public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 90b2703..2bbe2cd 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -1,9 +1,10 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.EconomyHandler; import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateDestroyEvent; +import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; import org.bukkit.block.Block; @@ -22,7 +23,17 @@ import org.bukkit.event.block.SignChangeEvent; import java.util.List; +/** + * This class is responsible for listening to relevant block events related to creating and breaking portals + */ +@SuppressWarnings("unused") public class BlockEventListener implements Listener { + + /** + * Detects sign changes to detect if the user is creating a new gate + * + * @param event

The triggered event

+ */ @EventHandler public void onSignChange(SignChangeEvent event) { if (event.isCancelled()) { @@ -30,11 +41,12 @@ public class BlockEventListener implements Listener { } Player player = event.getPlayer(); Block block = event.getBlock(); + //Ignore normal signs if (!(block.getBlockData() instanceof WallSign)) { return; } - final Portal portal = Portal.createPortal(event, player); + final Portal portal = PortalHandler.createPortal(event, player); // Not creating a gate, just placing a sign if (portal == null) { return; @@ -42,69 +54,94 @@ public class BlockEventListener implements Listener { Stargate.sendMessage(player, Stargate.getString("createMsg"), false); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> portal.drawSign(), 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); } // Switch to HIGHEST priority so as to come after block protection plugins (Hopefully) @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled()) return; + if (event.isCancelled()) { + return; + } Block block = event.getBlock(); Player player = event.getPlayer(); - Portal portal = Portal.getByBlock(block); - if (portal == null && Stargate.protectEntrance) - portal = Portal.getByEntrance(block); - if (portal == null) return; + //Decide if a portal is broken + Portal portal = PortalHandler.getByBlock(block); + if (portal == null && Stargate.protectEntrance) { + portal = PortalHandler.getByEntrance(block); + } + if (portal == null) { + return; + } boolean deny = false; String denyMsg = ""; + //Decide if the user can destroy the portal if (!Stargate.canDestroy(player, portal)) { - denyMsg = "Permission Denied"; // TODO: Change to stargate.getString() + denyMsg = Stargate.getString("denyMsg"); deny = true; Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); } int cost = Stargate.getDestroyCost(player, portal.getGate()); + //Create and call a StarGateDestroyEvent StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); Stargate.server.getPluginManager().callEvent(destroyEvent); if (destroyEvent.isCancelled()) { event.setCancelled(true); return; } + + //Destroy denied if (destroyEvent.getDeny()) { Stargate.sendMessage(player, destroyEvent.getDenyReason()); event.setCancelled(true); return; } - cost = destroyEvent.getCost(); - - if (cost != 0) { - if (!Stargate.chargePlayer(player, cost)) { - Stargate.debug("onBlockBreak", "Insufficient Funds"); - Stargate.sendMessage(player, Stargate.getString("inFunds")); - event.setCancelled(true); - return; - } - - if (cost > 0) { - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); - Stargate.sendMessage(player, deductMsg, false); - } else { - String refundMsg = Stargate.getString("ecoRefund"); - refundMsg = Stargate.replaceVars(refundMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(-cost), portal.getName()}); - Stargate.sendMessage(player, refundMsg, false); - } + //Take care of payment transactions + if (!handleEconomyPayment(destroyEvent, player, portal, event)) { + return; } - portal.unregister(true); + PortalHandler.unregister(portal, true); Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); } + /** + * Handles economy payment for breaking the portal + * @param destroyEvent

The destroy event

+ * @param player

The player which triggered the event

+ * @param portal

The broken portal

+ * @param event

The break event

+ * @return

True if the payment was successful. False if the event was cancelled

+ */ + private boolean handleEconomyPayment(StargateDestroyEvent destroyEvent, Player player, Portal portal, + BlockBreakEvent event) { + int cost = destroyEvent.getCost(); + if (cost != 0) { + if (!Stargate.chargePlayer(player, cost)) { + Stargate.debug("onBlockBreak", "Insufficient Funds"); + EconomyHelper.sendInsufficientFundsMessage(portal.getName(), player, cost); + event.setCancelled(true); + return false; + } + if (cost > 0) { + EconomyHelper.sendDeductMessage(portal.getName(), player, cost); + } else { + EconomyHelper.sendRefundMessage(portal.getName(), player, cost); + } + } + return true; + } + + /** + * Prevents any block physics events which may damage parts of the portal + * @param event

The event to check and possibly cancel

+ */ @EventHandler public void onBlockPhysics(BlockPhysicsEvent event) { Block block = event.getBlock(); @@ -112,27 +149,44 @@ public class BlockEventListener implements Listener { // Handle keeping portal material and buttons around if (block.getType() == Material.NETHER_PORTAL) { - portal = Portal.getByEntrance(block); + portal = PortalHandler.getByEntrance(block); } else if (MaterialHelper.isButtonCompatible(block.getType())) { - portal = Portal.getByControl(block); + portal = PortalHandler.getByControl(block); + } + if (portal != null) { + event.setCancelled(true); } - if (portal != null) event.setCancelled(true); } + /** + * Cancels any block move events which may cause a block to enter the opening of a portal + * + * @param event

The event to check and possibly cancel

+ */ @EventHandler public void onBlockFromTo(BlockFromToEvent event) { - Portal portal = Portal.getByEntrance(event.getBlock()); + Portal portal = PortalHandler.getByEntrance(event.getBlock()); if (portal != null) { event.setCancelled((event.getBlock().getY() == event.getToBlock().getY())); } } + /** + * Cancels any piston extend events if the target block is part of a portal + * + * @param event

The event to check and possibly cancel

+ */ @EventHandler public void onPistonExtend(BlockPistonExtendEvent event) { cancelPistonEvent(event, event.getBlocks()); } + /** + * Cancels any piston retract events if the target block is part of a portal + * + * @param event

The event to check and possibly cancel

+ */ @EventHandler public void onPistonRetract(BlockPistonRetractEvent event) { if (!event.isSticky()) { @@ -143,16 +197,18 @@ public class BlockEventListener implements Listener { /** * Cancels a piston event if it would destroy a portal - * @param event

The event to cancel

+ * + * @param event

The event to cancel

* @param blocks

The blocks included in the event

*/ private void cancelPistonEvent(BlockPistonEvent event, List blocks) { for (Block block : blocks) { - Portal portal = Portal.getByBlock(block); + Portal portal = PortalHandler.getByBlock(block); if (portal != null) { event.setCancelled(true); return; } } } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java index 51be7d5..69f5105 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java @@ -1,9 +1,11 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -19,7 +21,7 @@ import java.io.IOException; public class BungeeCordListener implements PluginMessageListener { @Override - public void onPluginMessageReceived(String channel, Player unused, byte[] message) { + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, @NotNull byte[] message) { if (!Stargate.enableBungee || !channel.equals("BungeeCord")) { return; } @@ -39,7 +41,7 @@ public class BungeeCordListener implements PluginMessageListener { if (player == null) { Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); } else { - Portal destinationPortal = Portal.getBungeeGate(destination); + Portal destinationPortal = PortalHandler.getBungeeGate(destination); // Specified an invalid gate. For now we'll just let them connect at their current location if (destinationPortal == null) { Stargate.log.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index a0f7759..dafec9d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -1,25 +1,39 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityExplodeEvent; +/** + * This listener listens for any relevant events on portal entities + */ +@SuppressWarnings("unused") public class EntityEventListener implements Listener { + + /** + * This method catches any explosion events + * + *

If destroyed by explosions is enabled, any portals destroyed by the explosion will be unregistered. If not, + * the explosion will be cancelled.

+ * + * @param event

The triggered explosion event

+ */ @EventHandler public void onEntityExplode(EntityExplodeEvent event) { if (event.isCancelled()) { return; } - for (Block b : event.blockList()) { - Portal portal = Portal.getByBlock(b); + for (Block block : event.blockList()) { + Portal portal = PortalHandler.getByBlock(block); if (portal == null) { continue; } if (Stargate.destroyedByExplosion()) { - portal.unregister(true); + PortalHandler.unregister(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 36399b9..6d7e3c4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.Stargate; @@ -39,7 +40,7 @@ public class PlayerEventsListener implements Listener { return; } - Portal portal = Portal.getBungeeGate(destination); + Portal portal = PortalHandler.getBungeeGate(destination); if (portal == null) { Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); return; @@ -54,7 +55,7 @@ public class PlayerEventsListener implements Listener { if (!event.isCancelled() && (cause == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL || cause == PlayerTeleportEvent.TeleportCause.END_GATEWAY && World.Environment.THE_END == event.getFrom().getWorld().getEnvironment()) - && Portal.getByAdjacentEntrance(event.getFrom()) != null) { + && PortalHandler.getByAdjacentEntrance(event.getFrom()) != null) { event.setCancelled(true); } } @@ -69,29 +70,29 @@ public class PlayerEventsListener implements Listener { } Player player = event.getPlayer(); - Portal portal = Portal.getByEntrance(event.getTo()); + Portal entracePortal = PortalHandler.getByEntrance(event.getTo()); // No portal or not open - if (portal == null || !portal.isOpen()) return; + if (entracePortal == null || !entracePortal.isOpen()) return; // Not open for this player - if (!portal.isOpenFor(player)) { + if (!entracePortal.isOpenFor(player)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.teleport(player, portal, event); + entracePortal.teleport(player, entracePortal, event); return; } - Portal destination = portal.getDestination(player); - if (!portal.isBungee() && destination == null) 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 (portal.isBungee()) { - if (!Stargate.canAccessServer(player, portal.getNetwork())) { + if (entracePortal.isBungee()) { + if (!Stargate.canAccessServer(player, entracePortal.getNetwork())) { deny = true; } } else { // Check if player has access to this network - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + if (!Stargate.canAccessNetwork(player, entracePortal.getNetwork())) { deny = true; } @@ -101,67 +102,42 @@ public class PlayerEventsListener implements Listener { } } - if (!Stargate.canAccessPortal(player, portal, deny)) { + if (!Stargate.canAccessPortal(player, entracePortal, deny)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); - portal.teleport(player, portal, event); - portal.close(false); + entracePortal.teleport(player, entracePortal, event); + entracePortal.close(false); return; } - int cost = Stargate.getUseCost(player, portal, destination); + int cost = Stargate.getUseCost(player, entracePortal, destination); if (cost > 0) { - boolean success; - if (portal.getGate().getToOwner()) { - success = portal.getOwnerUUID() != null && Stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = Stargate.chargePlayer(player, cost); - } - if (!success) { - // Insufficient Funds - Stargate.sendMessage(player, Stargate.getString("inFunds")); - portal.close(false); + if (!EconomyHelper.payTeleportFee(entracePortal, player, cost)) { return; } - String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); - Stargate.sendMessage(player, deductMsg, false); - if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) { - Player p; - if (portal.getOwnerUUID() != null) { - p = Stargate.server.getPlayer(portal.getOwnerUUID()); - } else { - p = Stargate.server.getPlayer(portal.getOwnerName()); - } - if (p != null) { - String obtainedMsg = Stargate.getString("ecoObtain"); - obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()}); - Stargate.sendMessage(p, obtainedMsg, false); - } - } } Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); // BungeeCord Support - if (portal.isBungee()) { + if (entracePortal.isBungee()) { if (!Stargate.enableBungee) { player.sendMessage(Stargate.getString("bungeeDisabled")); - portal.close(false); + entracePortal.close(false); return; } // Teleport the player back to this gate, for sanity's sake - portal.teleport(player, portal, event); + entracePortal.teleport(player, entracePortal, 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() + "#@#" + portal.getDestinationName(); + String msg = event.getPlayer().getName() + "#@#" + entracePortal.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(portal.getNetwork()); // Server + msgData.writeUTF(entracePortal.getNetwork()); // Server msgData.writeUTF("SGBungee"); // Channel msgData.writeShort(msg.length()); // Data Length msgData.writeBytes(msg); // Data @@ -177,7 +153,7 @@ public class PlayerEventsListener implements Listener { ByteArrayOutputStream bao = new ByteArrayOutputStream(); DataOutputStream msgData = new DataOutputStream(bao); msgData.writeUTF("Connect"); - msgData.writeUTF(portal.getNetwork()); + msgData.writeUTF(entracePortal.getNetwork()); player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray()); bao.reset(); @@ -188,12 +164,12 @@ public class PlayerEventsListener implements Listener { } // Close portal if required (Should never be) - portal.close(false); + entracePortal.close(false); return; } - destination.teleport(player, portal, event); - portal.close(false); + destination.teleport(player, entracePortal, event); + entracePortal.close(false); } @EventHandler @@ -208,7 +184,7 @@ public class PlayerEventsListener implements Listener { // Right click if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { if (block.getBlockData() instanceof WallSign) { - Portal portal = Portal.getByBlock(block); + Portal portal = PortalHandler.getByBlock(block); if (portal == null) { return; } @@ -246,7 +222,7 @@ public class PlayerEventsListener implements Listener { eventTime = System.currentTimeMillis(); } - Portal portal = Portal.getByBlock(block); + Portal portal = PortalHandler.getByBlock(block); if (portal == null) { return; } @@ -277,8 +253,10 @@ public class PlayerEventsListener implements Listener { if (event.getAction() == Action.LEFT_CLICK_BLOCK) { // Check if we're scrolling a sign if (block.getBlockData() instanceof WallSign) { - Portal portal = Portal.getByBlock(block); - if (portal == null) return; + Portal portal = PortalHandler.getByBlock(block); + if (portal == null) { + return; + } event.setUseInteractedBlock(Event.Result.DENY); // Only cancel event in creative mode diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 1c31b69..31fd75a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -1,7 +1,9 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.EconomyHelper; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; @@ -11,90 +13,86 @@ import org.bukkit.event.vehicle.VehicleMoveEvent; import java.util.List; +@SuppressWarnings("unused") public class VehicleEventListener implements Listener { + + /** + * Check for a vehicle moving through a portal + * @param event

The triggered move event

+ */ @EventHandler public void onVehicleMove(VehicleMoveEvent event) { - if (!Stargate.handleVehicles) return; + if (!Stargate.handleVehicles) { + return; + } List passengers = event.getVehicle().getPassengers(); Vehicle vehicle = event.getVehicle(); - Portal portal = Portal.getByEntrance(event.getTo()); - if (portal == null || !portal.isOpen()) return; + Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); - // We don't support vehicles in Bungee portals - if (portal.isBungee()) return; + //Return if the portal cannot be teleported through + if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { + return; + } if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - /* - Player player = (Player) passengers.get(0); - if (!portal.isOpenFor(player)) { - stargate.sendMessage(player, stargate.getString("denyMsg")); - return; - } - - Portal dest = portal.getDestination(player); - if (dest == null) return; - boolean deny = false; - // Check if player has access to this network - if (!canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - // Check if player has access to destination world - if (!canAccessWorld(player, dest.getWorld().getName())) { - deny = true; - } - - if (!canAccessPortal(player, portal, deny)) { - stargate.sendMessage(player, stargate.getString("denyMsg")); - portal.close(false); - return; - } - - int cost = stargate.getUseCost(player, portal, dest); - if (cost > 0) { - boolean success; - if(portal.getGate().getToOwner()) { - if(portal.getOwnerUUID() == null) { - success = stargate.chargePlayer(player, portal.getOwnerUUID(), cost); - } else { - success = stargate.chargePlayer(player, portal.getOwnerName(), cost); - } - } else { - success = stargate.chargePlayer(player, cost); - } - if(!success) { - // Insufficient Funds - stargate.sendMessage(player, stargate.getString("inFunds")); - portal.close(false); - return; - } - String deductMsg = stargate.getString("ecoDeduct"); - deductMsg = stargate.replaceVars(deductMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - sendMessage(player, deductMsg, false); - if (portal.getGate().getToOwner()) { - Player p; - if(portal.getOwnerUUID() != null) { - p = server.getPlayer(portal.getOwnerUUID()); - } else { - p = server.getPlayer(portal.getOwnerName()); - } - if (p != null) { - String obtainedMsg = stargate.getString("ecoObtain"); - obtainedMsg = stargate.replaceVars(obtainedMsg, new String[] {"%cost%", "%portal%"}, new String[] {EconomyHandler.format(cost), portal.getName()}); - stargate.sendMessage(p, obtainedMsg, false); - } - } - } - - stargate.sendMessage(player, stargate.getString("teleportMsg"), false); - dest.teleport(vehicle); - portal.close(false); - */ + Stargate.log.info(Stargate.getString("prefox") + "Found passenger minecart"); + teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Portal dest = portal.getDestination(); - if (dest == null) return; - dest.teleport(vehicle); + Stargate.log.info(Stargate.getString("prefox") + "Found empty minecart"); + Portal destinationPortal = entrancePortal.getDestination(); + if (destinationPortal == null) { + Stargate.log.warning(Stargate.getString("prefox") + "Unable to find portal destination"); + return; + } + destinationPortal.teleport(vehicle); } } + + /** + * Teleports a player and the minecart 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) { + Player player = (Player) passengers.get(0); + if (!entrancePortal.isOpenFor(player)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return; + } + + Portal destinationPortal = entrancePortal.getDestination(player); + 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)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + entrancePortal.close(false); + return; + } + + int cost = Stargate.getUseCost(player, entrancePortal, destinationPortal); + if (cost > 0) { + if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { + return; + } + } + + Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + destinationPortal.teleport(vehicle); + entrancePortal.close(false); + } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index e7d33be..252dbe3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.World; import org.bukkit.event.EventHandler; @@ -12,7 +13,7 @@ public class WorldEventListener implements Listener { @EventHandler public void onWorldLoad(WorldLoadEvent event) { if (!Stargate.managedWorlds.contains(event.getWorld().getName()) - && Portal.loadAllGates(event.getWorld())) { + && PortalHandler.loadAllGates(event.getWorld())) { Stargate.managedWorlds.add(event.getWorld().getName()); } } @@ -24,10 +25,10 @@ public class WorldEventListener implements Listener { World w = event.getWorld(); if (Stargate.managedWorlds.contains(w.getName())) { Stargate.managedWorlds.remove(w.getName()); - Portal.clearGates(); + PortalHandler.clearGates(); for (World world : Stargate.server.getWorlds()) { if (Stargate.managedWorlds.contains(world.getName())) { - Portal.loadAllGates(world); + PortalHandler.loadAllGates(world); } } } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java new file mode 100644 index 0000000..59ed896 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -0,0 +1,113 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.Stargate; +import org.bukkit.entity.Player; + +public class EconomyHelper { + + /** + * Tries to make the given user pay the teleport fee + * @param entrancePortal

The portal the player is entering

+ * @param player

The player wishing to teleport

+ * @param cost

The cost of teleportation

+ * @return

True if payment was successful

+ */ + public static boolean payTeleportFee(Portal entrancePortal, Player player, int cost) { + boolean success; + + //Try to charge the player + if (entrancePortal.getGate().getToOwner()) { + success = entrancePortal.getOwnerUUID() != null && Stargate.chargePlayer(player, entrancePortal.getOwnerUUID(), cost); + } else { + success = Stargate.chargePlayer(player, cost); + } + + // Insufficient Funds + if (!success) { + sendInsufficientFundsMessage(entrancePortal.getName(), player, cost); + entrancePortal.close(false); + return false; + } + + //Send the deduct message to the player + sendDeductMessage(entrancePortal.getName(), player, cost); + + if (entrancePortal.getGate().getToOwner()) { + Player gateOwner; + if (entrancePortal.getOwnerUUID() != null) { + gateOwner = Stargate.server.getPlayer(entrancePortal.getOwnerUUID()); + } else { + gateOwner = Stargate.server.getPlayer(entrancePortal.getOwnerName()); + } + + //Notify the gate owner of received payment + if (gateOwner != null) { + sendObtainMessage(entrancePortal.getName(), gateOwner, cost); + } + } + return true; + } + + /** + * Sends a message to the gate owner telling him/her how much he/she earned from a player using his/her gate + * @param portalName

The name of the used portal

+ * @param portalOwner

The owner of the portal

+ * @param earnings

The amount the owner earned

+ */ + public static void sendObtainMessage(String portalName, Player portalOwner, int earnings) { + String obtainedMsg = Stargate.getString("ecoObtain"); + obtainedMsg = replaceVars(obtainedMsg, portalName, earnings); + Stargate.sendMessage(portalOwner, obtainedMsg, false); + } + + /** + * Sends a message telling the user how much they paid for interacting with a portal + * @param portalName

The name of the portal interacted with

+ * @param player

The interacting player

+ * @param cost

The cost of the interaction

+ */ + public static void sendDeductMessage(String portalName, Player player, int cost) { + String deductMsg = Stargate.getString("ecoDeduct"); + deductMsg = replaceVars(deductMsg, portalName, cost); + Stargate.sendMessage(player, deductMsg, false); + } + + /** + * Sends a message telling the user they don't have enough funds to do a portal interaction + * @param portalName

The name of the portal interacted with

+ * @param player

The interacting player

+ * @param cost

The cost of the interaction

+ */ + public static void sendInsufficientFundsMessage(String portalName, Player player, int cost) { + String inFundMsg = Stargate.getString("ecoInFunds"); + inFundMsg = replaceVars(inFundMsg, portalName, cost); + Stargate.sendMessage(player, inFundMsg); + } + + /** + * Sends a message telling the user how much they are refunded for breaking their portal + * @param portalName

The name of the broken portal

+ * @param player

The player breaking the portal

+ * @param cost

The amount the user has to pay for destroying the portal. (expects a negative value)

+ */ + public static void sendRefundMessage(String portalName, Player player, int cost) { + String refundMsg = Stargate.getString("ecoRefund"); + refundMsg = replaceVars(refundMsg, portalName, -cost); + Stargate.sendMessage(player, refundMsg, false); + } + + /** + * Replaces the cost and portal variables in a string + * @param message

The message to replace variables in

+ * @param portalName

The name of the relevant portal

+ * @param cost

The cost for a given interaction

+ * @return

The same string with cost and portal variables replaced

+ */ + private static String replaceVars(String message, String portalName, int cost) { + return Stargate.replaceVars(message, new String[]{"%cost%", "%portal%"}, + new String[]{EconomyHandler.format(cost), portalName}); + } + +} From df074b9ff5e72d457e5f44b3b0d0132c07682880 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 Feb 2021 01:35:55 +0100 Subject: [PATCH 040/378] Adds an entity portal event listener which fixes the infuriating bug which caused empty minecarts to disappear into the nether --- .../stargate/listener/EntityEventListener.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index dafec9d..bab95f6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -5,8 +5,10 @@ import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityPortalEvent; /** * This listener listens for any relevant events on portal entities @@ -14,6 +16,18 @@ import org.bukkit.event.entity.EntityExplodeEvent; @SuppressWarnings("unused") 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) + public void onPortalEvent(EntityPortalEvent event) { + Portal portal = PortalHandler.getByAdjacentEntrance(event.getFrom()); + if (portal != null) { + event.setCancelled(true); + } + } + /** * This method catches any explosion events * From 5b7f5649b1436f7312aeca4b516970e18966b855 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 16 Feb 2021 21:58:31 +0100 Subject: [PATCH 041/378] Makes a whole lot of changes Adds some new tests Improves plugin command handling by using one class for each command Makes some changes to vehicle teleportation to support horses and pigs, but vehicle teleportation is still buggy and messy Adds some more missing comments Adds a wildcard permission and uses built-in permissions some places to avoid checking for three different permissions --- .../net/knarcraft/stargate/BlockLocation.java | 18 +- .../java/net/knarcraft/stargate/Gate.java | 22 ++- .../java/net/knarcraft/stargate/Portal.java | 158 ++++++++++++---- .../net/knarcraft/stargate/PortalHandler.java | 92 +++++---- .../stargate/RelativeBlockVector.java | 25 ++- .../java/net/knarcraft/stargate/Stargate.java | 175 ++++++++++-------- .../stargate/command/CommandAbout.java | 26 +++ .../stargate/command/CommandReload.java | 39 ++++ .../stargate/command/CommandStarGate.java | 43 +++++ .../command/StarGateTabCompleter.java | 23 +++ .../stargate/listener/BlockEventListener.java | 2 +- .../listener/EntityEventListener.java | 8 +- .../listener/PlayerEventsListener.java | 91 ++++----- .../listener/VehicleEventListener.java | 55 ++++-- .../stargate/listener/WorldEventListener.java | 1 - src/main/resources/plugin.yml | 26 ++- .../knarcraft/stargate/BlockLocationTest.java | 9 + .../stargate/RelativeBlockVectorTest.java | 17 ++ 18 files changed, 584 insertions(+), 246 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/command/CommandAbout.java create mode 100644 src/main/java/net/knarcraft/stargate/command/CommandReload.java create mode 100644 src/main/java/net/knarcraft/stargate/command/CommandStarGate.java create mode 100644 src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java create mode 100644 src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java 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()); + } + +} From c912624df1a3c1f6ba0fb723f7bea0138aaf1fda Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 19 Feb 2021 12:06:23 +0100 Subject: [PATCH 042/378] Adds comments to all custom events Adds full comments to every class implementing StarGateEvent Adds another abstract event StargatePlayerEvent which reduces code duplication --- .../stargate/event/StargateAccessEvent.java | 39 +++---- .../stargate/event/StargateActivateEvent.java | 105 ++++++++++++------ .../stargate/event/StargateCloseEvent.java | 44 ++++++-- .../stargate/event/StargateCreateEvent.java | 85 +++++++++++--- .../event/StargateDeactivateEvent.java | 28 ++++- .../stargate/event/StargateDestroyEvent.java | 43 +++---- .../stargate/event/StargateEvent.java | 16 ++- .../stargate/event/StargateOpenEvent.java | 71 +++++++----- .../stargate/event/StargatePlayerEvent.java | 33 ++++++ .../stargate/event/StargatePortalEvent.java | 53 +++++---- 10 files changed, 344 insertions(+), 173 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 919ff6d..71f2fe8 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -3,24 +3,18 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; +/** + * This event should be called whenever a player attempts to access a stargate + */ @SuppressWarnings("unused") -public class StargateAccessEvent extends StargateEvent { +public class StargateAccessEvent extends StargatePlayerEvent { - private final Player player; private boolean deny; private static final HandlerList handlers = new HandlerList(); - - /** - * Gets a handler-list containing all event handlers - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Instantiates a new stargate access event * @param player

The player involved in the vent

@@ -28,9 +22,8 @@ public class StargateAccessEvent extends StargateEvent { * @param deny

Whether the event should be denied

*/ public StargateAccessEvent(Player player, Portal portal, boolean deny) { - super("StargateAccessEvent", portal); - - this.player = player; + super("StargateAccessEvent", portal, player); + this.deny = deny; } @@ -51,15 +44,17 @@ public class StargateAccessEvent extends StargateEvent { } /** - * Gets the player involved in this stargate access event - * @return

The player involved in this event

+ * Gets a handler-list containing all event handlers + * @return

A handler-list with all event handlers

*/ - public Player getPlayer() { - return this.player; - } - - @Override - public @org.jetbrains.annotations.NotNull HandlerList getHandlers() { + public static HandlerList getHandlerList() { return handlers; } + + @Override + @NotNull + public HandlerList getHandlers() { + return handlers; + } + } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index 085c622..3f522a7 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -5,51 +5,84 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; +import java.util.List; -public class StargateActivateEvent extends StargateEvent { +/** + * This event should be called whenever a player activates a stargate + *

Activation of a stargate happens when a player right-clicks the sign of a stargate.

+ */ +@SuppressWarnings("unused") +public class StargateActivateEvent extends StargatePlayerEvent { - private final Player player; - private ArrayList destinations; + private List destinations; private String destination; private static final HandlerList handlers = new HandlerList(); + /** + * Instantiates a new stargate activate event + * + * @param portal

The activated portal

+ * @param player

The player activating the portal

+ * @param destinations

The destinations available to the player using the portal

+ * @param destination

The chosen destination to activate

+ */ + public StargateActivateEvent(Portal portal, Player player, List destinations, String destination) { + super("StargatActivateEvent", portal, player); + + this.destinations = destinations; + this.destination = destination; + } + + /** + * Gets the destinations available for the portal + * + * @return

The destinations available for the portal

+ */ + public List getDestinations() { + return destinations; + } + + /** + * Sets the destinations available to the player using the portal + * + * @param destinations

The new list of available destinations

+ */ + public void setDestinations(List destinations) { + this.destinations = destinations; + } + + /** + * Gets the chosen destination to activate + * + * @return

The chosen destination to activate

+ */ + public String getDestination() { + return destination; + } + + /** + * Sets (changes) the chosen destination to activate + * + * @param destination

The new destination to activate

+ */ + public void setDestination(String destination) { + this.destination = destination; + } + + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @Override @NotNull public HandlerList getHandlers() { return handlers; } - public static HandlerList getHandlerList() { - return handlers; - } - - public StargateActivateEvent(Portal portal, Player player, ArrayList destinations, String destination) { - super("StargatActivateEvent", portal); - - this.player = player; - this.destinations = destinations; - this.destination = destination; - } - - public Player getPlayer() { - return player; - } - - public ArrayList getDestinations() { - return destinations; - } - - public void setDestinations(ArrayList destinations) { - this.destinations = destinations; - } - - public String getDestination() { - return destination; - } - - public void setDestination(String destination) { - this.destination = destination; - } - } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index 070a4b3..a5e5ace 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -4,33 +4,59 @@ import net.knarcraft.stargate.Portal; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +/** + * This event should be called whenever a stargate is closed + */ +@SuppressWarnings("unused") public class StargateCloseEvent extends StargateEvent { private boolean force; private static final HandlerList handlers = new HandlerList(); - @NotNull - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - + /** + * Instantiates a new stargate closing event + * + * @param portal

The portal to close

+ * @param force

Whether to force the gate to close, even if set as always-on

+ */ public StargateCloseEvent(Portal portal, boolean force) { super("StargateCloseEvent", portal); this.force = force; } + /** + * Gets whether to force the stargate to close + * + * @return

Whether to force the stargate to close

+ */ public boolean getForce() { return force; } + /** + * Sets whether the stargate should be forced to close + * + * @param force

Whether the stargate should be forced to close

+ */ public void setForce(boolean force) { this.force = force; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java index bba2060..bd23679 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -5,9 +5,12 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -public class StargateCreateEvent extends StargateEvent { +/** + * This event should be called whenever a stargate is created + */ +@SuppressWarnings("unused") +public class StargateCreateEvent extends StargatePlayerEvent { - private final Player player; private boolean deny; private String denyReason; private final String[] lines; @@ -15,54 +18,102 @@ public class StargateCreateEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); - @NotNull - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - + /** + * Instantiates a new stargate creation event + * + * @param player

Thg player creating the stargate

+ * @param portal

The created portal

+ * @param lines

The lines of the sign creating the star gate

+ * @param deny

Whether to deny the creation of the new gate

+ * @param denyReason

The reason stargate creation was denied

+ * @param cost

The cost of creating the new star gate

+ */ public StargateCreateEvent(Player player, Portal portal, String[] lines, boolean deny, String denyReason, int cost) { - super("StargateCreateEvent", portal); - this.player = player; + super("StargateCreateEvent", portal, player); this.lines = lines; this.deny = deny; this.denyReason = denyReason; this.cost = cost; } - public Player getPlayer() { - return player; - } - + /** + * Gets a given line from the sign creating the star gate + * + * @param index

The line number to get

+ * @return

The text on the given line

+ * @throws IndexOutOfBoundsException

If given a line index less than zero or above three

+ */ public String getLine(int index) throws IndexOutOfBoundsException { return lines[index]; } + /** + * Gets whether the stargate creation should be denied + * + * @return

Whether the stargate creation should be denied

+ */ public boolean getDeny() { return deny; } + /** + * Sets whether the stargate creation should be denied + * + * @param deny

Whether the stargate creation should be denied

+ */ public void setDeny(boolean deny) { this.deny = deny; } + /** + * Gets the reason the stargate creation was denied + * + * @return

The reason the stargate creation was denied

+ */ public String getDenyReason() { return denyReason; } + /** + * Sets the reason the stargate creation was denied + * + * @param denyReason

The new reason why the stargate creation was denied

+ */ public void setDenyReason(String denyReason) { this.denyReason = denyReason; } + /** + * Gets the cost of creating the stargate + * + * @return

The cost of creating the stargate

+ */ public int getCost() { return cost; } + /** + * Sets the cost of creating the stargate + * + * @param cost

The new cost of creating the stargate

+ */ public void setCost(int cost) { this.cost = cost; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index 922e68f..4b3e68e 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -4,21 +4,37 @@ import net.knarcraft.stargate.Portal; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +/** + * This event should be called whenever a stargate is deactivated + *

A deactivation is usually caused by no activity for a set amount of time.

+ */ +@SuppressWarnings("unused") public class StargateDeactivateEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); - @NotNull - public HandlerList getHandlers() { - return handlers; + /** + * Instantiates a new stargate deactivation event + * + * @param portal

The portal which was deactivated

+ */ + public StargateDeactivateEvent(Portal portal) { + super("StargatDeactivateEvent", portal); } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ public static HandlerList getHandlerList() { return handlers; } - public StargateDeactivateEvent(Portal portal) { - super("StargatDeactivateEvent", portal); - + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; } + } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index 9d4f965..ffbf716 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -8,28 +8,15 @@ import org.jetbrains.annotations.NotNull; /** * This event represents an event where a star gate is destroyed or attempted to be destroyed */ -public class StargateDestroyEvent extends StargateEvent { +@SuppressWarnings("unused") +public class StargateDestroyEvent extends StargatePlayerEvent { - private final Player player; private boolean deny; private String denyReason; private int cost; private static final HandlerList handlers = new HandlerList(); - @NotNull - public HandlerList getHandlers() { - return handlers; - } - - /** - * Gets a handler-list containing all event handlers - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Instantiates a new Stargate Destroy Event * @param portal

The portal destroyed

@@ -39,21 +26,12 @@ public class StargateDestroyEvent extends StargateEvent { * @param cost

The cost of destroying the portal

*/ public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { - super("StargateDestroyEvent", portal); - this.player = player; + super("StargateDestroyEvent", portal, player); this.deny = deny; this.denyReason = denyMsg; this.cost = cost; } - /** - * Gets the player causing the destroy event - * @return

The player causing the destroy event

- */ - public Player getPlayer() { - return player; - } - /** * Gets whether this event should be denied * @return

Whether this event should be denied

@@ -102,4 +80,19 @@ public class StargateDestroyEvent extends StargateEvent { this.cost = cost; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index 1dbc915..f87ed1f 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -10,15 +10,23 @@ import org.bukkit.event.Event; @SuppressWarnings("unused") public abstract class StargateEvent extends Event implements Cancellable { - protected final Portal portal; - protected boolean cancelled; + private final Portal portal; + private boolean cancelled; - public StargateEvent(String event, Portal portal) { + /** + * Instantiates a new stargate event + * @param event

UNUSED

+ * @param portal

The portal involved in this stargate event

+ */ + StargateEvent(String event, Portal portal) { this.portal = portal; this.cancelled = false; } - + /** + * Gets the portal involved in this stargate event + * @return

The portal involved in this stargate event

+ */ public Portal getPortal() { return portal; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index 75a3bf4..360bb98 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -5,44 +5,55 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -public class StargateOpenEvent extends StargateEvent { +/** + * This event should be called whenever a player opens a stargate + */ +public class StargateOpenEvent extends StargatePlayerEvent { - private final Player player; private boolean force; private static final HandlerList handlers = new HandlerList(); + /** + * Instantiates a new stargate open event + * @param player

The player opening the stargate

+ * @param portal

The portal opened

+ * @param force

Whether to force the portal open

+ */ + public StargateOpenEvent(Player player, Portal portal, boolean force) { + super("StargateOpenEvent", portal, player); + + this.force = force; + } + + /** + * Gets whether the portal should be forced open + * @return

Whether the portal should be forced open

+ */ + public boolean getForce() { + return force; + } + + /** + * Sets whether the portal should be forced open + * @param force

Whether the portal should be forced open

+ */ + public void setForce(boolean force) { + this.force = force; + } + + /** + * Gets a handler-list containing all event handlers + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @Override @NotNull public HandlerList getHandlers() { return handlers; } - public static HandlerList getHandlerList() { - return handlers; - } - - public StargateOpenEvent(Player player, Portal portal, boolean force) { - super("StargateOpenEvent", portal); - - this.player = player; - this.force = force; - } - - /** - * Return the player than opened the gate. - * - * @return player than opened the gate - */ - public Player getPlayer() { - return player; - } - - public boolean getForce() { - return force; - } - - public void setForce(boolean force) { - this.force = force; - } - } diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java new file mode 100644 index 0000000..2dcf77b --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java @@ -0,0 +1,33 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.Portal; +import org.bukkit.entity.Player; + +/** + * An abstract event describing any stargate event where a player is involved + */ +public abstract class StargatePlayerEvent extends StargateEvent { + + private final Player player; + + /** + * Instantiates a new stargate player event + * + * @param event

UNUSED

+ * @param portal

The portal involved in this stargate event

+ */ + StargatePlayerEvent(String event, Portal portal, Player player) { + super(event, portal); + this.player = player; + } + + /** + * Gets the player creating the star gate + * + * @return

The player creating the star gate

+ */ + public Player getPlayer() { + return player; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java index 3b46461..6e7191a 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java @@ -6,38 +6,29 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -public class StargatePortalEvent extends StargateEvent { +/** + * This event should be called whenever a player teleports through a stargate + */ +@SuppressWarnings("unused") +public class StargatePortalEvent extends StargatePlayerEvent { - private final Player player; private final Portal destination; private Location exit; private static final HandlerList handlers = new HandlerList(); - @NotNull - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public StargatePortalEvent(Player player, Portal portal, Portal dest, Location exit) { - super("StargatePortalEvent", portal); - - this.player = player; - this.destination = dest; - this.exit = exit; - } - /** - * Return the player that went through the gate. - * - * @return player that went through the gate + * Instantiates a new stargate portal event + * @param player

The player teleporting

+ * @param portal

The portal the player entered from

+ * @param destination

The destination the player should exit from

+ * @param exit

The exit location of the destination portal the user will be teleported to

*/ - public Player getPlayer() { - return player; + public StargatePortalEvent(Player player, Portal portal, Portal destination, Location exit) { + super("StargatePortalEvent", portal, player); + + this.destination = destination; + this.exit = exit; } /** @@ -65,4 +56,18 @@ public class StargatePortalEvent extends StargateEvent { this.exit = loc; } + /** + * Gets a handler-list containing all event handlers + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + @NotNull + public HandlerList getHandlers() { + return handlers; + } + } From 2ae4fc96456fd6e5620f9789a7952dc8fe160b67 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 19 Feb 2021 12:07:34 +0100 Subject: [PATCH 043/378] Adds class comment to the stargate tab completer --- .../net/knarcraft/stargate/command/StarGateTabCompleter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index 5370beb..2675e80 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -9,6 +9,9 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +/** + * This is the tab completer for the /stargate (/sg) command + */ public class StarGateTabCompleter implements TabCompleter { @Override From 1721750aa11c8909e9be68899379317ee6e3c49d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 20 Feb 2021 13:57:04 +0100 Subject: [PATCH 044/378] Adds comments and simplifies some of the code Adds a PortalOption enum to simplify portal options Adds a BungeeHelper class to collect the bungee-related code --- .../net/knarcraft/stargate/BlockLocation.java | 64 +- .../net/knarcraft/stargate/BloxPopulator.java | 62 +- .../knarcraft/stargate/EconomyHandler.java | 6 + .../java/net/knarcraft/stargate/Gate.java | 591 +++++++++--------- .../knarcraft/stargate/LanguageLoader.java | 27 +- .../java/net/knarcraft/stargate/Portal.java | 320 +++++----- .../net/knarcraft/stargate/PortalHandler.java | 304 +++++---- .../net/knarcraft/stargate/PortalOption.java | 93 +++ .../stargate/RelativeBlockVector.java | 8 +- .../java/net/knarcraft/stargate/Stargate.java | 421 +++++++------ .../java/net/knarcraft/stargate/TwoTuple.java | 8 +- .../stargate/command/CommandReload.java | 1 + .../stargate/command/CommandStarGate.java | 1 + .../stargate/event/StargateAccessEvent.java | 51 +- .../stargate/event/StargateActivateEvent.java | 21 +- .../stargate/event/StargateCloseEvent.java | 21 +- .../stargate/event/StargateCreateEvent.java | 23 +- .../stargate/event/StargateDestroyEvent.java | 114 ++-- .../stargate/event/StargateEvent.java | 4 +- .../stargate/event/StargateOpenEvent.java | 25 +- .../stargate/event/StargatePortalEvent.java | 27 +- .../stargate/listener/BlockEventListener.java | 16 +- .../stargate/listener/BungeeCordListener.java | 65 +- .../listener/EntityEventListener.java | 1 + .../listener/PlayerEventsListener.java | 200 +++--- .../listener/VehicleEventListener.java | 66 +- .../stargate/utility/BungeeHelper.java | 133 ++++ .../stargate/utility/EconomyHelper.java | 30 +- .../stargate/utility/MaterialHelper.java | 2 + 29 files changed, 1499 insertions(+), 1206 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/PortalOption.java create mode 100644 src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index f289738..f033b10 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -22,10 +22,11 @@ public class BlockLocation extends Location { /** * Creates a new block location + * * @param world

The world the block exists in

- * @param x

The x coordinate of the block

- * @param y

The y coordinate of the block

- * @param z

The z coordinate of the block

+ * @param x

The x coordinate of the block

+ * @param y

The y coordinate of the block

+ * @param z

The z coordinate of the block

*/ public BlockLocation(World world, int x, int y, int z) { super(world, x, y, z); @@ -33,6 +34,7 @@ public class BlockLocation extends Location { /** * Copies a craftbukkit block + * * @param block

The block to

*/ public BlockLocation(Block block) { @@ -41,7 +43,8 @@ public class BlockLocation extends Location { /** * Gets a block from a string - * @param world

The world the block exists in

+ * + * @param world

The world the block exists in

* @param string

A comma separated list of z, y and z coordinates as integers

*/ public BlockLocation(World world, String string) { @@ -51,6 +54,7 @@ public class BlockLocation extends Location { /** * Makes a new block in a relative position to this block + * * @param x

The x position relative to this block's position

* @param y

The y position relative to this block's position

* @param z

The z position relative to this block's position

@@ -62,9 +66,10 @@ public class BlockLocation extends Location { /** * Makes a location relative to the block location - * @param x

The x position relative to this block's position

- * @param y

The y position relative to this block's position

- * @param z

The z position relative to this block's position

+ * + * @param x

The x position relative to this block's position

+ * @param y

The y position relative to this block's position

+ * @param z

The z position relative to this block's position

* @param rotX

The x rotation of the location

* @param rotY

The y rotation of the location

* @return

A new location

@@ -82,12 +87,12 @@ public class BlockLocation extends Location { *

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 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

+ * @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) { @@ -96,38 +101,42 @@ public class BlockLocation extends Location { /** * Makes a location relative to the current location according to given parameters - * @param right

- * @param depth

The y position relative to the current position

+ * + * @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 rotX

The yaw of the location

- * @param rotY

Unused

- * @param modX

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

- * @param modY

Unused

- * @param modZ

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

+ * @param rotX

The yaw of the location

+ * @param rotY

Unused

+ * @param modX

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

+ * @param modY

Unused

+ * @param modZ

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

* @return A new location relative to this block location */ public Location modRelativeLoc(double right, double depth, double distance, float rotX, float rotY, int modX, int modY, int modZ) { return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); } - /** - * Sets the type for the block at this location - * @param type

The new block material type

- */ - public void setType(Material type) { - this.getBlock().setType(type); - } - /** * Gets the type for the block at this location + * * @return

The block material type

*/ public Material getType() { return this.getBlock().getType(); } + /** + * Sets the type for the block at this location + * + * @param type

The new block material type

+ */ + public void setType(Material type) { + this.getBlock().setType(type); + } + /** * Gets the location representing this block location + * * @return

The location representing this block location

*/ public Location getLocation() { @@ -136,6 +145,7 @@ public class BlockLocation extends Location { /** * Gets this block location's parent block + * * @return

This block location's parent block

*/ public Block getParent() { diff --git a/src/main/java/net/knarcraft/stargate/BloxPopulator.java b/src/main/java/net/knarcraft/stargate/BloxPopulator.java index 63031c0..f25d48a 100644 --- a/src/main/java/net/knarcraft/stargate/BloxPopulator.java +++ b/src/main/java/net/knarcraft/stargate/BloxPopulator.java @@ -14,8 +14,9 @@ public class BloxPopulator { /** * Instantiates a new block populator + * * @param blockLocation

The location to start from

- * @param material

The material to populate

+ * @param material

The material to populate

*/ public BloxPopulator(BlockLocation blockLocation, Material material) { this.blockLocation = blockLocation; @@ -25,9 +26,10 @@ public class BloxPopulator { /** * Instantiates a new block populator + * * @param blockLocation

The location to start from

- * @param material

The material to populate

- * @param axis

The axis to populate along

+ * @param material

The material to populate

+ * @param axis

The axis to populate along

*/ public BloxPopulator(BlockLocation blockLocation, Material material, Axis axis) { this.blockLocation = blockLocation; @@ -35,52 +37,58 @@ public class BloxPopulator { nextAxis = axis; } - /** - * Sets the location to start from - * @param blockLocation

The new start location

- */ - public void setBlockLocation(BlockLocation blockLocation) { - this.blockLocation = blockLocation; - } - - /** - * Sets the polulator material - * @param material

The new populator material

- */ - public void setMat(Material material) { - nextMat = material; - } - - /** - * Sets the populator axis - * @param axis

The new populator axis

- */ - public void setAxis(Axis axis) { - nextAxis = axis; - } - /** * Gets the location to start from + * * @return

The location to start from

*/ public BlockLocation getBlockLocation() { return blockLocation; } + /** + * Sets the location to start from + * + * @param blockLocation

The new start location

+ */ + public void setBlockLocation(BlockLocation blockLocation) { + this.blockLocation = blockLocation; + } + /** * Gets the material used for population + * * @return

The material used for population

*/ public Material getMat() { return nextMat; } + /** + * Sets the polulator material + * + * @param material

The new populator material

+ */ + public void setMat(Material material) { + nextMat = material; + } + /** * Gets the current population axis + * * @return

The current population axis

*/ public Axis getAxis() { return nextAxis; } + /** + * Sets the populator axis + * + * @param axis

The new populator axis

+ */ + public void setAxis(Axis axis) { + nextAxis = axis; + } + } diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/EconomyHandler.java index 83bd86c..1cedc55 100644 --- a/src/main/java/net/knarcraft/stargate/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/EconomyHandler.java @@ -26,6 +26,7 @@ public class EconomyHandler { /** * Gets the balance (money) of the given player + * * @param player

The player to get balance for

* @return

The current balance of the player. Returns 0 if economy is disabled

*/ @@ -39,6 +40,7 @@ public class EconomyHandler { /** * Charges a player, giving the charge to a target + * * @param player

The player to charge

* @param target

The UUID of the player to pay

* @param amount

The amount to charge

@@ -57,6 +59,7 @@ public class EconomyHandler { /** * Charges a player + * * @param player

The player to charge

* @param amount

The amount to charge

* @return

True if the payment succeeded, or if no payment was necessary

@@ -73,6 +76,7 @@ public class EconomyHandler { /** * Gets a formatted string for an amount, adding the name of the currency + * * @param amount

The amount to display

* @return

A formatted text string describing the amount

*/ @@ -86,6 +90,7 @@ public class EconomyHandler { /** * Sets up economy by initializing vault and the vault economy provider + * * @param pluginManager

The plugin manager to get plugins from

* @return

True if economy was enabled

*/ @@ -113,6 +118,7 @@ public class EconomyHandler { /** * Gets whether to use economy + * * @return

True if the user has turned on economy and economy is available

*/ public static boolean useEconomy() { diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java index 6a64aed..a5db5d8 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/Gate.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.logging.Level; @@ -21,17 +22,17 @@ public class Gate { private static final Character ENTRANCE = '.'; private static final Character EXIT = '*'; private static final HashMap gates = new HashMap<>(); - private static final HashMap> controlBlocks = new HashMap<>(); + private static final HashMap> controlBlocks = new HashMap<>(); private static final HashSet frameBlocks = new HashSet<>(); private final String filename; private final Character[][] layout; private final HashMap types; + private final HashMap exits = new HashMap<>(); private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; private RelativeBlockVector[] border = new RelativeBlockVector[0]; private RelativeBlockVector[] controls = new RelativeBlockVector[0]; private RelativeBlockVector exitBlock = null; - private final HashMap exits = new HashMap<>(); private Material portalBlockOpen = Material.NETHER_PORTAL; private Material portalBlockClosed = Material.AIR; private Material button = Material.STONE_BUTTON; @@ -50,10 +51,300 @@ public class Gate { populateCoordinates(); } + public static void registerGate(Gate gate) { + gates.put(gate.getFilename(), gate); + + Material blockID = gate.getControlBlock(); + + if (!controlBlocks.containsKey(blockID)) { + controlBlocks.put(blockID, new ArrayList<>()); + } + + controlBlocks.get(blockID).add(gate); + } + + public static Gate loadGate(File file) { + Scanner scanner = null; + try { + scanner = new Scanner(file); + return loadGate(file.getName(), file.getParent(), scanner); + } catch (Exception ex) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + return null; + } finally { + if (scanner != null) { + scanner.close(); + } + } + } + + public static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { + boolean designing = false; + List> design = new ArrayList<>(); + HashMap types = new HashMap<>(); + HashMap config = new HashMap<>(); + HashSet frameTypes = new HashSet<>(); + int cols = 0; + + // Init types map + types.put(ENTRANCE, Material.AIR); + types.put(EXIT, Material.AIR); + types.put(ANYTHING, Material.AIR); + + try { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + + if (designing) { + List row = new ArrayList<>(); + + if (line.length() > cols) { + cols = line.length(); + } + + for (Character symbol : line.toCharArray()) { + if ((symbol.equals('?')) || (!types.containsKey(symbol))) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); + return null; + } + row.add(symbol); + } + + design.add(row); + } else { + if (!line.isEmpty() && !line.startsWith("#")) { + String[] split = line.split("="); + String key = split[0].trim(); + String value = split[1].trim(); + + if (key.length() == 1) { + Character symbol = key.charAt(0); + Material id = Material.getMaterial(value); + if (id == null) { + throw new Exception("Invalid material in line: " + line); + } + types.put(symbol, id); + frameTypes.add(id); + } else { + config.put(key, value); + } + } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { + designing = true; + } + } + } + } catch (Exception ex) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + return null; + } finally { + if (scanner != null) { + scanner.close(); + } + } + + Character[][] layout = new Character[design.size()][cols]; + + for (int y = 0; y < design.size(); y++) { + List row = design.get(y); + Character[] result = new Character[cols]; + + for (int x = 0; x < cols; x++) { + if (x < row.size()) { + result[x] = row.get(x); + } else { + result[x] = ' '; + } + } + + layout[y] = result; + } + + Gate gate = new Gate(fileName, layout, types); + + gate.portalBlockOpen = readConfig(config, fileName, "portal-open", gate.portalBlockOpen); + gate.portalBlockClosed = readConfig(config, fileName, "portal-closed", gate.portalBlockClosed); + gate.button = readConfig(config, fileName, "button", gate.button); + gate.useCost = readConfig(config, fileName, "usecost", -1); + gate.destroyCost = readConfig(config, fileName, "destroycost", -1); + gate.createCost = readConfig(config, fileName, "createcost", -1); + gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); + + if (gate.getControls().length != 2) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); + return null; + } + + if (!MaterialHelper.isButtonCompatible(gate.button)) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); + return null; + } + + // Merge frame types, add open mat to list + frameBlocks.addAll(frameTypes); + + gate.save(parentFolder + "/"); // Updates format for version changes + return gate; + } + + private static int readConfig(HashMap config, String fileName, String key, int defaultInteger) { + if (config.containsKey(key)) { + try { + return Integer.parseInt(config.get(key)); + } catch (NumberFormatException ex) { + Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); + } + } + + return defaultInteger; + } + + /** + * Gets the material defined in the config + * + * @param config

The config to read

+ * @param fileName

The config file the config belongs to

+ * @param key

The config key to read

+ * @param defaultMaterial

The default material to use, in case the config is invalid

+ * @return

The material to use

+ */ + private static Material readConfig(HashMap config, String fileName, String key, Material defaultMaterial) { + if (config.containsKey(key)) { + Material material = Material.getMaterial(config.get(key)); + if (material != null) { + return material; + } else { + Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, key)); + } + } + return defaultMaterial; + } + + /** + * Loads all gates inside the given folder + * + * @param gateFolder

The folder containing the gates

+ */ + public static void loadGates(String gateFolder) { + File directory = new File(gateFolder); + File[] files; + + if (directory.exists()) { + files = directory.listFiles((file) -> file.isFile() && file.getName().endsWith(".gate")); + } else { + files = new File[0]; + } + + if (files == null || files.length == 0) { + //The gates folder was not found. Assume this is the first run + if (directory.mkdir()) { + populateDefaults(gateFolder); + } + } else { + for (File file : files) { + Gate gate = loadGate(file); + if (gate != null) { + registerGate(gate); + } + } + } + } + + /** + * Writes the default gate specifications to the given folder + * + * @param gateFolder

The folder containing gate config files

+ */ + public static void populateDefaults(String gateFolder) { + loadGateFromJar("nethergate.gate", gateFolder); + loadGateFromJar("watergate.gate", gateFolder); + } + + /** + * Loads the given gate file from within the Jar's resources directory + * + * @param gateFile

The name of the gate file

+ * @param gateFolder

The folder containing gates

+ */ + private static void loadGateFromJar(String gateFile, String gateFolder) { + Scanner scanner = new Scanner(Gate.class.getResourceAsStream("/gates/" + gateFile)); + Gate gate = loadGate(gateFile, gateFolder, scanner); + if (gate != null) { + registerGate(gate); + } + } + + /** + * Gets the gates with the given control block + * + *

The control block is the block type where the sign should be placed. It is used to decide whether a user + * is creating a new portal.

+ * + * @param block

The control block to check

+ * @return

A list of gates using the given control block

+ */ + public static Gate[] getGatesByControlBlock(Block block) { + return getGatesByControlBlock(block.getType()); + } + + /** + * Gets the gates with the given control block + * + * @param type

The type of the control block to check

+ * @return

A list of gates using the given material for control block

+ */ + public static Gate[] getGatesByControlBlock(Material type) { + Gate[] result = new Gate[0]; + List lookup = controlBlocks.get(type); + + if (lookup != null) { + result = lookup.toArray(result); + } + + return result; + } + + /** + * Gets a portal by its name (filename before .gate) + * + * @param name

The name of the gate to get

+ * @return

The gate with the given name

+ */ + public static Gate getGateByName(String name) { + return gates.get(name); + } + + /** + * Gets the number of loaded gate configurations + * + * @return

The number of loaded gate configurations

+ */ + public static int getGateCount() { + return gates.size(); + } + + /** + * Checks whether the given material is used for the frame of any portals + * + * @param type

The material type to check

+ * @return

True if the material is used for the frame of at least one portal

+ */ + public static boolean isGateBlock(Material type) { + return frameBlocks.contains(type); + } + + /** + * Clears all loaded gates + */ + public static void clearGates() { + gates.clear(); + controlBlocks.clear(); + frameBlocks.clear(); + } + private void populateCoordinates() { - ArrayList entranceList = new ArrayList<>(); - ArrayList borderList = new ArrayList<>(); - ArrayList controlList = new ArrayList<>(); + List entranceList = new ArrayList<>(); + List borderList = new ArrayList<>(); + List controlList = new ArrayList<>(); RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; int[] exitDepths = new int[layout[0].length]; RelativeBlockVector lastExit = null; @@ -273,294 +564,4 @@ public class Gate { return true; } - public static void registerGate(Gate gate) { - gates.put(gate.getFilename(), gate); - - Material blockID = gate.getControlBlock(); - - if (!controlBlocks.containsKey(blockID)) { - controlBlocks.put(blockID, new ArrayList<>()); - } - - controlBlocks.get(blockID).add(gate); - } - - public static Gate loadGate(File file) { - Scanner scanner = null; - try { - scanner = new Scanner(file); - return loadGate(file.getName(), file.getParent(), scanner); - } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); - return null; - } finally { - if (scanner != null) { - scanner.close(); - } - } - } - - public static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { - boolean designing = false; - ArrayList> design = new ArrayList<>(); - HashMap types = new HashMap<>(); - HashMap config = new HashMap<>(); - HashSet frameTypes = new HashSet<>(); - int cols = 0; - - // Init types map - types.put(ENTRANCE, Material.AIR); - types.put(EXIT, Material.AIR); - types.put(ANYTHING, Material.AIR); - - try { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - - if (designing) { - ArrayList row = new ArrayList<>(); - - if (line.length() > cols) { - cols = line.length(); - } - - for (Character symbol : line.toCharArray()) { - if ((symbol.equals('?')) || (!types.containsKey(symbol))) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); - return null; - } - row.add(symbol); - } - - design.add(row); - } else { - if (!line.isEmpty() && !line.startsWith("#")) { - String[] split = line.split("="); - String key = split[0].trim(); - String value = split[1].trim(); - - if (key.length() == 1) { - Character symbol = key.charAt(0); - Material id = Material.getMaterial(value); - if (id == null) { - throw new Exception("Invalid material in line: " + line); - } - types.put(symbol, id); - frameTypes.add(id); - } else { - config.put(key, value); - } - } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { - designing = true; - } - } - } - } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); - return null; - } finally { - if (scanner != null) { - scanner.close(); - } - } - - Character[][] layout = new Character[design.size()][cols]; - - for (int y = 0; y < design.size(); y++) { - ArrayList row = design.get(y); - Character[] result = new Character[cols]; - - for (int x = 0; x < cols; x++) { - if (x < row.size()) { - result[x] = row.get(x); - } else { - result[x] = ' '; - } - } - - layout[y] = result; - } - - Gate gate = new Gate(fileName, layout, types); - - gate.portalBlockOpen = readConfig(config, fileName, "portal-open", gate.portalBlockOpen); - gate.portalBlockClosed = readConfig(config, fileName, "portal-closed", gate.portalBlockClosed); - gate.button = readConfig(config, fileName, "button", gate.button); - gate.useCost = readConfig(config, fileName, "usecost", -1); - gate.destroyCost = readConfig(config, fileName, "destroycost", -1); - gate.createCost = readConfig(config, fileName, "createcost", -1); - gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); - - if (gate.getControls().length != 2) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); - return null; - } - - if (!MaterialHelper.isButtonCompatible(gate.button)) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); - return null; - } - - // Merge frame types, add open mat to list - frameBlocks.addAll(frameTypes); - - gate.save(parentFolder + "/"); // Updates format for version changes - return gate; - } - - private static int readConfig(HashMap config, String fileName, String key, int defaultInteger) { - if (config.containsKey(key)) { - try { - return Integer.parseInt(config.get(key)); - } catch (NumberFormatException ex) { - Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); - } - } - - return defaultInteger; - } - - - /** - * Gets the material defined in the config - * - * @param config

The config to read

- * @param fileName

The config file the config belongs to

- * @param key

The config key to read

- * @param defaultMaterial

The default material to use, in case the config is invalid

- * @return

The material to use

- */ - private static Material readConfig(HashMap config, String fileName, String key, Material defaultMaterial) { - if (config.containsKey(key)) { - Material material = Material.getMaterial(config.get(key)); - if (material != null) { - return material; - } else { - Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, key)); - } - } - return defaultMaterial; - } - - /** - * Loads all gates inside the given folder - * - * @param gateFolder

The folder containing the gates

- */ - public static void loadGates(String gateFolder) { - File directory = new File(gateFolder); - File[] files; - - if (directory.exists()) { - files = directory.listFiles((file) -> file.isFile() && file.getName().endsWith(".gate")); - } else { - files = new File[0]; - } - - if (files == null || files.length == 0) { - //The gates folder was not found. Assume this is the first run - if (directory.mkdir()) { - populateDefaults(gateFolder); - } - } else { - for (File file : files) { - Gate gate = loadGate(file); - if (gate != null) { - registerGate(gate); - } - } - } - } - - /** - * Writes the default gate specifications to the given folder - * - * @param gateFolder

The folder containing gate config files

- */ - public static void populateDefaults(String gateFolder) { - loadGateFromJar("nethergate.gate", gateFolder); - loadGateFromJar("watergate.gate", gateFolder); - } - - /** - * Loads the given gate file from within the Jar's resources directory - * @param gateFile

The name of the gate file

- * @param gateFolder

The folder containing gates

- */ - private static void loadGateFromJar(String gateFile, String gateFolder) { - Scanner scanner = new Scanner(Gate.class.getResourceAsStream("/gates/" + gateFile)); - Gate gate = loadGate(gateFile, gateFolder, scanner); - if (gate != null) { - registerGate(gate); - } - } - - /** - * Gets the gates with the given control block - * - *

The control block is the block type where the sign should be placed. It is used to decide whether a user - * is creating a new portal.

- * - * @param block

The control block to check

- * @return

A list of gates using the given control block

- */ - public static Gate[] getGatesByControlBlock(Block block) { - return getGatesByControlBlock(block.getType()); - } - - /** - * Gets the gates with the given control block - * - * @param type

The type of the control block to check

- * @return

A list of gates using the given material for control block

- */ - public static Gate[] getGatesByControlBlock(Material type) { - Gate[] result = new Gate[0]; - ArrayList lookup = controlBlocks.get(type); - - if (lookup != null) { - result = lookup.toArray(result); - } - - return result; - } - - /** - * Gets a portal by its name (filename before .gate) - * - * @param name

The name of the gate to get

- * @return

The gate with the given name

- */ - public static Gate getGateByName(String name) { - return gates.get(name); - } - - /** - * Gets the number of loaded gate configurations - * - * @return

The number of loaded gate configurations

- */ - public static int getGateCount() { - return gates.size(); - } - - /** - * Checks whether the given material is used for the frame of any portals - * - * @param type

The material type to check

- * @return

True if the material is used for the frame of at least one portal

- */ - public static boolean isGateBlock(Material type) { - return frameBlocks.contains(type); - } - - /** - * Clears all loaded gates - */ - public static void clearGates() { - gates.clear(); - controlBlocks.clear(); - frameBlocks.clear(); - } - } diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index bc74785..ecce367 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -25,12 +25,13 @@ public class LanguageLoader { // Variables private final String languageFolder; + private final Map loadedBackupStrings; private String chosenLanguage; private Map loadedStringTranslations; - private final Map loadedBackupStrings; /** * Instantiates a new language loader + * * @param languageFolder

The folder containing the language files

* @param chosenLanguage

The chosen plugin language

*/ @@ -68,6 +69,7 @@ public class LanguageLoader { /** * Gets the string to display given its name/key + * * @param name

The name/key of the string to display

* @return

The string in the user's preferred language

*/ @@ -87,6 +89,7 @@ public class LanguageLoader { /** * Sets the chosen plugin language + * * @param chosenLanguage

The new plugin language

*/ public void setChosenLanguage(String chosenLanguage) { @@ -95,12 +98,13 @@ public class LanguageLoader { /** * Updates files in the plugin directory with contents from the compiled .jar + * * @param language

The language to update

*/ private void updateLanguage(String language) { // Load the current language file - ArrayList keyList = new ArrayList<>(); - ArrayList valueList = new ArrayList<>(); + List keyList = new ArrayList<>(); + List valueList = new ArrayList<>(); Map currentLanguageValues = load(language); @@ -159,15 +163,16 @@ public class LanguageLoader { /** * Reads language strings - * @param inputStream

The input stream to read from

- * @param keyList

The key list to add keys to

- * @param valueList

The value list to add values to

+ * + * @param inputStream

The input stream to read from

+ * @param keyList

The key list to add keys to

+ * @param valueList

The value list to add values to

* @param currentLanguageValues

The current values of the loaded/processed language

* @return

True if at least one line was updated

* @throws IOException

if unable to read a language file

*/ private boolean readChangedLanguageStrings(InputStream inputStream, List keyList, List valueList, - Map currentLanguageValues) throws IOException { + Map currentLanguageValues) throws IOException { boolean updated = false; // Input stuff InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); @@ -209,6 +214,7 @@ public class LanguageLoader { /** * Loads the given language + * * @param lang

The language to load

* @return

A mapping between loaded string indexes and the strings to display

*/ @@ -218,7 +224,8 @@ public class LanguageLoader { /** * Loads the given language - * @param lang

The language to load

+ * + * @param lang

The language to load

* @param inputStream

An optional input stream to use. Defaults to using a file input stream

* @return

A mapping between loaded string indexes and the strings to display

*/ @@ -253,8 +260,9 @@ public class LanguageLoader { /** * Reads a language file given its input stream + * * @param inputStreamReader

The input stream reader to read from

- * @param strings

The loaded string pairs

+ * @param strings

The loaded string pairs

* @throws IOException

If unable to read the file

*/ private void readLanguageFile(InputStreamReader inputStreamReader, Map strings) throws IOException { @@ -297,6 +305,7 @@ public class LanguageLoader { /** * Removes the UTF-8 Byte Order Mark if present + * * @param string

The string to remove the BOM from

* @return

A string guaranteed without a BOM

*/ diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java index f46f100..065596b 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/Portal.java @@ -26,6 +26,7 @@ import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.UUID; import java.util.logging.Level; @@ -41,49 +42,57 @@ public class Portal { // Block references private final BlockLocation id; + private final Gate gate; + private final World world; private BlockLocation button; private BlockLocation[] frame; private BlockLocation[] entrances; - // Gate information private String name; private String destination; private String lastDestination = ""; private String network; - private final Gate gate; private String ownerName; private UUID ownerUUID; - private final World world; private boolean verified; private boolean fixed; - - // Options - private boolean hidden = false; - private boolean alwaysOn = false; - private boolean isPrivate = false; - private boolean free = false; - private boolean backwards = false; - private boolean show = false; - private boolean noNetwork = false; - private boolean random = false; - private boolean bungee = false; + private Map options; // In-use information private Player player; private Player activePlayer; - private ArrayList destinations = new ArrayList<>(); + private List destinations = new ArrayList<>(); private boolean isOpen = false; private long openTime; + /** + * Instantiates a new portal + * + * @param topLeft

The top-left block of the portal. This is used to decide the positions of the rest of the portal

+ * @param modX

+ * @param modZ

+ * @param rotX

+ * @param id

The location of the portal's id block, which is the sign which activated the portal

+ * @param button

The location of the portal's open button

+ * @param destination

The destination defined on the sign's destination line

+ * @param name

The name of the portal defined on the sign's first line

+ * @param verified

Whether the portal's gate has been verified to match its template

+ * @param network

The network the portal belongs to, defined on the sign's network line

+ * @param gate

The gate template this portal uses

+ * @param ownerUUID

The UUID of the gate's owner

+ * @param ownerName

The name of the gate's owner

+ * @param options

A map containing all possible portal options

+ */ Portal(BlockLocation topLeft, int modX, int modZ, float rotX, BlockLocation id, BlockLocation button, - String dest, String name, boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName) { + String destination, String name, boolean verified, String network, Gate gate, UUID ownerUUID, + String ownerName, Map options) { this.topLeft = topLeft; this.modX = modX; this.modZ = modZ; this.rotX = rotX; this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; this.id = id; - this.destination = dest; + this.destination = destination; this.button = button; this.verified = verified; this.network = network; @@ -91,62 +100,17 @@ public class Portal { this.gate = gate; this.ownerUUID = ownerUUID; this.ownerName = ownerName; + this.options = options; this.world = topLeft.getWorld(); - this.fixed = dest.length() > 0 || this.random || this.bungee; + this.fixed = destination.length() > 0 || this.isRandom() || this.isBungee(); if (this.isAlwaysOn() && !this.isFixed()) { - this.alwaysOn = false; + this.options.put(PortalOption.ALWAYS_ON, false); Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); } - if (this.random && !this.isAlwaysOn()) { - this.alwaysOn = true; - Stargate.debug("Portal", "Gate marked as random, set to always-on"); - } - - if (verified) { - this.drawSign(); - } - } - - Portal(BlockLocation topLeft, int modX, int modZ, - float rotX, BlockLocation id, BlockLocation button, - String dest, String name, - boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, - boolean hidden, boolean alwaysOn, boolean isPrivate, boolean free, boolean backwards, boolean show, boolean noNetwork, boolean random, boolean bungee) { - this.topLeft = topLeft; - this.modX = modX; - this.modZ = modZ; - this.rotX = rotX; - this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; - this.id = id; - this.destination = dest; - this.button = button; - this.verified = verified; - this.network = network; - this.name = name; - this.gate = gate; - this.ownerUUID = ownerUUID; - this.ownerName = ownerName; - this.hidden = hidden; - this.alwaysOn = alwaysOn; - this.isPrivate = isPrivate; - this.free = free; - this.backwards = backwards; - this.show = show; - this.noNetwork = noNetwork; - this.random = random; - this.bungee = bungee; - this.world = topLeft.getWorld(); - this.fixed = dest.length() > 0 || this.random || this.bungee; - - if (this.isAlwaysOn() && !this.isFixed()) { - this.alwaysOn = false; - Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); - } - - if (this.random && !this.isAlwaysOn()) { - this.alwaysOn = true; + if (this.isRandom() && !this.isAlwaysOn()) { + this.options.put(PortalOption.ALWAYS_ON, true); Stargate.debug("Portal", "Gate marked as random, set to always-on"); } @@ -156,102 +120,115 @@ public class Portal { } /** - * Option Check Functions + * Removes the special characters |, : and # from a portal name + * + * @param input

The name to filter

+ * @return

The filtered name

+ */ + public static String filterName(String input) { + if (input == null) { + return ""; + } + return input.replaceAll("[|:#]", "").trim(); + } + + /** + * Gets whether this portal is currently open + * + * @return

Whether this portal is open

*/ public boolean isOpen() { return isOpen || isAlwaysOn(); } + /** + * Gets whether this portal is always on + * + * @return

Whether this portal is always on

+ */ public boolean isAlwaysOn() { - return alwaysOn; - } - - public boolean isHidden() { - return hidden; - } - - public boolean isPrivate() { - return isPrivate; - } - - public boolean isFree() { - return free; - } - - public boolean isBackwards() { - return backwards; - } - - public boolean isShown() { - return show; - } - - public boolean isNoNetwork() { - return noNetwork; - } - - public boolean isRandom() { - return random; - } - - public boolean isBungee() { - return bungee; - } - - public Portal setAlwaysOn(boolean alwaysOn) { - this.alwaysOn = alwaysOn; - return this; - } - - public Portal setHidden(boolean hidden) { - this.hidden = hidden; - return this; - } - - public Portal setPrivate(boolean priv) { - this.isPrivate = priv; - return this; - } - - public Portal setFree(boolean free) { - this.free = free; - return this; - } - - public Portal setBackwards(boolean backwards) { - this.backwards = backwards; - return this; - } - - public Portal setShown(boolean show) { - this.show = show; - return this; - } - - - public Portal setNoNetwork(boolean noNetwork) { - this.noNetwork = noNetwork; - return this; - } - - public Portal setRandom(boolean random) { - this.random = random; - return this; - } - - public Portal setBungee(boolean bungee) { - this.bungee = bungee; - return this; - } - - public void setFixed(boolean fixed) { - this.fixed = fixed; + return this.options.get(PortalOption.ALWAYS_ON); } /** - * Getters and Setters + * Gets whether this portal is hidden + * + * @return

Whether this portal is hidden

*/ + public boolean isHidden() { + return this.options.get(PortalOption.HIDDEN); + } + /** + * Gets whether this portal is private + * + * @return

Whether this portal is private

+ */ + public boolean isPrivate() { + return this.options.get(PortalOption.PRIVATE); + } + + /** + * Gets whether this portal is free + * + * @return

Whether this portal is free

+ */ + public boolean isFree() { + return this.options.get(PortalOption.FREE); + } + + /** + * Gets whether this portal is backwards + * + *

A backwards portal is one where players exit through the back.

+ * + * @return

Whether this portal is backwards

+ */ + public boolean isBackwards() { + return this.options.get(PortalOption.BACKWARDS); + } + + /** + * Gets whether this portal is shown on the network even if it's always on + * + * @return

Whether portal gate is shown

+ */ + public boolean isShown() { + return this.options.get(PortalOption.SHOW); + } + + /** + * Gets whether this portal shows no network + * + * @return

Whether this portal shows no network/p> + */ + public boolean isNoNetwork() { + return this.options.get(PortalOption.NO_NETWORK); + } + + /** + * Gets whether this portal goes to a random location on the network + * + * @return

Whether this portal goes to a random location

+ */ + public boolean isRandom() { + return this.options.get(PortalOption.RANDOM); + } + + /** + * Gets whether this portal is a bungee portal + * + * @return

Whether this portal is a bungee portal

+ */ + public boolean isBungee() { + return this.options.get(PortalOption.BUNGEE); + } + + /** + * Gets the rotation of the portal in degrees + * + * @return

The rotation of the portal

+ */ public float getRotation() { return rotX; } @@ -411,7 +388,7 @@ public class Portal { Portal end = getDestination(); // Only open dest if it's not-fixed or points at this gate - if (!random && end != null && (!end.isFixed() || end.getDestinationName().equalsIgnoreCase(getName())) && !end.isOpen()) { + if (!isRandom() && end != null && (!end.isFixed() || end.getDestinationName().equalsIgnoreCase(getName())) && !end.isOpen()) { end.open(openFor, false); end.setDestination(this); if (end.isVerified()) end.drawSign(); @@ -466,12 +443,17 @@ public class Portal { /** * 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; } + public void setFixed(boolean fixed) { + this.fixed = fixed; + } + public boolean isPowered() { RelativeBlockVector[] controls = gate.getControls(); @@ -488,9 +470,10 @@ public class Portal { /** * 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

+ * @param event

The player move event triggering the event

*/ public void teleport(Player player, Portal origin, PlayerMoveEvent event) { Location traveller = player.getLocation(); @@ -528,6 +511,7 @@ public class Portal { /** * Teleports a vehicle to this portal + * * @param vehicle

The vehicle to teleport

*/ public void teleport(final Vehicle vehicle) { @@ -591,7 +575,8 @@ public class Portal { /** * 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 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.

*/ @@ -624,6 +609,7 @@ public class Portal { /** * Checks whether the chunk the portal is located at is loaded + * * @return

True if the chunk containing the portal is loaded

*/ public boolean isChunkLoaded() { @@ -633,13 +619,13 @@ public class Portal { /** * 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; } @@ -654,6 +640,7 @@ public class Portal { /** * Gets the location of the top-left block of the portal + * * @return

The location of the top-left portal block

*/ public BlockLocation getTopLeft() { @@ -662,6 +649,7 @@ public class Portal { /** * Verifies that all control blocks in this portal follows its gate template + * * @return

True if all control blocks were verified

*/ public boolean isVerified() { @@ -677,6 +665,7 @@ public class Portal { /** * Gets the result of the last portal verification + * * @return

True if this portal was verified

*/ public boolean wasVerified() { @@ -688,6 +677,7 @@ public class Portal { /** * Checks if all blocks in a gate matches the gate template + * * @return

True if all blocks match the gate template

*/ public boolean checkIntegrity() { @@ -699,6 +689,7 @@ public class Portal { /** * Activates this portal for the given player + * * @param player

The player to activate the portal for

* @return

True if the portal was activated

*/ @@ -802,7 +793,7 @@ public class Portal { if (!isActive()) { Stargate.setLine(sign, ++done, Stargate.getString("signRightClick")); Stargate.setLine(sign, ++done, Stargate.getString("signToUse")); - if (!noNetwork) { + if (!isNoNetwork()) { Stargate.setLine(sign, ++done, "(" + network + ")"); } } else { @@ -817,7 +808,7 @@ public class Portal { } else { Stargate.setLine(sign, ++done, ">" + destination + "<"); } - if (noNetwork) { + if (isNoNetwork()) { Stargate.setLine(sign, ++done, ""); } else { Stargate.setLine(sign, ++done, "(" + network + ")"); @@ -887,6 +878,7 @@ public class Portal { /** * Gets the block at a relative block vector location + * * @param vector

The relative block vector

* @return

The block at the given relative position

*/ @@ -894,18 +886,6 @@ public class Portal { return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); } - /** - * Removes the special characters |, : and # from a portal name - * @param input

The name to filter

- * @return

The filtered name

- */ - public static String filterName(String input) { - if (input == null) { - return ""; - } - return input.replaceAll("[|:#]", "").trim(); - } - @Override public String toString() { return String.format("Portal [id=%s, network=%s name=%s, type=%s]", id, network, name, gate.getFilename()); diff --git a/src/main/java/net/knarcraft/stargate/PortalHandler.java b/src/main/java/net/knarcraft/stargate/PortalHandler.java index e3a5e11..83dc1d8 100644 --- a/src/main/java/net/knarcraft/stargate/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/PortalHandler.java @@ -44,13 +44,14 @@ 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

+ * @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(Portal entrancePortal, Player player, String network) { - ArrayList destinations = new ArrayList<>(); + public static List getDestinations(Portal entrancePortal, Player player, String network) { + List destinations = new ArrayList<>(); for (String destination : allPortalsNet.get(network.toLowerCase())) { Portal portal = getByName(destination, network); if (portal == null) { @@ -92,7 +93,8 @@ public class PortalHandler { /** * Un-registers the given portal - * @param portal

The portal to un-register

+ * + * @param portal

The portal to un-register

* @param removeAll

Whether to remove the portal from the list of all portals

*/ public static void unregisterPortal(Portal portal, boolean removeAll) { @@ -148,6 +150,7 @@ public class PortalHandler { /** * Registers a portal + * * @param portal

The portal to register

*/ private static void registerPortal(Portal portal) { @@ -193,7 +196,8 @@ public class PortalHandler { /** * Creates a new portal - * @param event

The sign change event which initialized the creation

+ * + * @param event

The sign change event which initialized the creation

* @param player

The player who's creating the portal

* @return

The created portal

*/ @@ -220,63 +224,7 @@ public class PortalHandler { 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 isPrivate = (options.indexOf('p') != -1); - boolean free = (options.indexOf('f') != -1); - boolean backwards = (options.indexOf('b') != -1); - boolean show = (options.indexOf('s') != -1); - boolean noNetwork = (options.indexOf('n') != -1); - boolean random = (options.indexOf('r') != -1); - boolean bungee = (options.indexOf('u') != -1); - - // Check permissions for options. - if (hidden && !Stargate.canOption(player, "hidden")) { - hidden = false; - } - if (alwaysOn && !Stargate.canOption(player, "alwayson")) { - alwaysOn = false; - } - if (isPrivate && !Stargate.canOption(player, "private")) { - isPrivate = false; - } - if (free && !Stargate.canOption(player, "free")) { - free = false; - } - if (backwards && !Stargate.canOption(player, "backwards")) { - backwards = false; - } - if (show && !Stargate.canOption(player, "show")) { - show = false; - } - if (noNetwork && !Stargate.canOption(player, "nonetwork")) { - noNetwork = false; - } - if (random && !Stargate.canOption(player, "random")) { - random = false; - } - - // Can not create a non-fixed always-on gate. - if (alwaysOn && destinationName.length() == 0) { - alwaysOn = false; - } - - // Show isn't useful if A is false - if (show && !alwaysOn) { - show = false; - } - - // Random gates are always on and can't be shown - if (random) { - alwaysOn = true; - show = false; - } - - // Bungee gates are always on and don't support Random - if (bungee) { - alwaysOn = true; - random = false; - } + Map portalOptions = getPortalOptions(player, destinationName, options); // Moved the layout check so as to avoid invalid messages when not making a gate int modX = 0; @@ -340,13 +288,16 @@ public class PortalHandler { // If the player is trying to create a Bungee gate without permissions, drop out here // Do this after the gate layout check, in the least - if (bungee) { + if (options.indexOf(PortalOption.BUNGEE.getCharacterRepresentation()) != -1) { + if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { + Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); + return null; + } + } + if (portalOptions.get(PortalOption.BUNGEE)) { if (!Stargate.enableBungee) { Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); return null; - } else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { - Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); - return null; } else if (destinationName.isEmpty() || network.isEmpty()) { Stargate.sendMessage(player, Stargate.getString("bungeeEmpty")); return null; @@ -354,9 +305,13 @@ public class PortalHandler { } // Debug - Stargate.debug("createPortal", "h = " + hidden + " a = " + alwaysOn + " p = " + isPrivate + " f = " + free + " b = " + backwards + " s = " + show + " n = " + noNetwork + " r = " + random + " u = " + bungee); + StringBuilder builder = new StringBuilder(); + for (PortalOption option : portalOptions.keySet()) { + builder.append(option.getCharacterRepresentation()).append(" = ").append(portalOptions.get(option)).append(" "); + } + Stargate.debug("createPortal", builder.toString()); - if (!bungee && (network.length() < 1 || network.length() > 11)) { + if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > 11)) { network = Stargate.getDefaultNetwork(); } @@ -364,7 +319,7 @@ public class PortalHandler { String denyMsg = ""; // Check if the player can create gates on this network - if (!bungee && !Stargate.canCreate(player, network)) { + if (!portalOptions.get(PortalOption.BUNGEE) && !Stargate.canCreate(player, network)) { Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); if (Stargate.canCreatePersonal(player)) { network = player.getName(); @@ -389,7 +344,7 @@ public class PortalHandler { } // Check if the user can create gates to this world. - if (!bungee && !deny && destinationName.length() > 0) { + if (!portalOptions.get(PortalOption.BUNGEE) && !deny && destinationName.length() > 0) { Portal p = getByName(destinationName, network); if (p != null) { String world = p.getWorld().getName(); @@ -413,7 +368,8 @@ public class PortalHandler { BlockLocation button = null; Portal portal; - 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); + portal = new Portal(topLeft, modX, modZ, rotX, id, button, destinationName, name, false, network, + gate, player.getUniqueId(), player.getName(), portalOptions); int cost = Stargate.getCreateCost(player, gate); @@ -469,11 +425,11 @@ public class PortalHandler { } // No button on an always-open gate. - if (!alwaysOn) { + if (!portalOptions.get(PortalOption.ALWAYS_ON)) { button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); - Directional buttondata = (Directional) Bukkit.createBlockData(gate.getButton()); - buttondata.setFacing(buttonFacing); - button.getBlock().setBlockData(buttondata); + Directional buttonData = (Directional) Bukkit.createBlockData(gate.getButton()); + buttonData.setFacing(buttonFacing); + button.getBlock().setBlockData(buttonData); portal.setButton(button); } @@ -513,9 +469,49 @@ public class PortalHandler { return portal; } + /** + * Gets all portal options to be applied to a new gate + * + * @param player

The player creating the portal

+ * @param destinationName

The destination of the portal

+ * @param options

The string on the option line of the sign

+ * @return

A map containing all portal options and their values

+ */ + private static Map getPortalOptions(Player player, String destinationName, String options) { + Map portalOptions = new HashMap<>(); + for (PortalOption option : PortalOption.values()) { + portalOptions.put(option, options.indexOf(option.getCharacterRepresentation()) != -1 && + Stargate.canOption(player, option)); + } + + // Can not create a non-fixed always-on gate. + if (portalOptions.get(PortalOption.ALWAYS_ON) && destinationName.length() == 0) { + portalOptions.put(PortalOption.ALWAYS_ON, false); + } + + // Show isn't useful if always on is false + if (portalOptions.get(PortalOption.SHOW) && !portalOptions.get(PortalOption.ALWAYS_ON)) { + portalOptions.put(PortalOption.SHOW, false); + } + + // Random gates are always on and can't be shown + if (portalOptions.get(PortalOption.RANDOM)) { + portalOptions.put(PortalOption.ALWAYS_ON, true); + portalOptions.put(PortalOption.SHOW, false); + } + + // Bungee gates are always on and don't support Random + if (portalOptions.get(PortalOption.BUNGEE)) { + portalOptions.put(PortalOption.ALWAYS_ON, true); + portalOptions.put(PortalOption.RANDOM, false); + } + return portalOptions; + } + /** * Gets a portal given its name - * @param name

The name of the portal

+ * + * @param name

The name of the portal

* @param network

The network the portal is connected to

* @return

The portal with the given name or null

*/ @@ -529,6 +525,7 @@ public class PortalHandler { /** * Gets a portal given its entrance + * * @param location

The location of the portal's entrance

* @return

The portal at the given location

*/ @@ -539,6 +536,7 @@ public class PortalHandler { /** * Gets a portal given its entrance + * * @param block

The block at the portal's entrance

* @return

The portal at the given block's location

*/ @@ -548,6 +546,7 @@ public class PortalHandler { /** * Gets a portal given a location adjacent to its entrance + * * @param loc

A location adjacent to the portal's entrance

* @return

The portal adjacent to the given location

*/ @@ -581,6 +580,7 @@ public class PortalHandler { /** * Gets a portal given its control block (the block type used for the sign and button) + * * @param block

The portal's control block

* @return

The gate with the given control block

*/ @@ -590,6 +590,7 @@ public class PortalHandler { /** * Gets a portal given a block + * * @param block

One of the loaded lookup blocks

* @return

The portal corresponding to the block

*/ @@ -599,6 +600,7 @@ public class PortalHandler { /** * Gets a bungee gate given its name + * * @param name

The name of the bungee gate to get

* @return

A bungee gate

*/ @@ -608,6 +610,7 @@ public class PortalHandler { /** * Saves all gates for the given world + * * @param world

The world to save gates for

*/ public static void saveAllGates(World world) { @@ -694,6 +697,7 @@ public class PortalHandler { /** * Loads all gates for the given world + * * @param world

The world to load gates for

* @return

True if gates could be loaded

*/ @@ -712,103 +716,123 @@ public class PortalHandler { /** * Loads all the given gates - * @param world

The world to load gates for

+ * + * @param world

The world to load gates for

* @param database

The database file containing the gates

* @return

True if the gates were loaded successfully

*/ private static boolean loadGates(World world, File database) { - int l = 0; + int lineIndex = 0; try { Scanner scanner = new Scanner(database); while (scanner.hasNextLine()) { - l++; + lineIndex++; String line = scanner.nextLine().trim(); + + //Ignore empty and comment lines if (line.startsWith("#") || line.isEmpty()) { continue; } + + //Check if the min. required portal data is present String[] portalData = line.split(":"); if (portalData.length < 8) { - Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + l); - continue; - } - String name = portalData[0]; - BlockLocation sign = new BlockLocation(world, portalData[1]); - BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; - int modX = Integer.parseInt(portalData[3]); - int modZ = Integer.parseInt(portalData[4]); - float rotX = Float.parseFloat(portalData[5]); - BlockLocation topLeft = new BlockLocation(world, portalData[6]); - Gate gate = Gate.getGateByName(portalData[7]); - if (gate == null) { - Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + l + " does not exist [" + portalData[7] + "]"); + Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); continue; } - String destination = (portalData.length > 8) ? portalData[8] : ""; - String network = (portalData.length > 9) ? portalData[9] : Stargate.getDefaultNetwork(); - if (network.isEmpty()) network = Stargate.getDefaultNetwork(); - String ownerString = (portalData.length > 10) ? portalData[10] : ""; - - // Attempt to get owner as UUID - UUID ownerUUID = null; - String ownerName; - if (ownerString.length() > 16) { - try { - ownerUUID = UUID.fromString(ownerString); - OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); - ownerName = offlineOwner.getName(); - } catch (IllegalArgumentException ex) { - // neither name nor UUID, so keep it as-is - ownerName = ownerString; - Stargate.debug("loadAllGates", "Invalid stargate owner string: " + ownerString); - } - } else { - ownerName = ownerString; - } - - //Creates the new portal - Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, destination, name, false, network, - gate, ownerUUID, ownerName); - loadPortalOptions(portal, portalData); - - registerPortal(portal); - portal.close(true); + loadGate(portalData, world, lineIndex); } scanner.close(); // Open any always-on gates. Do this here as it should be more efficient than in the loop. TwoTuple portalCounts = openAlwaysOpenGates(); - Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} Loaded " + portalCounts.getSecondValue() + " stargates with " + portalCounts.getFirstValue() + " set as always-on"); + Stargate.log.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", + Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), + portalCounts.getFirstValue())); return true; } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + l); + Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + lineIndex); e.printStackTrace(); } return false; } /** - * Loads all portal options and updates the given portal - * @param portal

The portal to apply the options to

- * @param portalData

The string list containing all information about a portal

+ * Loads one gate from a data array + * + * @param portalData

The array describing the portal

+ * @param world

The world to create the portal in

+ * @param lineIndex

The line index to report in case the user needs to fix an error

*/ - private static void loadPortalOptions(Portal portal, String[] portalData) { - boolean hidden = (portalData.length > 11) && portalData[11].equalsIgnoreCase("true"); - boolean alwaysOn = (portalData.length > 12) && portalData[12].equalsIgnoreCase("true"); - boolean isPrivate = (portalData.length > 13) && portalData[13].equalsIgnoreCase("true"); - boolean free = (portalData.length > 15) && portalData[15].equalsIgnoreCase("true"); - boolean backwards = (portalData.length > 16) && portalData[16].equalsIgnoreCase("true"); - boolean show = (portalData.length > 17) && portalData[17].equalsIgnoreCase("true"); - boolean noNetwork = (portalData.length > 18) && portalData[18].equalsIgnoreCase("true"); - boolean random = (portalData.length > 19) && portalData[19].equalsIgnoreCase("true"); - boolean bungee = (portalData.length > 20) && portalData[20].equalsIgnoreCase("true"); - portal.setHidden(hidden).setAlwaysOn(alwaysOn).setPrivate(isPrivate).setFree(free).setBungee(bungee); - portal.setBackwards(backwards).setShown(show).setNoNetwork(noNetwork).setRandom(random); + private static void loadGate(String[] portalData, World world, int lineIndex) { + //Load min. required portal data + String name = portalData[0]; + BlockLocation sign = new BlockLocation(world, portalData[1]); + BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; + int modX = Integer.parseInt(portalData[3]); + int modZ = Integer.parseInt(portalData[4]); + float rotX = Float.parseFloat(portalData[5]); + BlockLocation topLeft = new BlockLocation(world, portalData[6]); + Gate gate = Gate.getGateByName(portalData[7]); + if (gate == null) { + Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + + " does not exist [" + portalData[7] + "]"); + return; + } + + //Load extra portal data + String destination = (portalData.length > 8) ? portalData[8] : ""; + String network = (portalData.length > 9) ? portalData[9] : Stargate.getDefaultNetwork(); + if (network.isEmpty()) { + network = Stargate.getDefaultNetwork(); + } + String ownerString = (portalData.length > 10) ? portalData[10] : ""; + + // Attempt to get owner as UUID + UUID ownerUUID = null; + String ownerName; + if (ownerString.length() > 16) { + try { + ownerUUID = UUID.fromString(ownerString); + OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); + ownerName = offlineOwner.getName(); + } catch (IllegalArgumentException ex) { + // neither name nor UUID, so keep it as-is + ownerName = ownerString; + Stargate.debug("loadAllGates", "Invalid stargate owner string: " + ownerString); + } + } else { + ownerName = ownerString; + } + + //Creates the new portal + Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, destination, name, false, + network, gate, ownerUUID, ownerName, getPortalOptions(portalData)); + + registerPortal(portal); + portal.close(true); + } + + /** + * Gets all portal options stored in the portal data + * + * @param portalData

The string list containing all information about a portal

+ * @return

A map between portal options and booleans

+ */ + private static Map getPortalOptions(String[] portalData) { + Map portalOptions = new HashMap<>(); + for (PortalOption option : PortalOption.values()) { + int saveIndex = option.getSaveIndex(); + portalOptions.put(option, portalData.length > saveIndex && Boolean.parseBoolean(portalData[saveIndex])); + } + return portalOptions; } /** * Opens all always open gates + * * @return

A TwoTuple where the first value is the number of always open gates and the second value is the total number of gates

*/ private static TwoTuple openAlwaysOpenGates() { @@ -840,6 +864,7 @@ public class PortalHandler { /** * Destroys a star gate which has failed its integrity test + * * @param portal

The portal of the star gate

*/ private static void destroyInvalidStarGate(Portal portal) { @@ -867,6 +892,7 @@ public class PortalHandler { /** * Removes the special characters |, : and # from a portal name + * * @param input

The name to filter

* @return

The filtered name

*/ diff --git a/src/main/java/net/knarcraft/stargate/PortalOption.java b/src/main/java/net/knarcraft/stargate/PortalOption.java new file mode 100644 index 0000000..1c87685 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/PortalOption.java @@ -0,0 +1,93 @@ +package net.knarcraft.stargate; + +public enum PortalOption { + + /** + * This option allows a portal to be hidden from others + */ + HIDDEN('h', "stargate.option.hidden", 11), + + /** + * This option allows a portal that's always on and does not need to be activated or opened each time + */ + ALWAYS_ON('a', "stargate.option.alwayson", 12), + + /** + * This option allows a portal that's private to the stargate's owner + */ + PRIVATE('p', "stargate.option.private", 13), + + /** + * This option allows a portal that's free even if stargates usually are not + */ + FREE('f', "stargate.option.free", 15), + + /** + * This option allows a portal where players exit through the back of the portal + */ + BACKWARDS('b', "stargate.option.backwards", 16), + + /** + * This option shows the gate in the network list even if it's always on + */ + SHOW('s', "stargate.option.show", 17), + + /** + * This option hides the network name on the sign + */ + NO_NETWORK('n', "stargate.option.nonetwork", 18), + + /** + * This option allows a portal where players teleport to a random exit portal in the network + */ + RANDOM('r', "stargate.option.random", 19), + + /** + * This option allows a portal to teleport to another server connected through BungeeCord + */ + BUNGEE('u', "stargate.admin.bungee", 20); + + private final char characterRepresentation; + private final String permissionString; + private final int saveIndex; + + /** + * Instantiates a new portal options + * + * @param characterRepresentation

The character representation used on the sign to allow this option

+ * @param permissionString

The permission necessary to use this option

+ */ + PortalOption(final char characterRepresentation, String permissionString, int saveIndex) { + this.characterRepresentation = characterRepresentation; + this.permissionString = permissionString; + this.saveIndex = saveIndex; + } + + /** + * Gets the character representation used to enable this setting on the sign + * + * @return

The character representation of this option

+ */ + public char getCharacterRepresentation() { + return this.characterRepresentation; + } + + /** + * Gets the permission necessary to use this option + * + * @return

The permission necessary for this option

+ */ + public String getPermissionString() { + return this.permissionString; + } + + /** + * Gets the index of the save file this option is stored at + * + * @return

This option's save index

+ */ + public int getSaveIndex() { + return this.saveIndex; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index edfd6b0..3160361 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -16,8 +16,9 @@ public class RelativeBlockVector { /** * Instantiates a new relative block vector - * @param right

The distance to the right relative to the origin

- * @param depth

The distance downward relative to the origin

+ * + * @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) { @@ -28,6 +29,7 @@ public class RelativeBlockVector { /** * Gets the distance to the right relative to the origin + * * @return The distance to the right relative to the origin */ public int getRight() { @@ -36,6 +38,7 @@ public class RelativeBlockVector { /** * Gets the distance downward relative to the origin + * * @return The distance downward relative to the origin */ public int getDepth() { @@ -44,6 +47,7 @@ public class RelativeBlockVector { /** * Gets the distance outward relative to the origin + * * @return The distance outward relative to the origin */ public int getDistance() { diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 157bfa4..5bd8765 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -41,25 +41,14 @@ import java.util.logging.Logger; @SuppressWarnings("unused") public class Stargate extends JavaPlugin { + public static final ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); + private static final int activeTime = 10; + private static final int openTime = 10; public static Logger log; - private FileConfiguration newConfig; - private PluginManager pm; public static Server server; public static Stargate stargate; public static LanguageLoader languageLoader; - - private static String pluginVersion; - - private static String portalFolder; - private static String gateFolder; - private static String langFolder; - private static String defNetwork = "central"; - - private static boolean destroyExplosion = false; public static int maxGates = 0; - private static String langName = "en"; - private static final int activeTime = 10; - private static final int openTime = 10; public static boolean destMemory = false; public static boolean handleVehicles = true; public static boolean sortLists = false; @@ -67,115 +56,45 @@ public class Stargate extends JavaPlugin { public static boolean enableBungee = true; public static boolean verifyPortals = true; public static ChatColor signColor; - // Temp workaround for snowmen, don't check gate entrance public static boolean ignoreEntrance = false; - // Used for debug public static boolean debug = false; public static boolean permDebug = false; - - public static final ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); public static ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); - // Used for populating gate open/closed material. public static Queue blockPopulatorQueue = new LinkedList<>(); - // HashMap of player names for Bungee support public static Map bungeeQueue = new HashMap<>(); - // World names that contain stargates public static HashSet managedWorlds = new HashSet<>(); + private static String pluginVersion; + private static String portalFolder; + private static String gateFolder; + private static String langFolder; + private static String defNetwork = "central"; + private static boolean destroyExplosion = false; + private static String langName = "en"; + private FileConfiguration newConfig; + private PluginManager pm; public Stargate() { super(); + } /** * Special constructor used for MockBukkit - * @param loader

The plugin loader to be used.

+ * + * @param loader

The plugin loader to be used.

* @param descriptionFile

The description file to be used.

- * @param dataFolder

The data folder to be used.

- * @param file

The file to be used

+ * @param dataFolder

The data folder to be used.

+ * @param file

The file to be used

*/ protected Stargate(JavaPluginLoader loader, PluginDescriptionFile descriptionFile, File dataFolder, File file) { super(loader, descriptionFile, dataFolder, file); } - @Override - public void onDisable() { - PortalHandler.closeAllGates(); - PortalHandler.clearGates(); - managedWorlds.clear(); - getServer().getScheduler().cancelTasks(this); - } - - @Override - public void onEnable() { - PluginDescriptionFile pluginDescriptionFile = this.getDescription(); - pm = getServer().getPluginManager(); - newConfig = this.getConfig(); - log = Logger.getLogger("Minecraft"); - Stargate.server = getServer(); - Stargate.stargate = this; - - // Set portalFile and gateFolder to the plugin folder as defaults. - String dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); - portalFolder = dataFolderPath + "/portals/"; - gateFolder = dataFolderPath + "/gates/"; - langFolder = dataFolderPath + "/lang/"; - - 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); - pm.registerEvents(new BlockEventListener(), this); - - pm.registerEvents(new VehicleEventListener(), this); - pm.registerEvents(new EntityEventListener(), this); - pm.registerEvents(new WorldEventListener(), this); - pm.registerEvents(new PluginEventListener(this), this); - - this.loadConfig(); - - // Enable the required channels for Bungee support - if (enableBungee) { - Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); - } - - // It is important to load languages here, as they are used during reloadGates() - languageLoader = new LanguageLoader(langFolder, Stargate.langName); - - this.migrate(); - this.loadGates(); - this.loadAllPortals(); - - // Check to see if Economy is loaded yet. - if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) { - String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); - log.info(Stargate.getString("prefix") + - replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); - } - } - - 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; } @@ -192,86 +111,6 @@ public class Stargate extends JavaPlugin { return activeTime; } - public void loadConfig() { - reloadConfig(); - newConfig = this.getConfig(); - // Copy default values if required - newConfig.options().copyDefaults(true); - - // Load values into variables - portalFolder = newConfig.getString("portal-folder"); - gateFolder = newConfig.getString("gate-folder"); - defNetwork = newConfig.getString("default-gate-network").trim(); - destroyExplosion = newConfig.getBoolean("destroyexplosion"); - maxGates = newConfig.getInt("maxgates"); - langName = newConfig.getString("lang"); - destMemory = newConfig.getBoolean("destMemory"); - ignoreEntrance = newConfig.getBoolean("ignoreEntrance"); - handleVehicles = newConfig.getBoolean("handleVehicles"); - sortLists = newConfig.getBoolean("sortLists"); - protectEntrance = newConfig.getBoolean("protectEntrance"); - enableBungee = newConfig.getBoolean("enableBungee"); - verifyPortals = newConfig.getBoolean("verifyPortals"); - // Sign color - String sc = newConfig.getString("signColor"); - try { - signColor = ChatColor.valueOf(sc.toUpperCase()); - } catch (Exception ignore) { - log.warning(Stargate.getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); - signColor = ChatColor.BLACK; - } - // Debug - debug = newConfig.getBoolean("debug"); - permDebug = newConfig.getBoolean("permdebug"); - // Economy - EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); - EconomyHandler.createCost = newConfig.getInt("createcost"); - EconomyHandler.destroyCost = newConfig.getInt("destroycost"); - EconomyHandler.useCost = newConfig.getInt("usecost"); - EconomyHandler.toOwner = newConfig.getBoolean("toowner"); - EconomyHandler.chargeFreeDestination = newConfig.getBoolean("chargefreedestination"); - EconomyHandler.freeGatesGreen = newConfig.getBoolean("freegatesgreen"); - - this.saveConfig(); - } - - public void closeAllPortals() { - // Close all gates prior to reloading - for (Portal p : openList) { - p.close(true); - } - } - - public void loadGates() { - Gate.loadGates(gateFolder); - log.info(Stargate.getString("prefix") + "Loaded " + Gate.getGateCount() + " gate layouts"); - } - - public void loadAllPortals() { - for (World world : getServer().getWorlds()) { - if (!managedWorlds.contains(world.getName())) { - PortalHandler.loadAllGates(world); - managedWorlds.add(world.getName()); - } - } - } - - private void migrate() { - // Only migrate if new file doesn't exist. - File newPortalDir = new File(portalFolder); - if (!newPortalDir.exists()) { - if (!newPortalDir.mkdirs()) { - log.severe("Unable to create portal directory"); - } - } - File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); - if (!newFile.exists()) { - if (!newFile.getParentFile().mkdirs()) { - log.severe("Unable to create portal directory"); - } - } - } - public static void debug(String rout, String msg) { if (Stargate.debug) { log.info("[stargate::" + rout + "] " + msg); @@ -442,9 +281,10 @@ public class Stargate extends JavaPlugin { /** * Checks whether a given user can travel between two portals - * @param player

The player to check

+ * + * @param player

The player to check

* @param entrancePortal

The portal the user wants to enter

- * @param destination

The portal the user wants to exit

+ * @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) { @@ -497,11 +337,13 @@ public class Stargate extends JavaPlugin { /* * Check if the player has access to {option} */ - public static boolean canOption(Player player, String option) { + public static boolean canOption(Player player, PortalOption option) { // Check if the player can use all options - if (hasPerm(player, "stargate.option")) return true; + if (hasPerm(player, "stargate.option") || option == PortalOption.BUNGEE) { + return true; + } // Check if they can use this specific option - return hasPerm(player, "stargate.option." + option); + return hasPerm(player, option.getPermissionString()); } /* @@ -629,6 +471,190 @@ public class Stargate extends JavaPlugin { return gate.getDestroyCost(); } + /** + * Replaces a list of variables in a string in the order they are given + * + * @param input

The input containing the variables

+ * @param search

The variables to replace

+ * @param values

The replacement values

+ * @return

The input string with the search values replaced with the given values

+ */ + public static String replaceVars(String input, String[] search, String[] values) { + if (search.length != values.length) { + throw new IllegalArgumentException("The number of search values and replace values do not match."); + } + for (int i = 0; i < search.length; i++) { + input = replaceVars(input, search[i], values[i]); + } + return input; + } + + /** + * Replaces a variable in a string + * + * @param input

The input containing the variables

+ * @param search

The variable to replace

+ * @param value

The replacement value

+ * @return

The input string with the search replaced with value

+ */ + public static String replaceVars(String input, String search, String value) { + return input.replace(search, value); + } + + @Override + public void onDisable() { + PortalHandler.closeAllGates(); + PortalHandler.clearGates(); + managedWorlds.clear(); + getServer().getScheduler().cancelTasks(this); + } + + @Override + public void onEnable() { + PluginDescriptionFile pluginDescriptionFile = this.getDescription(); + pm = getServer().getPluginManager(); + newConfig = this.getConfig(); + log = Logger.getLogger("Minecraft"); + Stargate.server = getServer(); + Stargate.stargate = this; + + // Set portalFile and gateFolder to the plugin folder as defaults. + String dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); + portalFolder = dataFolderPath + "/portals/"; + gateFolder = dataFolderPath + "/gates/"; + langFolder = dataFolderPath + "/lang/"; + + 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); + pm.registerEvents(new BlockEventListener(), this); + + pm.registerEvents(new VehicleEventListener(), this); + pm.registerEvents(new EntityEventListener(), this); + pm.registerEvents(new WorldEventListener(), this); + pm.registerEvents(new PluginEventListener(this), this); + + this.loadConfig(); + + // Enable the required channels for Bungee support + if (enableBungee) { + Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); + } + + // It is important to load languages here, as they are used during reloadGates() + languageLoader = new LanguageLoader(langFolder, Stargate.langName); + + this.migrate(); + this.loadGates(); + this.loadAllPortals(); + + // Check to see if Economy is loaded yet. + if (EconomyHandler.setupEconomy(pm)) { + if (EconomyHandler.economy != null) { + String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + log.info(Stargate.getString("prefix") + + replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + } + } + + 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 void loadConfig() { + reloadConfig(); + newConfig = this.getConfig(); + // Copy default values if required + newConfig.options().copyDefaults(true); + + // Load values into variables + portalFolder = newConfig.getString("portal-folder"); + gateFolder = newConfig.getString("gate-folder"); + defNetwork = newConfig.getString("default-gate-network").trim(); + destroyExplosion = newConfig.getBoolean("destroyexplosion"); + maxGates = newConfig.getInt("maxgates"); + langName = newConfig.getString("lang"); + destMemory = newConfig.getBoolean("destMemory"); + ignoreEntrance = newConfig.getBoolean("ignoreEntrance"); + handleVehicles = newConfig.getBoolean("handleVehicles"); + sortLists = newConfig.getBoolean("sortLists"); + protectEntrance = newConfig.getBoolean("protectEntrance"); + enableBungee = newConfig.getBoolean("enableBungee"); + verifyPortals = newConfig.getBoolean("verifyPortals"); + // Sign color + String sc = newConfig.getString("signColor"); + try { + signColor = ChatColor.valueOf(sc.toUpperCase()); + } catch (Exception ignore) { + log.warning(Stargate.getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); + signColor = ChatColor.BLACK; + } + // Debug + debug = newConfig.getBoolean("debug"); + permDebug = newConfig.getBoolean("permdebug"); + // Economy + EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); + EconomyHandler.createCost = newConfig.getInt("createcost"); + EconomyHandler.destroyCost = newConfig.getInt("destroycost"); + EconomyHandler.useCost = newConfig.getInt("usecost"); + EconomyHandler.toOwner = newConfig.getBoolean("toowner"); + EconomyHandler.chargeFreeDestination = newConfig.getBoolean("chargefreedestination"); + EconomyHandler.freeGatesGreen = newConfig.getBoolean("freegatesgreen"); + + this.saveConfig(); + } + + public void closeAllPortals() { + // Close all gates prior to reloading + for (Portal p : openList) { + p.close(true); + } + } + + public void loadGates() { + Gate.loadGates(gateFolder); + log.info(Stargate.getString("prefix") + "Loaded " + Gate.getGateCount() + " gate layouts"); + } + + public void loadAllPortals() { + for (World world : getServer().getWorlds()) { + if (!managedWorlds.contains(world.getName())) { + PortalHandler.loadAllGates(world); + managedWorlds.add(world.getName()); + } + } + } + + private void migrate() { + // Only migrate if new file doesn't exist. + File newPortalDir = new File(portalFolder); + if (!newPortalDir.exists()) { + if (!newPortalDir.mkdirs()) { + log.severe("Unable to create portal directory"); + } + } + File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); + if (!newFile.exists()) { + if (!newFile.getParentFile().mkdirs()) { + log.severe("Unable to create portal directory"); + } + } + } + /* * Check if a plugin is loaded/enabled already. Returns the plugin if so, null otherwise */ @@ -645,36 +671,9 @@ public class Stargate extends JavaPlugin { return null; } - /** - * Replaces a list of variables in a string in the order they are given - * @param input

The input containing the variables

- * @param search

The variables to replace

- * @param values

The replacement values

- * @return

The input string with the search values replaced with the given values

- */ - public static String replaceVars(String input, String[] search, String[] values) { - if (search.length != values.length) { - throw new IllegalArgumentException("The number of search values and replace values do not match."); - } - for (int i = 0; i < search.length; i++) { - input = replaceVars(input, search[i], values[i]); - } - return input; - } - - /** - * Replaces a variable in a string - * @param input

The input containing the variables

- * @param search

The variable to replace

- * @param value

The replacement value

- * @return

The input string with the search replaced with value

- */ - public static String replaceVars(String input, String search, String value) { - return input.replace(search, value); - } - /** * Reloads all portals and files + * * @param sender

The sender of the reload request

*/ public void reload(CommandSender sender) { diff --git a/src/main/java/net/knarcraft/stargate/TwoTuple.java b/src/main/java/net/knarcraft/stargate/TwoTuple.java index f2a8593..6167fac 100644 --- a/src/main/java/net/knarcraft/stargate/TwoTuple.java +++ b/src/main/java/net/knarcraft/stargate/TwoTuple.java @@ -2,17 +2,19 @@ package net.knarcraft.stargate; /** * This class allows storing two values of any type + * * @param

The first type

* @param

The second type

*/ -public class TwoTuple { +public class TwoTuple { private K firstValue; private L secondValue; /** * Instantiate a new TwoTuple - * @param firstValue

The first value

+ * + * @param firstValue

The first value

* @param secondValue

The second value

*/ public TwoTuple(K firstValue, L secondValue) { @@ -22,6 +24,7 @@ public class TwoTuple { /** * Gets the first value + * * @return

The first value

*/ public K getFirstValue() { @@ -30,6 +33,7 @@ public class TwoTuple { /** * Gets the second value + * * @return

The second value

*/ public L getSecondValue() { diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index a81dfc7..3147062 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -16,6 +16,7 @@ public class CommandReload implements CommandExecutor { /** * Instantiates the reload command + * * @param plugin

A reference to the calling plugin object

*/ public CommandReload(Stargate plugin) { diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index 63687d7..bcc86ab 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -19,6 +19,7 @@ public class CommandStarGate implements CommandExecutor { /** * Instantiates the stargate command + * * @param plugin

A reference to the calling plugin object

*/ public CommandStarGate(Stargate plugin) { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 71f2fe8..8925d53 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -11,46 +11,49 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class StargateAccessEvent extends StargatePlayerEvent { - private boolean deny; - - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); + private boolean deny; /** * Instantiates a new stargate access event + * * @param player

The player involved in the vent

* @param portal

The portal involved in the event

- * @param deny

Whether the event should be denied

+ * @param deny

Whether the event should be denied

*/ - public StargateAccessEvent(Player player, Portal portal, boolean deny) { - super("StargateAccessEvent", portal, player); + public StargateAccessEvent(Player player, Portal portal, boolean deny) { + super("StargateAccessEvent", portal, player); - this.deny = deny; - } - - /** - * Gets whether the player should be denied access - * @return

Whether the player should be denied access

- */ - public boolean getDeny() { - return this.deny; - } - - /** - * Sets whether to deny the player - * @param deny

Whether to deny the player

- */ - public void setDeny(boolean deny) { - this.deny = deny; - } + this.deny = deny; + } /** * Gets a handler-list containing all event handlers + * * @return

A handler-list with all event handlers

*/ public static HandlerList getHandlerList() { return handlers; } + /** + * Gets whether the player should be denied access + * + * @return

Whether the player should be denied access

+ */ + public boolean getDeny() { + return this.deny; + } + + /** + * Sets whether to deny the player + * + * @param deny

Whether to deny the player

+ */ + public void setDeny(boolean deny) { + this.deny = deny; + } + @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index 3f522a7..ea73802 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -14,11 +14,10 @@ import java.util.List; @SuppressWarnings("unused") public class StargateActivateEvent extends StargatePlayerEvent { + private static final HandlerList handlers = new HandlerList(); private List destinations; private String destination; - private static final HandlerList handlers = new HandlerList(); - /** * Instantiates a new stargate activate event * @@ -34,6 +33,15 @@ public class StargateActivateEvent extends StargatePlayerEvent { this.destination = destination; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + /** * Gets the destinations available for the portal * @@ -70,15 +78,6 @@ public class StargateActivateEvent extends StargatePlayerEvent { this.destination = destination; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index a5e5ace..aacb0d5 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -10,9 +10,8 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class StargateCloseEvent extends StargateEvent { - private boolean force; - private static final HandlerList handlers = new HandlerList(); + private boolean force; /** * Instantiates a new stargate closing event @@ -26,6 +25,15 @@ public class StargateCloseEvent extends StargateEvent { this.force = force; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + /** * Gets whether to force the stargate to close * @@ -44,15 +52,6 @@ public class StargateCloseEvent extends StargateEvent { this.force = force; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - @NotNull @Override public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java index bd23679..6f901cd 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -11,13 +11,12 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class StargateCreateEvent extends StargatePlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final String[] lines; private boolean deny; private String denyReason; - private final String[] lines; private int cost; - private static final HandlerList handlers = new HandlerList(); - /** * Instantiates a new stargate creation event * @@ -36,6 +35,15 @@ public class StargateCreateEvent extends StargatePlayerEvent { this.cost = cost; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + /** * Gets a given line from the sign creating the star gate * @@ -101,15 +109,6 @@ public class StargateCreateEvent extends StargatePlayerEvent { this.cost = cost; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - @NotNull @Override public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index ffbf716..0b66b6d 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -11,19 +11,19 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class StargateDestroyEvent extends StargatePlayerEvent { + private static final HandlerList handlers = new HandlerList(); private boolean deny; private String denyReason; private int cost; - private static final HandlerList handlers = new HandlerList(); - /** * Instantiates a new Stargate Destroy Event - * @param portal

The portal destroyed

- * @param player

The player destroying the portal

- * @param deny

Whether the event should be denied (cancelled)

+ * + * @param portal

The portal destroyed

+ * @param player

The player destroying the portal

+ * @param deny

Whether the event should be denied (cancelled)

* @param denyMsg

The message to display if the event is denied

- * @param cost

The cost of destroying the portal

+ * @param cost

The cost of destroying the portal

*/ public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { super("StargateDestroyEvent", portal, player); @@ -32,54 +32,6 @@ public class StargateDestroyEvent extends StargatePlayerEvent { this.cost = cost; } - /** - * Gets whether this event should be denied - * @return

Whether this event should be denied

- */ - public boolean getDeny() { - return deny; - } - - /** - * Sets whether this event should be denied - * @param deny

Whether this event should be denied

- */ - public void setDeny(boolean deny) { - this.deny = deny; - } - - /** - * Gets the reason the event was denied - * @return

The reason the event was denied

- */ - public String getDenyReason() { - return denyReason; - } - - /** - * Sets the reason the event was denied - * @param denyReason

The reason the event was denied

- */ - public void setDenyReason(String denyReason) { - this.denyReason = denyReason; - } - - /** - * Gets the cost of destroying the portal - * @return

The cost of destroying the portal

- */ - public int getCost() { - return cost; - } - - /** - * Sets the cost of destroying the portal - * @param cost

The cost of destroying the portal

- */ - public void setCost(int cost) { - this.cost = cost; - } - /** * Gets a handler-list containing all event handlers * @@ -89,6 +41,60 @@ public class StargateDestroyEvent extends StargatePlayerEvent { return handlers; } + /** + * Gets whether this event should be denied + * + * @return

Whether this event should be denied

+ */ + public boolean getDeny() { + return deny; + } + + /** + * Sets whether this event should be denied + * + * @param deny

Whether this event should be denied

+ */ + public void setDeny(boolean deny) { + this.deny = deny; + } + + /** + * Gets the reason the event was denied + * + * @return

The reason the event was denied

+ */ + public String getDenyReason() { + return denyReason; + } + + /** + * Sets the reason the event was denied + * + * @param denyReason

The reason the event was denied

+ */ + public void setDenyReason(String denyReason) { + this.denyReason = denyReason; + } + + /** + * Gets the cost of destroying the portal + * + * @return

The cost of destroying the portal

+ */ + public int getCost() { + return cost; + } + + /** + * Sets the cost of destroying the portal + * + * @param cost

The cost of destroying the portal

+ */ + public void setCost(int cost) { + this.cost = cost; + } + @NotNull @Override public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index f87ed1f..97da60a 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -15,7 +15,8 @@ public abstract class StargateEvent extends Event implements Cancellable { /** * Instantiates a new stargate event - * @param event

UNUSED

+ * + * @param event

UNUSED

* @param portal

The portal involved in this stargate event

*/ StargateEvent(String event, Portal portal) { @@ -25,6 +26,7 @@ public abstract class StargateEvent extends Event implements Cancellable { /** * Gets the portal involved in this stargate event + * * @return

The portal involved in this stargate event

*/ public Portal getPortal() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index 360bb98..d337b24 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -10,15 +10,15 @@ import org.jetbrains.annotations.NotNull; */ public class StargateOpenEvent extends StargatePlayerEvent { - private boolean force; - private static final HandlerList handlers = new HandlerList(); + private boolean force; /** * Instantiates a new stargate open event + * * @param player

The player opening the stargate

* @param portal

The portal opened

- * @param force

Whether to force the portal open

+ * @param force

Whether to force the portal open

*/ public StargateOpenEvent(Player player, Portal portal, boolean force) { super("StargateOpenEvent", portal, player); @@ -26,8 +26,18 @@ public class StargateOpenEvent extends StargatePlayerEvent { this.force = force; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + /** * Gets whether the portal should be forced open + * * @return

Whether the portal should be forced open

*/ public boolean getForce() { @@ -36,20 +46,13 @@ public class StargateOpenEvent extends StargatePlayerEvent { /** * Sets whether the portal should be forced open + * * @param force

Whether the portal should be forced open

*/ public void setForce(boolean force) { this.force = force; } - /** - * Gets a handler-list containing all event handlers - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java index 6e7191a..9f80447 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java @@ -12,17 +12,17 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class StargatePortalEvent extends StargatePlayerEvent { + private static final HandlerList handlers = new HandlerList(); private final Portal destination; private Location exit; - private static final HandlerList handlers = new HandlerList(); - /** * Instantiates a new stargate portal event - * @param player

The player teleporting

- * @param portal

The portal the player entered from

+ * + * @param player

The player teleporting

+ * @param portal

The portal the player entered from

* @param destination

The destination the player should exit from

- * @param exit

The exit location of the destination portal the user will be teleported to

+ * @param exit

The exit location of the destination portal the user will be teleported to

*/ public StargatePortalEvent(Player player, Portal portal, Portal destination, Location exit) { super("StargatePortalEvent", portal, player); @@ -31,6 +31,15 @@ public class StargatePortalEvent extends StargatePlayerEvent { this.exit = exit; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + /** * Return the destination gate * @@ -56,14 +65,6 @@ public class StargatePortalEvent extends StargatePlayerEvent { this.exit = loc; } - /** - * Gets a handler-list containing all event handlers - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 5b58fd4..2f8f41e 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -57,7 +57,11 @@ public class BlockEventListener implements Listener { Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); } - // Switch to HIGHEST priority so as to come after block protection plugins (Hopefully) + /** + * Detects block breaking to detect if the user is destroying a gate + * + * @param event

The triggered event

+ */ @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent event) { if (event.isCancelled()) { @@ -113,14 +117,15 @@ public class BlockEventListener implements Listener { /** * Handles economy payment for breaking the portal + * * @param destroyEvent

The destroy event

- * @param player

The player which triggered the event

- * @param portal

The broken portal

- * @param event

The break event

+ * @param player

The player which triggered the event

+ * @param portal

The broken portal

+ * @param event

The break event

* @return

True if the payment was successful. False if the event was cancelled

*/ private boolean handleEconomyPayment(StargateDestroyEvent destroyEvent, Player player, Portal portal, - BlockBreakEvent event) { + BlockBreakEvent event) { int cost = destroyEvent.getCost(); if (cost != 0) { if (!Stargate.chargePlayer(player, cost)) { @@ -140,6 +145,7 @@ public class BlockEventListener implements Listener { /** * Prevents any block physics events which may damage parts of the portal + * * @param event

The event to check and possibly cancel

*/ @EventHandler diff --git a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java index 69f5105..700fda4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java @@ -1,16 +1,11 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.BungeeHelper; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - /** * This listener teleports a user if a valid message is received from BungeeCord * @@ -20,65 +15,27 @@ import java.io.IOException; */ public class BungeeCordListener implements PluginMessageListener { + /** + * Receive a plugin message + * + * @param channel

The channel the message was received on

+ * @param unused

Unused.

+ * @param message

The message received from the plugin

+ */ @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, @NotNull byte[] message) { + //Ignore plugin messages if bungee support is not enabled or some other plugin message is received if (!Stargate.enableBungee || !channel.equals("BungeeCord")) { return; } - String receivedMessage = readPluginMessage(message); + String receivedMessage = BungeeHelper.readPluginMessage(message); if (receivedMessage == null) { return; } - String[] messageParts = receivedMessage.split("#@#"); - - String playerName = messageParts[0]; - String destination = messageParts[1]; - - // Check if the player is online, if so, teleport, otherwise, queue - Player player = Stargate.server.getPlayer(playerName); - if (player == null) { - Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); - } else { - Portal destinationPortal = PortalHandler.getBungeeGate(destination); - // Specified an invalid gate. For now we'll just let them connect at their current location - if (destinationPortal == null) { - Stargate.log.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); - return; - } - destinationPortal.teleport(player, destinationPortal, null); - } + BungeeHelper.handleTeleportMessage(receivedMessage); } - /** - * Reads a plugin message byte array to a string - * @param message

The byte array to read

- * @return

The message contained in the byte array

- */ - private String readPluginMessage(byte[] message) { - // Get data from message - String inChannel; - byte[] data; - try { - DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(message)); - inChannel = dataInputStream.readUTF(); - short dataLength = dataInputStream.readShort(); - data = new byte[dataLength]; - dataInputStream.readFully(data); - } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); - ex.printStackTrace(); - return null; - } - - // Verify that it's an SGBungee packet - if (!inChannel.equals("SGBungee")) { - return null; - } - - // Data should be player name, and destination gate name - return new String(data); - } } diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index f8272e5..dfbbde3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -18,6 +18,7 @@ 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.LOWEST) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 511a7f9..79d79a2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -1,10 +1,12 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.BlockLocation; +import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.Stargate; import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.block.Block; @@ -21,9 +23,6 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; 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 { @@ -31,6 +30,11 @@ public class PlayerEventsListener implements Listener { private static long eventTime; private static PlayerInteractEvent previousEvent; + /** + * This event handler handles detection of any player teleporting through a bungee gate + * + * @param event

The event to check for a teleporting player

+ */ @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { if (!Stargate.enableBungee) { @@ -51,9 +55,18 @@ public class PlayerEventsListener implements Listener { portal.teleport(player, portal, null); } + /** + * This event handler handles some special teleportation events + * + *

This event cancels nether portal and end gateway teleportation if the user teleported from a stargate + * entrance. This prevents the user from just teleporting to the nether with the default portal design. + * Additionally, this event teleports any vehicles not detected by the VehicleMove event together with the player.

+ * + * @param event

The event to check and possibly cancel

+ */ @EventHandler public void onPlayerTeleport(PlayerTeleportEvent event) { - // cancel portal and endgateway teleportation if it's from a stargate entrance + // cancel portal and end gateway 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 == @@ -76,101 +89,39 @@ public class PlayerEventsListener implements Listener { } } + /** + * This event handler detects if a player moves into a portal + * + * @param event

Player move event which was triggered

+ */ @EventHandler public void onPlayerMove(PlayerMoveEvent event) { - if (event.isCancelled()) return; + 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()) { + //Check to see if the player moved to another block + BlockLocation fromLocation = (BlockLocation) event.getFrom(); + BlockLocation toLocation = (BlockLocation) event.getTo(); + if (toLocation == null || fromLocation.equals(toLocation)) { return; } Player player = event.getPlayer(); - Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); - // No portal or not open - if (entrancePortal == null || !entrancePortal.isOpen()) { - return; - } - - // Not open for this player - if (!entrancePortal.isOpenFor(player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - entrancePortal.teleport(player, entrancePortal, event); - return; - } - + Portal entrancePortal = PortalHandler.getByEntrance(toLocation); Portal destination = entrancePortal.getDestination(player); - if (!entrancePortal.isBungee() && destination == null) { - return; - } - if (!Stargate.canAccessPortal(player, entrancePortal, destination)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - entrancePortal.teleport(player, entrancePortal, event); - entrancePortal.close(false); + //Decide if the anything stops the player from teleport + if (!playerCanTeleport(entrancePortal, destination, player, event)) { return; } - int cost = Stargate.getUseCost(player, entrancePortal, destination); - if (cost > 0) { - if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { - return; - } - } - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - // BungeeCord Support - if (entrancePortal.isBungee()) { - if (!Stargate.enableBungee) { - player.sendMessage(Stargate.getString("bungeeDisabled")); - entrancePortal.close(false); - return; - } - - // Teleport the player back to this gate, for sanity's sake - 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() + "#@#" + 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(entrancePortal.getNetwork()); // Server - msgData.writeUTF("SGBungee"); // Channel - msgData.writeShort(msg.length()); // Data Length - msgData.writeBytes(msg); // Data - player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray()); - } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); - ex.printStackTrace(); - return; - } - - // Connect player to new server - try { - ByteArrayOutputStream bao = new ByteArrayOutputStream(); - DataOutputStream msgData = new DataOutputStream(bao); - msgData.writeUTF("Connect"); - msgData.writeUTF(entrancePortal.getNetwork()); - - player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray()); - bao.reset(); - } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); - ex.printStackTrace(); - return; - } - - // Close portal if required (Should never be) - entrancePortal.close(false); + //Decide if the user should be teleported to another bungee server + if (entrancePortal.isBungee() && bungeeTeleport(player, entrancePortal, event)) { return; } - destination.teleport(player, entrancePortal, event); entrancePortal.close(false); } @@ -284,4 +235,83 @@ public class PlayerEventsListener implements Listener { } } + /** + * Teleports a player to a bungee gate + * + * @param player

The player to teleport

+ * @param entrancePortal

The gate the player is entering from

+ * @param event

The event causing the teleportation

+ * @return

True if the teleportation was successful

+ */ + private boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { + //Check if bungee is actually enabled + if (!Stargate.enableBungee) { + player.sendMessage(Stargate.getString("bungeeDisabled")); + entrancePortal.close(false); + return false; + } + + //Teleport the player back to this gate, for sanity's sake + entrancePortal.teleport(player, entrancePortal, event); + + //Send the SGBungee packet first, it will be queued by BC if required + if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { + return false; + } + + // Connect player to new server + if (!BungeeHelper.changeServer(player, entrancePortal)) { + return false; + } + + // Close portal if required (Should never be) + entrancePortal.close(false); + return true; + } + + /** + * Decide of the player can teleport through a portal + * + * @param entrancePortal

The portal the player is entering from

+ * @param destination

The destination of the portal the player is inside

+ * @param player

The player wanting to teleport

+ * @param event

The move event causing the teleportation

+ * @return

True if the player can teleport. False otherwise

+ */ + private boolean playerCanTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) { + // No portal or not open + if (entrancePortal == null || !entrancePortal.isOpen()) { + return false; + } + + // Not open for this player + if (!entrancePortal.isOpenFor(player)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + entrancePortal.teleport(player, entrancePortal, event); + return false; + } + + //No destination + if (!entrancePortal.isBungee() && destination == null) { + return false; + } + + //Player cannot access portal + if (!Stargate.canAccessPortal(player, entrancePortal, destination)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + entrancePortal.teleport(player, entrancePortal, event); + entrancePortal.close(false); + return false; + } + + //Player cannot pay for teleportation + int cost = Stargate.getUseCost(player, entrancePortal, destination); + if (cost > 0) { + if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { + return false; + } + } + return true; + } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 95114c3..5165acc 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -16,30 +16,6 @@ import java.util.List; @SuppressWarnings("unused") public class VehicleEventListener implements Listener { - /** - * Check for a vehicle moving through a portal - * @param event

The triggered move event

- */ - @EventHandler - public void onVehicleMove(VehicleMoveEvent event) { - if (!Stargate.handleVehicles) { - return; - } - List passengers = event.getVehicle().getPassengers(); - Vehicle vehicle = event.getVehicle(); - - Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); - - //Return if the portal cannot be teleported through - if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { - 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); @@ -47,9 +23,10 @@ public class VehicleEventListener implements Listener { /** * Teleports a vehicle through a stargate - * @param passengers

The passengers inside the vehicle

+ * + * @param passengers

The passengers inside the vehicle

* @param entrancePortal

The portal the vehicle is entering

- * @param vehicle

The vehicle passing through

+ * @param vehicle

The vehicle passing through

*/ public static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { teleportVehicle(passengers, entrancePortal, vehicle, false); @@ -57,10 +34,11 @@ public class VehicleEventListener implements Listener { /** * Teleports a vehicle through a stargate - * @param passengers

The passengers inside the vehicle

+ * + * @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

+ * @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) { @@ -79,9 +57,10 @@ public class VehicleEventListener implements Listener { /** * 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

+ * @param vehicle

The vehicle to teleport

+ * @param passengers

Any entities sitting in the minecart

*/ private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers, boolean skipOpenCheck) { @@ -116,4 +95,29 @@ public class VehicleEventListener implements Listener { entrancePortal.close(false); } + /** + * Check for a vehicle moving through a portal + * + * @param event

The triggered move event

+ */ + @EventHandler + public void onVehicleMove(VehicleMoveEvent event) { + if (!Stargate.handleVehicles) { + return; + } + List passengers = event.getVehicle().getPassengers(); + Vehicle vehicle = event.getVehicle(); + + Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); + + //Return if the portal cannot be teleported through + if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { + 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); + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java new file mode 100644 index 0000000..0f2d4b7 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -0,0 +1,133 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.Stargate; +import org.bukkit.entity.Player; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * This class contains helpful functions to help with sending and receiving BungeeCord plugin messages + */ +public final class BungeeHelper { + + private final static String bungeeSubChannel = "SGBungee"; + private final static String bungeeChannel = "BungeeCord"; + private final static String teleportMessageDelimiter = "#@#"; + + /** + * Sends a plugin message to BungeeCord allowing the target server to catch it + * + * @param player

The player teleporting

+ * @param entrancePortal

The portal the player is teleporting from

+ * @return

True if the message was successfully sent

+ */ + public static boolean sendTeleportationMessage(Player player, Portal entrancePortal) { + try { + // Build the message, format is #@# + String message = player.getName() + teleportMessageDelimiter + entrancePortal.getDestinationName(); + // Build the message data, sent over the SGBungee BungeeCord channel + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + dataOutputStream.writeUTF("Forward"); + dataOutputStream.writeUTF(entrancePortal.getNetwork()); // Server + //Specify SGBungee channel/tag + dataOutputStream.writeUTF(bungeeSubChannel); + //Length of the message + dataOutputStream.writeShort(message.length()); + //The data to send + dataOutputStream.writeBytes(message); + player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); + } catch (IOException ex) { + Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); + ex.printStackTrace(); + return false; + } + return true; + } + + /** + * Sends the bungee message necessary to change the server + * + * @param player

The player to teleport

+ * @param entrancePortal

The bungee portal the player teleports from

+ * @return

True if able to send the plugin message

+ */ + public static boolean changeServer(Player player, Portal entrancePortal) { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + dataOutputStream.writeUTF("Connect"); + dataOutputStream.writeUTF(entrancePortal.getNetwork()); + + player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); + byteArrayOutputStream.reset(); + } catch (IOException ex) { + Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); + ex.printStackTrace(); + return false; + } + return true; + } + + /** + * Reads a plugin message byte array to a string if it's sent from another stargate plugin + * + * @param message

The byte array to read

+ * @return

The message contained in the byte array or null on failure

+ */ + public static String readPluginMessage(byte[] message) { + // Get data from message + byte[] data; + try { + DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(message)); + String subChannel = dataInputStream.readUTF(); + //Only listen for the SGBungee channel + if (!subChannel.equals(bungeeSubChannel)) { + return null; + } + short dataLength = dataInputStream.readShort(); + data = new byte[dataLength]; + dataInputStream.readFully(data); + } catch (IOException ex) { + Stargate.log.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); + ex.printStackTrace(); + return null; + } + + // Data should be player name, and destination gate name + return new String(data); + } + + /** + * Handles the receival of a teleport message + * + * @param receivedMessage

The received message

+ */ + public static void handleTeleportMessage(String receivedMessage) { + String[] messageParts = receivedMessage.split(teleportMessageDelimiter); + + String playerName = messageParts[0]; + String destination = messageParts[1]; + + // Check if the player is online, if so, teleport, otherwise, queue + Player player = Stargate.server.getPlayer(playerName); + if (player == null) { + Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); + } else { + Portal destinationPortal = PortalHandler.getBungeeGate(destination); + // Specified an invalid gate. For now we'll just let them connect at their current location + if (destinationPortal == null) { + Stargate.log.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); + return; + } + destinationPortal.teleport(player, destinationPortal, null); + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 59ed896..238be40 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -9,9 +9,10 @@ public class EconomyHelper { /** * Tries to make the given user pay the teleport fee + * * @param entrancePortal

The portal the player is entering

- * @param player

The player wishing to teleport

- * @param cost

The cost of teleportation

+ * @param player

The player wishing to teleport

+ * @param cost

The cost of teleportation

* @return

True if payment was successful

*/ public static boolean payTeleportFee(Portal entrancePortal, Player player, int cost) { @@ -52,9 +53,10 @@ public class EconomyHelper { /** * Sends a message to the gate owner telling him/her how much he/she earned from a player using his/her gate - * @param portalName

The name of the used portal

+ * + * @param portalName

The name of the used portal

* @param portalOwner

The owner of the portal

- * @param earnings

The amount the owner earned

+ * @param earnings

The amount the owner earned

*/ public static void sendObtainMessage(String portalName, Player portalOwner, int earnings) { String obtainedMsg = Stargate.getString("ecoObtain"); @@ -64,9 +66,10 @@ public class EconomyHelper { /** * Sends a message telling the user how much they paid for interacting with a portal + * * @param portalName

The name of the portal interacted with

- * @param player

The interacting player

- * @param cost

The cost of the interaction

+ * @param player

The interacting player

+ * @param cost

The cost of the interaction

*/ public static void sendDeductMessage(String portalName, Player player, int cost) { String deductMsg = Stargate.getString("ecoDeduct"); @@ -76,9 +79,10 @@ public class EconomyHelper { /** * Sends a message telling the user they don't have enough funds to do a portal interaction + * * @param portalName

The name of the portal interacted with

- * @param player

The interacting player

- * @param cost

The cost of the interaction

+ * @param player

The interacting player

+ * @param cost

The cost of the interaction

*/ public static void sendInsufficientFundsMessage(String portalName, Player player, int cost) { String inFundMsg = Stargate.getString("ecoInFunds"); @@ -88,9 +92,10 @@ public class EconomyHelper { /** * Sends a message telling the user how much they are refunded for breaking their portal + * * @param portalName

The name of the broken portal

- * @param player

The player breaking the portal

- * @param cost

The amount the user has to pay for destroying the portal. (expects a negative value)

+ * @param player

The player breaking the portal

+ * @param cost

The amount the user has to pay for destroying the portal. (expects a negative value)

*/ public static void sendRefundMessage(String portalName, Player player, int cost) { String refundMsg = Stargate.getString("ecoRefund"); @@ -100,9 +105,10 @@ public class EconomyHelper { /** * Replaces the cost and portal variables in a string - * @param message

The message to replace variables in

+ * + * @param message

The message to replace variables in

* @param portalName

The name of the relevant portal

- * @param cost

The cost for a given interaction

+ * @param cost

The cost for a given interaction

* @return

The same string with cost and portal variables replaced

*/ private static String replaceVars(String message, String portalName, int cost) { diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 83d6e5a..76e4d27 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -10,6 +10,7 @@ public final class MaterialHelper { /** * Checks whether the given material is a dead or alive wall coral + * * @param material

The material to check

* @return

True if the material is a wall coral

*/ @@ -24,6 +25,7 @@ public final class MaterialHelper { /** * Checks whether the given material can be used as a button + * * @param material

The material to check

* @return

True if the material can be used as a button

*/ From 889a9d2cbc650036e02b9671cd13b1a228fc2e67 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 20 Feb 2021 14:42:41 +0100 Subject: [PATCH 045/378] Finishes commenting and refactoring the player events listener --- .../listener/PlayerEventsListener.java | 225 ++++++++++-------- 1 file changed, 132 insertions(+), 93 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 79d79a2..27da64a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -25,6 +25,9 @@ import org.bukkit.event.player.PlayerTeleportEvent; import java.util.Objects; +/** + * This listener listens to any player-related events related to stargates + */ public class PlayerEventsListener implements Listener { private static long eventTime; @@ -92,7 +95,7 @@ public class PlayerEventsListener implements Listener { /** * This event handler detects if a player moves into a portal * - * @param event

Player move event which was triggered

+ * @param event

The player move event which was triggered

*/ @EventHandler public void onPlayerMove(PlayerMoveEvent event) { @@ -126,6 +129,11 @@ public class PlayerEventsListener implements Listener { entrancePortal.close(false); } + /** + * This event handler detects if a player clicks a button or a sign + * + * @param event

The player interact event which was triggered

+ */ @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { Player player = event.getPlayer(); @@ -135,106 +143,139 @@ public class PlayerEventsListener implements Listener { return; } - // Right click if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (block.getBlockData() instanceof WallSign) { - Portal portal = PortalHandler.getByBlock(block); - if (portal == null) { - return; - } - // Cancel item use - event.setUseItemInHand(Event.Result.DENY); - event.setUseInteractedBlock(Event.Result.DENY); + handleRightClickBlock(event, player, block); + } else if (event.getAction() == Action.LEFT_CLICK_BLOCK && block.getBlockData() instanceof WallSign) { + //Handle left click of a wall sign + handleSignClick(event, player, block, true); + } + } - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - if ((!portal.isOpen()) && (!portal.isFixed())) { - portal.cycleDestination(player); - } - return; - } - - // Implement right-click to toggle a stargate, gets around spawn protection problem. - if (MaterialHelper.isButtonCompatible(block.getType())) { - - if (MaterialHelper.isWallCoral(block.getType())) { - if (previousEvent != null && - event.getPlayer() == previousEvent.getPlayer() && eventTime + 10 > System.currentTimeMillis()) { - previousEvent = null; - eventTime = 0; - return; - } - previousEvent = event; - eventTime = System.currentTimeMillis(); - } - - Portal portal = PortalHandler.getByBlock(block); - if (portal == null) { - return; - } - - // Cancel item use - event.setUseItemInHand(Event.Result.DENY); - event.setUseInteractedBlock(Event.Result.DENY); - - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - Stargate.openPortal(player, portal); - if (portal.isOpenFor(player)) { - event.setUseInteractedBlock(Event.Result.ALLOW); - } - } + /** + * This method handles left- or right-clicking of a sign + * + * @param event

The event causing the click

+ * @param player

The player clicking the sign

+ * @param block

The block that was clicked

+ * @param leftClick

Whether the player performed a left click as opposed to a right click

+ */ + private void handleSignClick(PlayerInteractEvent event, Player player, Block block, boolean leftClick) { + Portal portal = PortalHandler.getByBlock(block); + if (portal == null) { return; } - // Left click - if (event.getAction() == Action.LEFT_CLICK_BLOCK) { - // Check if we're scrolling a sign - if (block.getBlockData() instanceof WallSign) { - Portal portal = PortalHandler.getByBlock(block); - if (portal == null) { - return; - } + event.setUseInteractedBlock(Event.Result.DENY); + if (leftClick) { + //Cancel event in creative mode to prevent breaking the sign + if (player.getGameMode().equals(GameMode.CREATIVE)) { + event.setCancelled(true); + } + } else { + //Prevent usage of item in the player's hand (placing block and such) + event.setUseItemInHand(Event.Result.DENY); + } - event.setUseInteractedBlock(Event.Result.DENY); - // Only cancel event in creative mode - if (player.getGameMode().equals(GameMode.CREATIVE)) { - event.setCancelled(true); - } + //Check if the user can use the portal + if (cannotAccessPortal(player, portal)) { + return; + } - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } - - if (!Stargate.canAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - if ((!portal.isOpen()) && (!portal.isFixed())) { - portal.cycleDestination(player, -1); - } + //Cycle portal destination + if ((!portal.isOpen()) && (!portal.isFixed())) { + if (leftClick) { + portal.cycleDestination(player, -1); + } else { + portal.cycleDestination(player); } } } + /** + * Check if a player should be denied from accessing (using) a portal + * + * @param player

The player trying to access the portal

+ * @param portal

The portal the player is trying to use

+ * @return

True if the player should be denied

+ */ + private boolean cannotAccessPortal(Player player, Portal portal) { + boolean deny = false; + if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { + deny = true; + } + + if (!Stargate.canAccessPortal(player, portal, deny)) { + Stargate.sendMessage(player, Stargate.getString("denyMsg")); + return true; + } + return false; + } + + /** + * This method handles right clicking of a sign or button belonging to a stargate + * + * @param event

The event triggering the right-click

+ * @param player

The player doing the right-click

+ * @param block

The block the player clicked

+ */ + private void handleRightClickBlock(PlayerInteractEvent event, Player player, Block block) { + if (block.getBlockData() instanceof WallSign) { + handleSignClick(event, player, block, false); + return; + } + + // Implement right-click to toggle a stargate, gets around spawn protection problem. + if (MaterialHelper.isButtonCompatible(block.getType())) { + //Prevent a double click caused by a Spigot bug + if (clickIsBug(event, block)) { + return; + } + + Portal portal = PortalHandler.getByBlock(block); + if (portal == null) { + return; + } + + // Cancel item use + event.setUseItemInHand(Event.Result.DENY); + event.setUseInteractedBlock(Event.Result.DENY); + + //Check if the user can use the portal + if (cannotAccessPortal(player, portal)) { + return; + } + + Stargate.openPortal(player, portal); + if (portal.isOpenFor(player)) { + event.setUseInteractedBlock(Event.Result.ALLOW); + } + } + } + + /** + * This function decides if a right click of a coral is caused by a Spigot bug + * + *

The Spigot bug currently makes every right click of a coral trigger twice, causing the portal to close + * immediately. This fix should detect the bug without breaking wall coral buttons once the bug is fixed.

+ * + * @param event

The event causing the right click

+ * @param block

The block to check

+ * @return

True if the click is a bug and should be cancelled

+ */ + private boolean clickIsBug(PlayerInteractEvent event, Block block) { + if (MaterialHelper.isWallCoral(block.getType())) { + if (previousEvent != null && + event.getPlayer() == previousEvent.getPlayer() && eventTime + 15 > System.currentTimeMillis()) { + previousEvent = null; + eventTime = 0; + return true; + } + previousEvent = event; + eventTime = System.currentTimeMillis(); + } + return false; + } + /** * Teleports a player to a bungee gate * @@ -307,9 +348,7 @@ public class PlayerEventsListener implements Listener { //Player cannot pay for teleportation int cost = Stargate.getUseCost(player, entrancePortal, destination); if (cost > 0) { - if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { - return false; - } + return EconomyHelper.payTeleportFee(entrancePortal, player, cost); } return true; } From 1da0f4eddc85f1756900862d716ddd9d5ae45e2c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 20 Feb 2021 14:55:23 +0100 Subject: [PATCH 046/378] Adds comments to the plugin event listener --- .../listener/PlayerEventsListener.java | 1 + .../listener/PluginEventListener.java | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 27da64a..656dca4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -28,6 +28,7 @@ import java.util.Objects; /** * This listener listens to any player-related events related to stargates */ +@SuppressWarnings("unused") public class PlayerEventsListener implements Listener { private static long eventTime; diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index dbf96e5..85775c6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -7,26 +7,47 @@ import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginEnableEvent; +/** + * This listener listens for any plugins being enabled or disabled to catch the loading of vault + */ +@SuppressWarnings("unused") public class PluginEventListener implements Listener { + private final Stargate stargate; + /** + * Instantiates a new plugin event listener + * + * @param stargate

A reference to the stargate plugin to

+ */ public PluginEventListener(Stargate stargate) { this.stargate = stargate; } + /** + * This event listens for and announces that the vault plugin was detected and enabled + * + *

Each time this event is called, the economy handler will try to enable vault

+ * @param ignored

The actual event called. This is currently not used

+ */ @EventHandler - public void onPluginEnable(PluginEnableEvent event) { + public void onPluginEnable(PluginEnableEvent ignored) { if (EconomyHandler.setupEconomy(stargate.getServer().getPluginManager())) { String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); - Stargate.log.info(Stargate.getString("prefix") + + stargate.getLogger().info(Stargate.getString("prefix") + Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } } + /** + * This event listens for the vault plugin being disabled and notifies the console + * + * @param event

The event caused by disabling a plugin

+ */ @EventHandler public void onPluginDisable(PluginDisableEvent event) { if (event.getPlugin().equals(EconomyHandler.vault)) { - Stargate.log.info(Stargate.getString("prefix") + "Vault plugin lost."); + stargate.getLogger().info(Stargate.getString("prefix") + "Vault plugin lost."); } } } From 1d642bfcf24044168f0bf075821b8f6e338bbdf7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 20 Feb 2021 14:59:59 +0100 Subject: [PATCH 047/378] Adds missing comments to the vehicle event listener --- .../stargate/listener/VehicleEventListener.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 5165acc..955b859 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -13,9 +13,19 @@ import org.bukkit.event.vehicle.VehicleMoveEvent; import java.util.List; +/** + * This listener listens for the vehicle move event to teleport vehicles through portals + */ @SuppressWarnings("unused") public class VehicleEventListener implements Listener { + /** + * If the player teleported, but its vehicle was left behind, make the vehicle teleport to the player + * + * @param vehicle

The vehicle to teleport

+ * @param destinationPortal

The portal the player teleported to

+ * @param player

The player who teleported

+ */ public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player) { destinationPortal.teleport(vehicle); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6); From a475e8d8b1c790104e6032bb4bb8ffe9a69df579 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 20 Feb 2021 16:21:18 +0100 Subject: [PATCH 048/378] Adds missing comments to the world event listener and adds faster gate unloading Replaces the clear all + load all with a method which just removes all relevant portals directly. This should be faster, especially with many gates and worlds --- .../net/knarcraft/stargate/PortalHandler.java | 40 ++++++++++++++++++- .../stargate/listener/WorldEventListener.java | 33 +++++++++------ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/PortalHandler.java b/src/main/java/net/knarcraft/stargate/PortalHandler.java index 83dc1d8..a45f8c2 100644 --- a/src/main/java/net/knarcraft/stargate/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/PortalHandler.java @@ -684,7 +684,7 @@ public class PortalHandler { } /** - * Clears all loaded gates and gate data + * Clears all loaded gates and gate data from all worlds */ public static void clearGates() { lookupBlocks.clear(); @@ -695,6 +695,44 @@ public class PortalHandler { allPortalsNet.clear(); } + /** + * Clears all gates loaded in a given world + * + * @param world

The world containing the portals to clear

+ */ + public static void clearGates(World world) { + //This is necessary + List portalsToRemove = new ArrayList<>(); + allPortals.forEach((portal) -> { + if (portal.getWorld().equals(world)) { + portalsToRemove.add(portal); + } + }); + + clearGates(portalsToRemove); + } + + /** + * Clears a given list of portals from all relevant variables + * + * @param portalsToRemove

A list of portals to remove

+ */ + private static void clearGates(List portalsToRemove) { + List portalNames = new ArrayList<>(); + portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); + lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); + lookupNamesNet.keySet().forEach((network) -> lookupNamesNet.get(network).keySet().removeIf((key) -> + portalsToRemove.contains(lookupNamesNet.get(network).get(key)))); + //Remove any networks with no portals + lookupNamesNet.keySet().removeIf((key) -> lookupNamesNet.get(key).isEmpty()); + lookupEntrances.keySet().removeIf((key) -> portalsToRemove.contains(lookupEntrances.get(key))); + lookupControls.keySet().removeIf((key) -> portalsToRemove.contains(lookupControls.get(key))); + allPortals.removeIf(portalsToRemove::contains); + allPortalsNet.keySet().forEach((network) -> allPortalsNet.get(network).removeIf(portalNames::contains)); + //Remove any networks with no portals + allPortalsNet.keySet().removeIf((network) -> allPortalsNet.get(network).isEmpty()); + } + /** * Loads all gates for the given world * diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 9609b1a..5c0e056 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -8,28 +8,37 @@ import org.bukkit.event.Listener; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; +/** + * This listener listens for the loading and unloading of worlds to load and unload stargates + */ +@SuppressWarnings("unused") public class WorldEventListener implements Listener { + + /** + * This listener listens for the loading of a world and loads all all gates from the world if not already loaded + * + * @param event

The triggered world load event

+ */ @EventHandler public void onWorldLoad(WorldLoadEvent event) { - if (!Stargate.managedWorlds.contains(event.getWorld().getName()) - && PortalHandler.loadAllGates(event.getWorld())) { + if (!Stargate.managedWorlds.contains(event.getWorld().getName()) && + PortalHandler.loadAllGates(event.getWorld())) { Stargate.managedWorlds.add(event.getWorld().getName()); } } - // We need to reload all gates on world unload, boo + /** + * This listener listens for the unloading of a world + * + * @param event

The triggered world unload event

+ */ @EventHandler public void onWorldUnload(WorldUnloadEvent event) { Stargate.debug("onWorldUnload", "Reloading all Stargates"); - World w = event.getWorld(); - if (Stargate.managedWorlds.contains(w.getName())) { - Stargate.managedWorlds.remove(w.getName()); - PortalHandler.clearGates(); - for (World world : Stargate.server.getWorlds()) { - if (Stargate.managedWorlds.contains(world.getName())) { - PortalHandler.loadAllGates(world); - } - } + World world = event.getWorld(); + if (Stargate.managedWorlds.contains(world.getName())) { + Stargate.managedWorlds.remove(world.getName()); + PortalHandler.clearGates(world); } } } From c422cb9ea966d66f17d31dd89c7f4cd7e8c52b6a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 15:49:44 +0100 Subject: [PATCH 049/378] Overrides toString and equals methods of the relative block vector to make it testable --- .../knarcraft/stargate/RelativeBlockVector.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index 3160361..eab9f91 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -54,4 +54,19 @@ public class RelativeBlockVector { return distance; } + @Override + public String toString() { + return String.format("right = %d, depth = %d, distance = %d", right, depth, distance); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof RelativeBlockVector)) { + return false; + } + RelativeBlockVector otherVector = (RelativeBlockVector) other; + return this.right == otherVector.right && this.depth == otherVector.depth && + this.distance == otherVector.distance; + } + } From fb70b8bc759aa089267236e606fd830039c484c1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 17:01:47 +0100 Subject: [PATCH 050/378] Splits Gate into Gate, GateLayout and GateHandler, and creates a new portal package with portal related classes --- .../net/knarcraft/stargate/BlockLocation.java | 9 +- .../stargate/RelativeBlockVector.java | 13 +- .../java/net/knarcraft/stargate/Stargate.java | 15 +- .../stargate/event/StargateAccessEvent.java | 2 +- .../stargate/event/StargateActivateEvent.java | 2 +- .../stargate/event/StargateCloseEvent.java | 2 +- .../stargate/event/StargateCreateEvent.java | 2 +- .../event/StargateDeactivateEvent.java | 2 +- .../stargate/event/StargateDestroyEvent.java | 2 +- .../stargate/event/StargateEvent.java | 2 +- .../stargate/event/StargateOpenEvent.java | 2 +- .../stargate/event/StargatePlayerEvent.java | 2 +- .../stargate/event/StargatePortalEvent.java | 2 +- .../stargate/listener/BlockEventListener.java | 4 +- .../listener/EntityEventListener.java | 4 +- .../listener/PlayerEventsListener.java | 4 +- .../listener/VehicleEventListener.java | 4 +- .../stargate/listener/WorldEventListener.java | 2 +- .../net/knarcraft/stargate/portal/Gate.java | 300 +++++++++++++++++ .../{Gate.java => portal/GateHandler.java} | 313 +++--------------- .../knarcraft/stargate/portal/GateLayout.java | 202 +++++++++++ .../stargate/{ => portal}/Portal.java | 23 +- .../stargate/{ => portal}/PortalHandler.java | 26 +- .../stargate/{ => portal}/PortalOption.java | 2 +- .../stargate/thread/StarGateThread.java | 2 +- .../stargate/utility/BungeeHelper.java | 8 +- .../stargate/utility/EconomyHelper.java | 8 +- .../stargate/utility/MaterialHelper.java | 4 + .../stargate/RelativeBlockVectorTest.java | 15 + .../stargate/portal/GateLayoutTest.java | 95 ++++++ 30 files changed, 749 insertions(+), 324 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/Gate.java rename src/main/java/net/knarcraft/stargate/{Gate.java => portal/GateHandler.java} (51%) create mode 100644 src/main/java/net/knarcraft/stargate/portal/GateLayout.java rename src/main/java/net/knarcraft/stargate/{ => portal}/Portal.java (97%) rename src/main/java/net/knarcraft/stargate/{ => portal}/PortalHandler.java (97%) rename src/main/java/net/knarcraft/stargate/{ => portal}/PortalOption.java (98%) create mode 100644 src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index f033b10..639072e 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -202,9 +202,12 @@ public class BlockLocation extends Location { @Override public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } BlockLocation blockLocation = (BlockLocation) obj; diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index eab9f91..8bf2624 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -4,9 +4,9 @@ package net.knarcraft.stargate; * 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.

+ * top-left block of a gate (top-left when looking at the side with the sign). 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 { @@ -56,12 +56,15 @@ public class RelativeBlockVector { @Override public String toString() { - return String.format("right = %d, depth = %d, distance = %d", right, depth, distance); + return String.format("(right = %d, depth = %d, distance = %d)", right, depth, distance); } @Override public boolean equals(Object other) { - if (!(other instanceof RelativeBlockVector)) { + if (other == this) { + return true; + } + if (other == null || this.getClass() != other.getClass()) { return false; } RelativeBlockVector otherVector = (RelativeBlockVector) other; diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 5bd8765..2ef10ed 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -10,6 +10,11 @@ import net.knarcraft.stargate.listener.PlayerEventsListener; import net.knarcraft.stargate.listener.PluginEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; +import net.knarcraft.stargate.portal.Gate; +import net.knarcraft.stargate.portal.GateHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalOption; import net.knarcraft.stargate.thread.BlockPopulatorThread; import net.knarcraft.stargate.thread.StarGateThread; import org.bukkit.Bukkit; @@ -561,8 +566,8 @@ public class Stargate extends JavaPlugin { } } - getServer().getScheduler().scheduleSyncRepeatingTask(this, new StarGateThread(), 0L, 100L); - getServer().getScheduler().scheduleSyncRepeatingTask(this, new BlockPopulatorThread(), 0L, 1L); + getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); + getServer().getScheduler().runTaskTimer(this, new BlockPopulatorThread(), 0L, 100L); this.registerCommands(); } @@ -626,8 +631,8 @@ public class Stargate extends JavaPlugin { } public void loadGates() { - Gate.loadGates(gateFolder); - log.info(Stargate.getString("prefix") + "Loaded " + Gate.getGateCount() + " gate layouts"); + GateHandler.loadGates(gateFolder); + log.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); } public void loadAllPortals() { @@ -688,7 +693,7 @@ public class Stargate extends JavaPlugin { openList.clear(); managedWorlds.clear(); PortalHandler.clearGates(); - Gate.clearGates(); + GateHandler.clearGates(); // Store the old Bungee enabled value boolean oldEnableBungee = enableBungee; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 8925d53..8370b0e 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index ea73802..b169580 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index aacb0d5..8306a92 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java index 6f901cd..a703a3b 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index 4b3e68e..241b6ac 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index 0b66b6d..5032036 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index 97da60a..6584355 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index d337b24..04bf752 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java index 2dcf77b..bc7074d 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; /** diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java index 9f80447..ed13e26 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.event; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 2f8f41e..99ff498 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateDestroyEvent; import net.knarcraft.stargate.utility.EconomyHelper; diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index dfbbde3..9d35ad2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 656dca4..15030f1 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.EconomyHelper; diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 955b859..1888370 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.EconomyHelper; import org.bukkit.entity.Entity; diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 5c0e056..08c248b 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.World; import org.bukkit.event.EventHandler; diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java new file mode 100644 index 0000000..f2fce39 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -0,0 +1,300 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.BlockLocation; +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.Stargate; +import org.bukkit.Material; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; + +/** + * A gate describes the physical structure of a stargate + * + *

While the portal class represents a portal in space, the Gate class represents the physical gate/portal entrance.

+ */ +public class Gate { + + private final String filename; + private final GateLayout layout; + private final HashMap types; + + //Gate materials + private Material portalOpenBlock; + private Material portalClosedBlock; + private Material portalButton; + + // Economy information + private int useCost; + private int createCost; + private int destroyCost; + private boolean toOwner; + + /** + * Instantiates a new gate + * + * @param filename

The name of the gate which equal the name of the file

+ * @param layout

The character layout defined in the gate file

+ * @param types

The block types the different layout characters represent

+ * @param portalOpenBlock

The material to set the non-frame to when the portal is open

+ * @param portalClosedBlock

The material to set the non-frame to when the portal is closed

+ * @param portalButton

The material to use for the portal button

+ * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

+ * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

+ * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

+ * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

+ */ + public Gate(String filename, GateLayout layout, HashMap types, Material portalOpenBlock, + Material portalClosedBlock, Material portalButton, int useCost, int createCost, int destroyCost, + boolean toOwner) { + this.filename = filename; + this.layout = layout; + this.types = types; + this.portalOpenBlock = portalOpenBlock; + this.portalClosedBlock = portalClosedBlock; + this.portalButton = portalButton; + this.useCost = useCost; + this.createCost = createCost; + this.destroyCost = destroyCost; + this.toOwner = toOwner; + } + + /** + * Gets the layout of this gate + * + * @return

The layout of this gate

+ */ + public GateLayout getLayout() { + return layout; + } + + /** + * Gets the material types each layout character represents + * + * @return

The material types each layout character represents

+ */ + public HashMap getTypes() { + return types; + } + + public Material getControlBlock() { + return types.get('-'); + } + + public String getFilename() { + return filename; + } + + public Material getPortalOpenBlock() { + return portalOpenBlock; + } + + public void setPortalOpenBlock(Material type) { + portalOpenBlock = type; + } + + public Material getPortalClosedBlock() { + return portalClosedBlock; + } + + public void setPortalClosedBlock(Material type) { + portalClosedBlock = type; + } + + public Material getPortalButton() { + return portalButton; + } + + public int getUseCost() { + if (useCost < 0) return EconomyHandler.useCost; + return useCost; + } + + public Integer getCreateCost() { + if (createCost < 0) return EconomyHandler.createCost; + return createCost; + } + + public Integer getDestroyCost() { + if (destroyCost < 0) return EconomyHandler.destroyCost; + return destroyCost; + } + + public Boolean getToOwner() { + 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, boolean onCreate) { + HashMap portalTypes = new HashMap<>(types); + Character[][] layout = this.layout.getLayout(); + 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(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) { + if (Stargate.ignoreEntrance) { + continue; + } + + 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 (type != portalClosedBlock && type != portalOpenBlock) { + Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); + return false; + } + } else if (!key.equals(GateHandler.getAnythingCharacter())) { + 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); + return false; + } + } + } + } + + return true; + } + + /** + * Saves this gate to a file + * + *

This method will save the gate to its filename in the given folder.

+ * + * @param gateFolder

The folder to save the gate file in

+ */ + public void save(String gateFolder) { + try { + BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(gateFolder + filename)); + + writeConfig(bufferedWriter, "portal-open", portalOpenBlock.name()); + writeConfig(bufferedWriter, "portal-closed", portalClosedBlock.name()); + writeConfig(bufferedWriter, "button", portalButton.name()); + + //Save the values necessary for economy + saveEconomyValues(bufferedWriter); + + //Store type material type to use for frame blocks + saveFrameBlockTypes(bufferedWriter); + + bufferedWriter.newLine(); + + //Save the layout + layout.save(bufferedWriter); + + bufferedWriter.close(); + } catch (IOException ex) { + Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); + } + } + + /** + * Saves current economy related values using a buffered writer + * + * @param bufferedWriter

The buffered writer to write to

+ * * @throws IOException

If unable to write to the buffered writer

+ */ + private void saveEconomyValues(BufferedWriter bufferedWriter) throws IOException { + if (useCost != -1) { + writeConfig(bufferedWriter, "usecost", useCost); + } + if (createCost != -1) { + writeConfig(bufferedWriter, "createcost", createCost); + } + if (destroyCost != -1) { + writeConfig(bufferedWriter, "destroycost", destroyCost); + } + writeConfig(bufferedWriter, "toowner", toOwner); + } + + /** + * Saves the types of blocks used for the gate frame/border using a buffered writer + * + * @param bufferedWriter

The buffered writer to write to

+ * @throws IOException

If unable to write to the buffered writer

+ */ + private void saveFrameBlockTypes(BufferedWriter bufferedWriter) throws IOException { + for (Map.Entry entry : types.entrySet()) { + Character type = entry.getKey(); + Material value = entry.getValue(); + // Skip control values + if (type.equals(GateHandler.getAnythingCharacter()) || + type.equals(GateHandler.getEntranceCharacter()) || + type.equals(GateHandler.getExitCharacter())) { + continue; + } + + bufferedWriter.append(type); + bufferedWriter.append('='); + if (value != null) { + bufferedWriter.append(value.toString()); + } + bufferedWriter.newLine(); + } + } + + /** + * Writes an integer to a config + * + * @param bufferedWriter

The buffered writer to write the config to

+ * @param key

The config key to save

+ * @param value

The value of the config key

+ * @throws IOException

If unable to write to the buffered writer

+ */ + private void writeConfig(BufferedWriter bufferedWriter, String key, int value) throws IOException { + writeConfig(bufferedWriter, "%s=%d", key, value); + } + + /** + * Writes a boolean to a config + * + * @param bufferedWriter

The buffered writer to write the config to

+ * @param key

The config key to save

+ * @param value

The value of the config key

+ * @throws IOException

If unable to write to the buffered writer

+ */ + private void writeConfig(BufferedWriter bufferedWriter, String key, boolean value) throws IOException { + writeConfig(bufferedWriter, "%s=%b", key, value); + } + + /** + * Writes a string to a config + * + * @param bufferedWriter

The buffered writer to write the config to

+ * @param key

The config key to save

+ * @param value

The value of the config key

+ * @throws IOException

If unable to write to the buffered writer

+ */ + private void writeConfig(BufferedWriter bufferedWriter, String key, String value) throws IOException { + writeConfig(bufferedWriter, "%s=%s", key, value); + } + + /** + * Writes a formatted string to a buffered writer + * + * @param bufferedWriter

The buffered writer to write the formatted string to

+ * @param format

The format to use

+ * @param key

The config key to save

+ * @param value

The config value to save

+ * @throws IOException

If unable to write to the buffered writer

+ */ + private void writeConfig(BufferedWriter bufferedWriter, String format, String key, Object value) throws IOException { + bufferedWriter.append(String.format(format, key, value)); + bufferedWriter.newLine(); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java similarity index 51% rename from src/main/java/net/knarcraft/stargate/Gate.java rename to src/main/java/net/knarcraft/stargate/portal/GateHandler.java index a5db5d8..7c94e9f 100644 --- a/src/main/java/net/knarcraft/stargate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -1,54 +1,56 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.portal; +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; import org.bukkit.block.Block; - -import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Scanner; import java.util.logging.Level; -public class Gate { +public class GateHandler { private static final Character ANYTHING = ' '; private static final Character ENTRANCE = '.'; private static final Character EXIT = '*'; + + private static Material defaultPortalBlockOpen = Material.NETHER_PORTAL; + private static Material defaultPortalBlockClosed = Material.AIR; + private static Material defaultButton = Material.STONE_BUTTON; + private static final HashMap gates = new HashMap<>(); private static final HashMap> controlBlocks = new HashMap<>(); private static final HashSet frameBlocks = new HashSet<>(); - private final String filename; - private final Character[][] layout; - private final HashMap types; - private final HashMap exits = new HashMap<>(); - private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; - private RelativeBlockVector[] border = new RelativeBlockVector[0]; - private RelativeBlockVector[] controls = new RelativeBlockVector[0]; - private RelativeBlockVector exitBlock = null; - private Material portalBlockOpen = Material.NETHER_PORTAL; - private Material portalBlockClosed = Material.AIR; - private Material button = Material.STONE_BUTTON; + private GateHandler() { - // Economy information - private int useCost = -1; - private int createCost = -1; - private int destroyCost = -1; - private boolean toOwner = false; + } - public Gate(String filename, Character[][] layout, HashMap types) { - this.filename = filename; - this.layout = layout; - this.types = types; + /** + * Gets the character used for blocks that are not part of the gate + * + * @return

The character used for blocks that are not part of the gate

+ */ + public static Character getAnythingCharacter() { + return ANYTHING; + } - populateCoordinates(); + /** + * Gets the character used for defining the entrance + * + * @return

The character used for defining the entrance

+ */ + public static Character getEntranceCharacter() { + return ENTRANCE; + } + + public static Character getExitCharacter() { + return EXIT; } public static void registerGate(Gate gate) { @@ -64,17 +66,11 @@ public class Gate { } public static Gate loadGate(File file) { - Scanner scanner = null; - try { - scanner = new Scanner(file); + try (Scanner scanner = new Scanner(file)) { return loadGate(file.getName(), file.getParent(), scanner); } catch (Exception ex) { Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); return null; - } finally { - if (scanner != null) { - scanner.close(); - } } } @@ -144,6 +140,7 @@ public class Gate { Character[][] layout = new Character[design.size()][cols]; + //y = relative line number of layout file for (int y = 0; y < design.size(); y++) { List row = design.get(y); Character[] result = new Character[cols]; @@ -159,22 +156,25 @@ public class Gate { layout[y] = result; } - Gate gate = new Gate(fileName, layout, types); + Material portalOpenBlock = readConfig(config, fileName, "portal-open", defaultPortalBlockOpen); + Material portalClosedBlock = readConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); + Material portalButton = readConfig(config, fileName, "button", defaultButton); + int useCost = readConfig(config, fileName, "usecost", -1); + int createCost = readConfig(config, fileName, "createcost", -1); + int destroyCost = readConfig(config, fileName, "destroycost", -1); + boolean toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); - gate.portalBlockOpen = readConfig(config, fileName, "portal-open", gate.portalBlockOpen); - gate.portalBlockClosed = readConfig(config, fileName, "portal-closed", gate.portalBlockClosed); - gate.button = readConfig(config, fileName, "button", gate.button); - gate.useCost = readConfig(config, fileName, "usecost", -1); - gate.destroyCost = readConfig(config, fileName, "destroycost", -1); - gate.createCost = readConfig(config, fileName, "createcost", -1); - gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); + Gate gate = new Gate(fileName, new GateLayout(layout), types, portalOpenBlock, portalClosedBlock, portalButton, useCost, + createCost, destroyCost, toOwner); - if (gate.getControls().length != 2) { + + + if (gate.getLayout().getControls().length != 2) { Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); return null; } - if (!MaterialHelper.isButtonCompatible(gate.button)) { + if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); return null; } @@ -341,227 +341,4 @@ public class Gate { frameBlocks.clear(); } - private void populateCoordinates() { - List entranceList = new ArrayList<>(); - List borderList = new ArrayList<>(); - List controlList = new ArrayList<>(); - RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; - int[] exitDepths = new int[layout[0].length]; - RelativeBlockVector lastExit = null; - - 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('-')) { - controlList.add(new RelativeBlockVector(x, y, 0)); - } - - if (key.equals(ENTRANCE) || key.equals(EXIT)) { - entranceList.add(new RelativeBlockVector(x, y, 0)); - exitDepths[x] = y; - if (key.equals(EXIT)) { - this.exitBlock = new RelativeBlockVector(x, y, 0); - } - } else if (!key.equals(ANYTHING)) { - borderList.add(new RelativeBlockVector(x, y, 0)); - } - } - } - - for (int x = 0; x < exitDepths.length; x++) { - relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0); - } - - for (int x = relativeExits.length - 1; x >= 0; x--) { - if (relativeExits[x] != null) { - lastExit = relativeExits[x]; - } else { - relativeExits[x] = lastExit; - } - - if (exitDepths[x] > 0) this.exits.put(relativeExits[x], x); - } - - this.entrances = entranceList.toArray(this.entrances); - this.border = borderList.toArray(this.border); - this.controls = controlList.toArray(this.controls); - } - - public void save(String gateFolder) { - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(gateFolder + filename)); - - writeConfig(bw, "portal-open", portalBlockOpen.name()); - writeConfig(bw, "portal-closed", portalBlockClosed.name()); - writeConfig(bw, "button", button.name()); - if (useCost != -1) - writeConfig(bw, "usecost", useCost); - if (createCost != -1) - writeConfig(bw, "createcost", createCost); - if (destroyCost != -1) - writeConfig(bw, "destroycost", destroyCost); - writeConfig(bw, "toowner", toOwner); - - for (Map.Entry entry : types.entrySet()) { - Character type = entry.getKey(); - Material value = entry.getValue(); - // Skip control values - if (type.equals(ANYTHING) || type.equals(ENTRANCE) || type.equals(EXIT)) { - continue; - } - - bw.append(type); - bw.append('='); - if (value != null) { - bw.append(value.toString()); - } - bw.newLine(); - } - - bw.newLine(); - - for (Character[] aLayout : layout) { - for (Character symbol : aLayout) { - bw.append(symbol); - } - bw.newLine(); - } - - bw.close(); - } catch (IOException ex) { - Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); - } - } - - private void writeConfig(BufferedWriter bw, String key, int value) throws IOException { - bw.append(String.format("%s=%d", key, value)); - bw.newLine(); - } - - private void writeConfig(BufferedWriter bw, String key, boolean value) throws IOException { - bw.append(String.format("%s=%b", key, value)); - bw.newLine(); - } - - private void writeConfig(BufferedWriter bw, String key, String value) throws IOException { - bw.append(String.format("%s=%s", key, value)); - bw.newLine(); - } - - public Character[][] getLayout() { - return layout; - } - - public HashMap getTypes() { - return types; - } - - public RelativeBlockVector[] getEntrances() { - return entrances; - } - - public RelativeBlockVector[] getBorder() { - return border; - } - - public RelativeBlockVector[] getControls() { - return controls; - } - - public HashMap getExits() { - return exits; - } - - public RelativeBlockVector getExit() { - return exitBlock; - } - - public Material getControlBlock() { - return types.get('-'); - } - - public String getFilename() { - return filename; - } - - public Material getPortalBlockOpen() { - return portalBlockOpen; - } - - public void setPortalBlockOpen(Material type) { - portalBlockOpen = type; - } - - public Material getPortalBlockClosed() { - return portalBlockClosed; - } - - public void setPortalBlockClosed(Material type) { - portalBlockClosed = type; - } - - public Material getButton() { - return button; - } - - public int getUseCost() { - if (useCost < 0) return EconomyHandler.useCost; - return useCost; - } - - public Integer getCreateCost() { - if (createCost < 0) return EconomyHandler.createCost; - return createCost; - } - - public Integer getDestroyCost() { - if (destroyCost < 0) return EconomyHandler.destroyCost; - return destroyCost; - } - - public Boolean getToOwner() { - 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, 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; - } - - 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 (type != portalBlockClosed && type != portalBlockOpen) { - Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); - return false; - } - } 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); - return false; - } - } - } - } - - return true; - } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java new file mode 100644 index 0000000..bdbff33 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -0,0 +1,202 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.RelativeBlockVector; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * The gate layout describes where every part of the gate should be + * + *

The gate layout parses a layout described by a Character matrix and stores the different parts of the gate as + * relative block vectors.

+ */ +public class GateLayout { + + private Character [][] layout; + private final HashMap exits = new HashMap<>(); + private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; + private RelativeBlockVector[] border = new RelativeBlockVector[0]; + private RelativeBlockVector[] controls = new RelativeBlockVector[0]; + private RelativeBlockVector exitBlock = null; + + /** + * Instantiates a new gate layout + * + * @param layout

A character array describing the layout

+ */ + public GateLayout(Character[][] layout) { + this.layout = layout; + readLayout(); + } + + /** + * Gets the character array describing this layout + * + * @return

The character array describing this layout

+ */ + public Character[][] getLayout() { + return this.layout; + } + + /** + * Gets the locations of entrances for this gate + * + * @return

The locations of entrances for this gate

+ */ + public RelativeBlockVector[] getEntrances() { + return entrances; + } + + /** + * Gets the locations of border blocks for the gate described by this layout + * + *

A border block is basically any block of the frame. In terms of the nether gate, the border blocks are every + * block of the gate that's not air when the gate is closed. The sign and button are not border blocks.

+ * + * @return

The locations of border blocks for this gate

+ */ + public RelativeBlockVector[] getBorder() { + return border; + } + + /** + * Gets the exit block defined in the layout + * + * @return

The exit block defined in the layout

+ */ + public RelativeBlockVector getExit() { + return exitBlock; + } + + /** + * Gets other possible exits of the gate + * + * @return

Other possible gate exits

+ */ + public HashMap getExits() { + return exits; + } + + /** + * Gets the locations of the control blocks for this gate + * + *

The control blocks are the blocks where a sign can be placed to create a portal.

+ * + * @return

The locations of the control blocks for this gate

+ */ + public RelativeBlockVector[] getControls() { + return controls; + } + + /** + * Saves the gate layout using a buffered writer + * + * @param bufferedWriter

The buffered writer to write to

+ * @throws IOException

If unable to write to the buffered writer

+ */ + public void save(BufferedWriter bufferedWriter) throws IOException { + for (Character[] line : this.layout) { + for (Character symbol : line) { + bufferedWriter.append(symbol); + } + bufferedWriter.newLine(); + } + } + + /** + * Reads the gate layout to relative block vectors + */ + private void readLayout() { + List entranceList = new ArrayList<>(); + List borderList = new ArrayList<>(); + List controlList = new ArrayList<>(); + RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; + RelativeBlockVector lastExit = null; + + int[] exitDepths = readLayout(controlList, entranceList, borderList); + + //Generate other possible exits + for (int x = 0; x < exitDepths.length; x++) { + relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0); + } + + //Add non-null exits to the exits list + for (int x = relativeExits.length - 1; x >= 0; x--) { + if (relativeExits[x] != null) { + lastExit = relativeExits[x]; + } else { + relativeExits[x] = lastExit; + } + + if (exitDepths[x] > 0) { + this.exits.put(relativeExits[x], x); + } + } + + this.entrances = entranceList.toArray(this.entrances); + this.border = borderList.toArray(this.border); + this.controls = controlList.toArray(this.controls); + } + + /** + * Reads the given layout matrix, filling in the given lists of relative block vectors + * + * @param controlList

The list of control blocks to save to

+ * @param entranceList

The list of entrances to save to

+ * @param borderList

The list of border blocks to save to

+ * @return

A list of depths of possible extra exits

+ */ + private int[] readLayout(List controlList, List entranceList, + List borderList) { + //Store the depth/line of each + int[] exitDepths = new int[layout[0].length]; + + int lineCount = layout.length; + for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) { + int rowSize = layout[lineIndex].length; + for (int rowIndex = 0; rowIndex < rowSize; rowIndex++) { + Character key = layout[lineIndex][rowIndex]; + parseLayoutCharacter(key, rowIndex, lineIndex, exitDepths, controlList, entranceList, borderList); + } + } + return exitDepths; + } + + /** + * Parses one character of the layout + * + * @param key

The character read

+ * @param rowIndex

The row of the read character

+ * @param lineIndex

The line of the read character

+ * @param exitDepths

The list of exit depths to save to

+ * @param controlList

The list of control blocks to save to

+ * @param entranceList

The list of entrances to save to

+ * @param borderList

The list of border blocks to save to

+ */ + private void parseLayoutCharacter(Character key, int rowIndex, int lineIndex, int[] exitDepths, + List controlList, List entranceList, + List borderList) { + //Add control blocks + if (key.equals('-')) { + controlList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); + } + + if (key.equals(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) { + //Register entrances + entranceList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); + //Find the lowest exit block at a given x position + exitDepths[rowIndex] = lineIndex; + //Register exit + if (key.equals(GateHandler.getExitCharacter())) { + this.exitBlock = new RelativeBlockVector(rowIndex, lineIndex, 0); + } + } else if (!key.equals(GateHandler.getAnythingCharacter())) { + //Add border + borderList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); + } + } +} diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java similarity index 97% rename from src/main/java/net/knarcraft/stargate/Portal.java rename to src/main/java/net/knarcraft/stargate/portal/Portal.java index 065596b..a705168 100644 --- a/src/main/java/net/knarcraft/stargate/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -1,5 +1,10 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.portal; +import net.knarcraft.stargate.BlockLocation; +import net.knarcraft.stargate.BloxPopulator; +import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; @@ -317,7 +322,7 @@ public class Portal { public BlockLocation[] getEntrances() { if (entrances == null) { - RelativeBlockVector[] space = gate.getEntrances(); + RelativeBlockVector[] space = gate.getLayout().getEntrances(); entrances = new BlockLocation[space.length]; int i = 0; @@ -330,7 +335,7 @@ public class Portal { public BlockLocation[] getFrame() { if (frame == null) { - RelativeBlockVector[] border = gate.getBorder(); + RelativeBlockVector[] border = gate.getLayout().getBorder(); frame = new BlockLocation[border.length]; int i = 0; @@ -371,7 +376,7 @@ public class Portal { if (isOpen() && !force) return false; - Material openType = gate.getPortalBlockOpen(); + Material openType = gate.getPortalOpenBlock(); Axis ax = openType == Material.NETHER_PORTAL ? rot : null; for (BlockLocation inside : getEntrances()) { Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, ax)); @@ -409,7 +414,7 @@ public class Portal { if (isAlwaysOn() && !force) return; // Only close always-open if forced // Close this gate, then the dest gate. - Material closedType = gate.getPortalBlockClosed(); + Material closedType = gate.getPortalClosedBlock(); for (BlockLocation inside : getEntrances()) { Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType)); } @@ -455,7 +460,7 @@ public class Portal { } public boolean isPowered() { - RelativeBlockVector[] controls = gate.getControls(); + RelativeBlockVector[] controls = gate.getLayout().getControls(); for (RelativeBlockVector vector : controls) { BlockData data = getBlockAt(vector).getBlock().getBlockData(); @@ -583,8 +588,8 @@ public class Portal { 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()); + if (gate.getLayout().getExit() != null) { + BlockLocation exit = getBlockAt(gate.getLayout().getExit()); int back = (isBackwards()) ? -1 : 1; 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); @@ -657,7 +662,7 @@ public class Portal { if (!Stargate.verifyPortals) { return true; } - for (RelativeBlockVector control : gate.getControls()) { + for (RelativeBlockVector control : gate.getLayout().getControls()) { verified = verified && getBlockAt(control).getBlock().getType().equals(gate.getControlBlock()); } return verified; diff --git a/src/main/java/net/knarcraft/stargate/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java similarity index 97% rename from src/main/java/net/knarcraft/stargate/PortalHandler.java rename to src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index a45f8c2..4c38422 100644 --- a/src/main/java/net/knarcraft/stargate/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -1,5 +1,9 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.portal; +import net.knarcraft.stargate.BlockLocation; +import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.TwoTuple; import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.utility.EconomyHelper; import org.bukkit.Bukkit; @@ -38,6 +42,10 @@ public class PortalHandler { // A list of Bungee gates private static final Map bungeePortals = new HashMap<>(); + private PortalHandler() { + + } + public static List getNetwork(String network) { return allPortalsNet.get(network.toLowerCase()); } @@ -208,7 +216,7 @@ public class PortalHandler { return null; } - if (Gate.getGatesByControlBlock(idParent).length == 0) { + if (GateHandler.getGatesByControlBlock(idParent).length == 0) { return null; } @@ -250,7 +258,7 @@ public class PortalHandler { buttonFacing = BlockFace.SOUTH; } - Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); + Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent); Gate gate = null; RelativeBlockVector buttonVector = null; @@ -258,7 +266,7 @@ public class PortalHandler { if (gate != null || buttonVector != null) { break; } - RelativeBlockVector[] vectors = possibility.getControls(); + RelativeBlockVector[] vectors = possibility.getLayout().getControls(); RelativeBlockVector otherControl = null; for (RelativeBlockVector vector : vectors) { @@ -357,7 +365,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()) { + for (RelativeBlockVector v : gate.getLayout().getBorder()) { 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"); @@ -427,7 +435,7 @@ public class PortalHandler { // No button on an always-open gate. if (!portalOptions.get(PortalOption.ALWAYS_ON)) { button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); - Directional buttonData = (Directional) Bukkit.createBlockData(gate.getButton()); + Directional buttonData = (Directional) Bukkit.createBlockData(gate.getPortalButton()); buttonData.setFacing(buttonFacing); button.getBlock().setBlockData(buttonData); portal.setButton(button); @@ -447,7 +455,7 @@ public class PortalHandler { // Set the inside of the gate to its closed material } else { for (BlockLocation inside : portal.getEntrances()) { - inside.setType(portal.getGate().getPortalBlockClosed()); + inside.setType(portal.getGate().getPortalClosedBlock()); } } @@ -813,7 +821,7 @@ public class PortalHandler { int modZ = Integer.parseInt(portalData[4]); float rotX = Float.parseFloat(portalData[5]); BlockLocation topLeft = new BlockLocation(world, portalData[6]); - Gate gate = Gate.getGateByName(portalData[7]); + Gate gate = GateHandler.getGateByName(portalData[7]); if (gate == null) { Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + " does not exist [" + portalData[7] + "]"); @@ -907,7 +915,7 @@ public class PortalHandler { */ private static void destroyInvalidStarGate(Portal portal) { // DEBUG - for (RelativeBlockVector control : portal.getGate().getControls()) { + for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); } diff --git a/src/main/java/net/knarcraft/stargate/PortalOption.java b/src/main/java/net/knarcraft/stargate/portal/PortalOption.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/PortalOption.java rename to src/main/java/net/knarcraft/stargate/portal/PortalOption.java index 1c87685..e989aec 100644 --- a/src/main/java/net/knarcraft/stargate/PortalOption.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOption.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.portal; public enum PortalOption { diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index bfdedec..234c370 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.thread; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.Stargate; import java.util.Iterator; diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 0f2d4b7..b51cf4e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.utility; -import net.knarcraft.stargate.Portal; -import net.knarcraft.stargate.PortalHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; @@ -20,6 +20,10 @@ public final class BungeeHelper { private final static String bungeeChannel = "BungeeCord"; private final static String teleportMessageDelimiter = "#@#"; + private BungeeHelper() { + + } + /** * Sends a plugin message to BungeeCord allowing the target server to catch it * diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 238be40..4ca48e0 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -1,11 +1,15 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.EconomyHandler; -import net.knarcraft.stargate.Portal; +import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; -public class EconomyHelper { +public final class EconomyHelper { + + private EconomyHelper() { + + } /** * Tries to make the given user pay the teleport fee diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 76e4d27..285e118 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -8,6 +8,10 @@ import org.bukkit.Tag; */ public final class MaterialHelper { + private MaterialHelper() { + + } + /** * Checks whether the given material is a dead or alive wall coral * diff --git a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java index 293e9fd..f4eb05c 100644 --- a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java +++ b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; public class RelativeBlockVectorTest { @@ -14,4 +15,18 @@ public class RelativeBlockVectorTest { assertEquals(23, relativeBlockVector.getDistance()); } + @Test + public void equalsTest() { + RelativeBlockVector vector1 = new RelativeBlockVector(56, 34, 76); + RelativeBlockVector vector2 = new RelativeBlockVector(56, 34, 76); + assertEquals(vector1, vector2); + } + + @Test + public void notEqualsTest() { + RelativeBlockVector vector1 = new RelativeBlockVector(456, 78, 234); + RelativeBlockVector vector2 = new RelativeBlockVector(56, 34, 76); + assertNotEquals(vector1, vector2); + } + } diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java new file mode 100644 index 0000000..537df09 --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -0,0 +1,95 @@ +package net.knarcraft.stargate.portal; + +import be.seeseemelk.mockbukkit.ServerMock; +import be.seeseemelk.mockbukkit.WorldMock; +import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.Stargate; +import org.bukkit.Material; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import be.seeseemelk.mockbukkit.MockBukkit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class GateLayoutTest { + + private static GateLayout layout; + + @BeforeAll + public static void setUp() { + ServerMock server = MockBukkit.mock(); + server.addWorld(new WorldMock(Material.DIRT, 5)); + MockBukkit.load(Stargate.class); + layout = GateHandler.getGateByName("nethergate.gate").getLayout(); + } + + @Test + public void gateLayoutExitTest() { + assertEquals(new RelativeBlockVector(1, 3, 0), layout.getExit()); + } + + @Test + public void gateLayoutExitsTest() { + List expected = new ArrayList<>(); + expected.add(new RelativeBlockVector(1, 3, 0)); + expected.add(new RelativeBlockVector(2, 3, 0)); + + Set exits = layout.getExits().keySet(); + exits.forEach((blockVector) -> assertTrue(expected.contains(blockVector))); + } + + @Test + public void gateLayoutBorderTest() { + List expected = new ArrayList<>(); + expected.add(new RelativeBlockVector(1, 0, 0)); + expected.add(new RelativeBlockVector(2, 0, 0)); + expected.add(new RelativeBlockVector(0, 1, 0)); + expected.add(new RelativeBlockVector(0, 2, 0)); + expected.add(new RelativeBlockVector(0, 3, 0)); + expected.add(new RelativeBlockVector(1, 4, 0)); + expected.add(new RelativeBlockVector(2, 4, 0)); + expected.add(new RelativeBlockVector(3, 1, 0)); + expected.add(new RelativeBlockVector(3, 2, 0)); + expected.add(new RelativeBlockVector(3, 3, 0)); + + RelativeBlockVector[] borderBlocks = layout.getBorder(); + for (RelativeBlockVector blockVector : borderBlocks) { + assertTrue(expected.contains(blockVector)); + } + } + + @Test + public void gateLayoutControlsTest() { + List expected = new ArrayList<>(); + expected.add(new RelativeBlockVector(0, 2, 0)); + expected.add(new RelativeBlockVector(3, 2, 0)); + + RelativeBlockVector[] controlBlocks = layout.getControls(); + for (RelativeBlockVector blockVector : controlBlocks) { + assertTrue(expected.contains(blockVector)); + } + } + + @Test + public void gateLayoutEntrancesTest() { + List expected = new ArrayList<>(); + expected.add(new RelativeBlockVector(1, 1, 0)); + expected.add(new RelativeBlockVector(2, 1, 0)); + expected.add(new RelativeBlockVector(1, 2, 0)); + expected.add(new RelativeBlockVector(2, 2, 0)); + expected.add(new RelativeBlockVector(1, 3, 0)); + expected.add(new RelativeBlockVector(2, 3, 0)); + + RelativeBlockVector[] controlBlocks = layout.getEntrances(); + for (RelativeBlockVector blockVector : controlBlocks) { + assertTrue(expected.contains(blockVector)); + } + } + +} From d26196b8aa15098eb32cc9af69fbf6abb45f8668 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 18:34:23 +0100 Subject: [PATCH 051/378] Adds some extra explanations to gate layout's description --- src/main/java/net/knarcraft/stargate/portal/GateLayout.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index bdbff33..51a9902 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -12,7 +12,8 @@ import java.util.List; * The gate layout describes where every part of the gate should be * *

The gate layout parses a layout described by a Character matrix and stores the different parts of the gate as - * relative block vectors.

+ * relative block vectors. All relative vectors has an origin in the top-left block when looking at the gate's front + * (the side with the sign)

*/ public class GateLayout { From 279ea9d8f0074f64455718d28c1fe09597237d3f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 20:23:12 +0100 Subject: [PATCH 052/378] Fixes some nullpointerexceptions in PlayerEventsListener's onPlayerMove --- .../stargate/listener/PlayerEventsListener.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 15030f1..7b36964 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -100,19 +100,23 @@ public class PlayerEventsListener implements Listener { */ @EventHandler public void onPlayerMove(PlayerMoveEvent event) { - if (event.isCancelled()) { + if (event.isCancelled() || event.getTo() == null) { return; } //Check to see if the player moved to another block - BlockLocation fromLocation = (BlockLocation) event.getFrom(); - BlockLocation toLocation = (BlockLocation) event.getTo(); - if (toLocation == null || fromLocation.equals(toLocation)) { + BlockLocation fromLocation = new BlockLocation(event.getFrom().getBlock()); + BlockLocation toLocation = new BlockLocation(event.getTo().getBlock()); + if (fromLocation.equals(toLocation)) { return; } Player player = event.getPlayer(); Portal entrancePortal = PortalHandler.getByEntrance(toLocation); + if (entrancePortal == null) { + return; + } + Portal destination = entrancePortal.getDestination(player); //Decide if the anything stops the player from teleport From e665a49f0300a6cc8a979c0d29d6fc534df3bd2a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 20:25:07 +0100 Subject: [PATCH 053/378] Adds missing comments to Gate and changes the matches function from n^2 to n execution time --- .../net/knarcraft/stargate/portal/Gate.java | 216 +++++++++++++----- 1 file changed, 160 insertions(+), 56 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index f2fce39..f129ce0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -1,8 +1,9 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Material; import java.io.BufferedWriter; @@ -37,16 +38,16 @@ public class Gate { /** * Instantiates a new gate * - * @param filename

The name of the gate which equal the name of the file

- * @param layout

The character layout defined in the gate file

- * @param types

The block types the different layout characters represent

- * @param portalOpenBlock

The material to set the non-frame to when the portal is open

+ * @param filename

The name of the gate which equal the name of the file

+ * @param layout

The character layout defined in the gate file

+ * @param types

The block types the different layout characters represent

+ * @param portalOpenBlock

The material to set the non-frame to when the portal is open

* @param portalClosedBlock

The material to set the non-frame to when the portal is closed

- * @param portalButton

The material to use for the portal button

- * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

- * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

- * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

- * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

+ * @param portalButton

The material to use for the portal button

+ * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

+ * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

+ * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

+ * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

*/ public Gate(String filename, GateLayout layout, HashMap types, Material portalOpenBlock, Material portalClosedBlock, Material portalButton, int useCost, int createCost, int destroyCost, @@ -81,95 +82,198 @@ public class Gate { return types; } + /** + * Gets the material type used for this gate's control blocks + * + * @return

The material type used for control blocks

+ */ public Material getControlBlock() { - return types.get('-'); + return types.get(GateHandler.getControlBlockCharacter()); } + /** + * Gets the filename of this gate + * + * @return

The filename of this gate

+ */ public String getFilename() { return filename; } + /** + * Gets the block type to use for the opening when a portal using this gate is open + * + * @return

The block type to use for the opening when open

+ */ public Material getPortalOpenBlock() { return portalOpenBlock; } + /** + * Sets the block to use for the opening when a portal using this gate is open + * + * @param type

The block type to use for the opening when open

+ */ public void setPortalOpenBlock(Material type) { portalOpenBlock = type; } + /** + * Gets the block type to use for the opening when a portal using this gate is closed + * + * @return

The block type to use for the opening when closed

+ */ public Material getPortalClosedBlock() { return portalClosedBlock; } + /** + * Sets the block type to use for the opening when a portal using this gate is closed + * + * @param type

The block type to use for the opening when closed

+ */ public void setPortalClosedBlock(Material type) { portalClosedBlock = type; } + /** + * Gets the material to use for a portal's button if using this gate type + * + * @return

The material to use for a portal's button if using this gate type

+ */ public Material getPortalButton() { return portalButton; } + /** + * Gets the cost of using a portal with this gate + * + * @return

The cost of using a portal with this gate

+ */ public int getUseCost() { - if (useCost < 0) return EconomyHandler.useCost; - return useCost; + return useCost < 0 ? EconomyHandler.getUseCost() : useCost; } + /** + * Gets the cost of creating a portal with this gate + * + * @return

The cost of creating a portal with this gate

+ */ public Integer getCreateCost() { - if (createCost < 0) return EconomyHandler.createCost; - return createCost; + return createCost < 0 ? EconomyHandler.getCreateCost() : createCost; } + /** + * Gets the cost of destroying a portal with this gate + * + * @return

The cost of destroying a portal with this gate

+ */ public Integer getDestroyCost() { - if (destroyCost < 0) return EconomyHandler.destroyCost; + if (destroyCost < 0) return EconomyHandler.getDestroyCost(); return destroyCost; } + /** + * Gets whether portal payments go to this portal's owner + * + * @return

Whether portal payments go to the owner

+ */ public Boolean getToOwner() { return toOwner; } + /** + * Checks whether a portal's gate matches this gate type + * + * @param topLeft

The top-left block of the portal's gate

+ * @param modX

The x modifier used

+ * @param modZ

The z modifier used

+ * @return

True if this gate matches the portal

+ */ public boolean matches(BlockLocation topLeft, int modX, int modZ) { return matches(topLeft, modX, modZ, false); } + /** + * Checks whether a portal's gate matches this gate type + * + * @param topLeft

The top-left block of the portal's gate

+ * @param modX

The x modifier used

+ * @param modZ

The z modifier used

+ * @param onCreate

Whether this is used in the context of creating a new gate

+ * @return

True if this gate matches the portal

+ */ public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) { - HashMap portalTypes = new HashMap<>(types); - Character[][] layout = this.layout.getLayout(); - for (int y = 0; y < layout.length; y++) { - for (int x = 0; x < layout[y].length; x++) { - Character key = layout[y][x]; + return verifyGateEntrancesMatch(topLeft, modX, modZ, onCreate) && verifyGateBorderMatches(topLeft, modX, modZ); + } - if (key.equals(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) { - if (Stargate.ignoreEntrance) { - continue; - } + /** + * Verifies that all border blocks of a portal gate matches this gate type + * + * @param topLeft

The top-left block of the portal

+ * @param modX

The x modifier used

+ * @param modZ

The z modifier used

+ * @return

True if all border blocks of the gate match the layout

+ */ + private boolean verifyGateBorderMatches(BlockLocation topLeft, int modX, int modZ) { + Map portalTypes = new HashMap<>(types); + for (RelativeBlockVector borderVector : layout.getBorder()) { + int rowIndex = borderVector.getRight(); + int lineIndex = borderVector.getDepth(); + Character key = layout.getLayout()[lineIndex][rowIndex]; - 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 (type != portalClosedBlock && type != portalOpenBlock) { - Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); - return false; - } - } else if (!key.equals(GateHandler.getAnythingCharacter())) { - 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); - return false; - } - } + Material materialInLayout = portalTypes.get(key); + Material materialAtLocation = getBlockAt(topLeft, borderVector, modX, modZ).getType(); + if (materialInLayout == null) { + portalTypes.put(key, materialAtLocation); + } else if (materialAtLocation != materialInLayout) { + Stargate.debug("Gate::Matches", String.format("Block Type Mismatch: %s != %s", + materialAtLocation, materialInLayout)); + return false; } } - return true; } + /** + * Verifies that all entrances of a portal gate matches this gate type + * + * @param topLeft

The top-left block of this portal

+ * @param modX

The x modifier used

+ * @param modZ

The z modifier used

+ * @param onCreate

Whether this is used in the context of creating a new gate

+ * @return

Whether this is used in the context of creating a new gate

+ */ + private boolean verifyGateEntrancesMatch(BlockLocation topLeft, int modX, int modZ, boolean onCreate) { + if (Stargate.ignoreEntrance) { + return true; + } + for (RelativeBlockVector entranceVector : layout.getEntrances()) { + Material type = getBlockAt(topLeft, entranceVector, modX, modZ).getType(); + + // Ignore entrance if it's air and we're creating a new gate + if (onCreate && type == Material.AIR) { + continue; + } + + if (type != portalClosedBlock && type != portalOpenBlock) { + Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); + return false; + } + } + return true; + } + + /** + * Gets the block at a relative block vector location + * + * @param vector

The relative block vector

+ * @return

The block at the given relative position

+ */ + private BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, int modX, int modZ) { + return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); + } + /** * Saves this gate to a file * @@ -206,7 +310,7 @@ public class Gate { * Saves current economy related values using a buffered writer * * @param bufferedWriter

The buffered writer to write to

- * * @throws IOException

If unable to write to the buffered writer

+ * * @throws IOException

If unable to write to the buffered writer

*/ private void saveEconomyValues(BufferedWriter bufferedWriter) throws IOException { if (useCost != -1) { @@ -251,8 +355,8 @@ public class Gate { * Writes an integer to a config * * @param bufferedWriter

The buffered writer to write the config to

- * @param key

The config key to save

- * @param value

The value of the config key

+ * @param key

The config key to save

+ * @param value

The value of the config key

* @throws IOException

If unable to write to the buffered writer

*/ private void writeConfig(BufferedWriter bufferedWriter, String key, int value) throws IOException { @@ -263,8 +367,8 @@ public class Gate { * Writes a boolean to a config * * @param bufferedWriter

The buffered writer to write the config to

- * @param key

The config key to save

- * @param value

The value of the config key

+ * @param key

The config key to save

+ * @param value

The value of the config key

* @throws IOException

If unable to write to the buffered writer

*/ private void writeConfig(BufferedWriter bufferedWriter, String key, boolean value) throws IOException { @@ -275,8 +379,8 @@ public class Gate { * Writes a string to a config * * @param bufferedWriter

The buffered writer to write the config to

- * @param key

The config key to save

- * @param value

The value of the config key

+ * @param key

The config key to save

+ * @param value

The value of the config key

* @throws IOException

If unable to write to the buffered writer

*/ private void writeConfig(BufferedWriter bufferedWriter, String key, String value) throws IOException { @@ -287,9 +391,9 @@ public class Gate { * Writes a formatted string to a buffered writer * * @param bufferedWriter

The buffered writer to write the formatted string to

- * @param format

The format to use

- * @param key

The config key to save

- * @param value

The config value to save

+ * @param format

The format to use

+ * @param key

The config key to save

+ * @param value

The config value to save

* @throws IOException

If unable to write to the buffered writer

*/ private void writeConfig(BufferedWriter bufferedWriter, String format, String key, Object value) throws IOException { From e5fef0b16a3b3cd5b91c2dfe4c73e3ab05d34336 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 20:26:10 +0100 Subject: [PATCH 054/378] Moves the EconomyHandler to utility and adds some encapsulation for three of its variables --- .../java/net/knarcraft/stargate/Stargate.java | 7 +- .../listener/PluginEventListener.java | 2 +- .../stargate/portal/GateHandler.java | 21 +++++- .../knarcraft/stargate/portal/GateLayout.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 2 +- .../{ => utility}/EconomyHandler.java | 75 +++++++++++++++++-- .../stargate/utility/EconomyHelper.java | 7 +- 7 files changed, 101 insertions(+), 15 deletions(-) rename src/main/java/net/knarcraft/stargate/{ => utility}/EconomyHandler.java (68%) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2ef10ed..6487083 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -17,6 +17,7 @@ import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalOption; import net.knarcraft.stargate.thread.BlockPopulatorThread; import net.knarcraft.stargate.thread.StarGateThread; +import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; @@ -613,9 +614,9 @@ public class Stargate extends JavaPlugin { permDebug = newConfig.getBoolean("permdebug"); // Economy EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); - EconomyHandler.createCost = newConfig.getInt("createcost"); - EconomyHandler.destroyCost = newConfig.getInt("destroycost"); - EconomyHandler.useCost = newConfig.getInt("usecost"); + EconomyHandler.setCreateCost(newConfig.getInt("createcost")); + EconomyHandler.setDestroyCost(newConfig.getInt("destroycost")); + EconomyHandler.setUseCost(newConfig.getInt("usecost")); EconomyHandler.toOwner = newConfig.getBoolean("toowner"); EconomyHandler.chargeFreeDestination = newConfig.getBoolean("chargefreedestination"); EconomyHandler.freeGatesGreen = newConfig.getBoolean("freegatesgreen"); diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index 85775c6..fbe34be 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 7c94e9f..521838c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; @@ -13,11 +13,15 @@ import java.util.List; import java.util.Scanner; import java.util.logging.Level; +/** + * The gate handler keeps track of all gates + */ public class GateHandler { private static final Character ANYTHING = ' '; private static final Character ENTRANCE = '.'; private static final Character EXIT = '*'; + private static final Character CONTROL_BLOCK = '-'; private static Material defaultPortalBlockOpen = Material.NETHER_PORTAL; private static Material defaultPortalBlockClosed = Material.AIR; @@ -49,10 +53,25 @@ public class GateHandler { return ENTRANCE; } + /** + * Gets the character used for defining the exit + * + * @return

The character used for defining the exit

+ */ public static Character getExitCharacter() { return EXIT; } + + /** + * Gets the character used for defining control blocks + * + * @return

The character used for defining control blocks

+ */ + public static Character getControlBlockCharacter() { + return CONTROL_BLOCK; + } + public static void registerGate(Gate gate) { gates.put(gate.getFilename(), gate); diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 51a9902..9876439 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -182,7 +182,7 @@ public class GateLayout { List controlList, List entranceList, List borderList) { //Add control blocks - if (key.equals('-')) { + if (key.equals(GateHandler.getControlBlockCharacter())) { controlList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index a705168..4287748 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -2,7 +2,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.BloxPopulator; -import net.knarcraft.stargate.EconomyHandler; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; diff --git a/src/main/java/net/knarcraft/stargate/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java similarity index 68% rename from src/main/java/net/knarcraft/stargate/EconomyHandler.java rename to src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 1cedc55..0a614e2 100644 --- a/src/main/java/net/knarcraft/stargate/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -1,5 +1,6 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.utility; +import net.knarcraft.stargate.Stargate; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -12,18 +13,79 @@ import java.util.UUID; /** * This handler handles economy actions such as payment for using a gate */ -public class EconomyHandler { +public final class EconomyHandler { + public static boolean economyEnabled = false; public static Economy economy = null; public static Plugin vault = null; - - public static int useCost = 0; - public static int createCost = 0; - public static int destroyCost = 0; + private static int useCost = 0; + private static int createCost = 0; + private static int destroyCost = 0; public static boolean toOwner = false; public static boolean chargeFreeDestination = true; public static boolean freeGatesGreen = false; + /** + * Gets the cost of using a gate without a specified cost + * + * @return

The gate use cost

+ */ + public static int getUseCost() { + return useCost; + } + + /** + * Sets the cost of using a gate without a specified cost + * + *

The use cost cannot be negative.

+ * + * @param useCost

The gate use cost

+ */ + public static void setUseCost(int useCost) { + if (useCost < 0) { + throw new IllegalArgumentException("Using a gate cannot cost a negative amount"); + } + EconomyHandler.useCost = useCost; + } + + /** + * Gets the cost of creating a gate without a specified cost + * + * @return

The gate creation cost

+ */ + public static int getCreateCost() { + return createCost; + } + + /** + * Sets the cost of creating a gate without a specified cost + * + *

The gate create cost cannot be negative

+ * + * @param createCost

The gate creation cost

+ */ + public static void setCreateCost(int createCost) { + EconomyHandler.createCost = createCost; + } + + /** + * Gets the cost of destroying a gate without a specified cost + * + * @return

The gate destruction cost

+ */ + public static int getDestroyCost() { + return destroyCost; + } + + /** + * Sets the cost of destroying a gate without a specified cost + * + * @param destroyCost

The gate destruction cost

+ */ + public static void setDestroyCost(int destroyCost) { + EconomyHandler.destroyCost = destroyCost; + } + /** * Gets the balance (money) of the given player * @@ -51,6 +113,7 @@ public class EconomyHandler { if (!economy.has(player, amount)) { return false; } + //Take money from the user and give to the owner economy.withdrawPlayer(player, amount); economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 4ca48e0..3df2b1f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -1,10 +1,12 @@ package net.knarcraft.stargate.utility; -import net.knarcraft.stargate.EconomyHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; +/** + * The economy helper class has helper functions for player payment + */ public final class EconomyHelper { private EconomyHelper() { @@ -24,7 +26,8 @@ public final class EconomyHelper { //Try to charge the player if (entrancePortal.getGate().getToOwner()) { - success = entrancePortal.getOwnerUUID() != null && Stargate.chargePlayer(player, entrancePortal.getOwnerUUID(), cost); + success = entrancePortal.getOwnerUUID() != null && Stargate.chargePlayer(player, + entrancePortal.getOwnerUUID(), cost); } else { success = Stargate.chargePlayer(player, cost); } From 151c242e6927f6fb880f8bfec2c95f3064ef85e8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Feb 2021 20:36:37 +0100 Subject: [PATCH 055/378] Changes names of some variables and one method to increase readability --- .../net/knarcraft/stargate/BloxPopulator.java | 2 +- .../stargate/thread/BlockPopulatorThread.java | 24 ++++++++++--------- .../stargate/thread/StarGateThread.java | 23 ++++++++++-------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BloxPopulator.java b/src/main/java/net/knarcraft/stargate/BloxPopulator.java index f25d48a..130cf94 100644 --- a/src/main/java/net/knarcraft/stargate/BloxPopulator.java +++ b/src/main/java/net/knarcraft/stargate/BloxPopulator.java @@ -60,7 +60,7 @@ public class BloxPopulator { * * @return

The material used for population

*/ - public Material getMat() { + public Material getMaterial() { return nextMat; } diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java index 1f620e2..a37547b 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java @@ -12,20 +12,22 @@ public class BlockPopulatorThread implements Runnable { public void run() { long sTime = System.nanoTime(); while (System.nanoTime() - sTime < 25000000) { - BloxPopulator b = Stargate.blockPopulatorQueue.poll(); - if (b == null) return; - Block blk = b.getBlockLocation().getBlock(); - blk.setType(b.getMat(), false); - if (b.getMat() == Material.END_GATEWAY && blk.getWorld().getEnvironment() == World.Environment.THE_END) { + BloxPopulator bloxPopulator = Stargate.blockPopulatorQueue.poll(); + if (bloxPopulator == null) { + return; + } + Block block = bloxPopulator.getBlockLocation().getBlock(); + block.setType(bloxPopulator.getMaterial(), false); + if (bloxPopulator.getMaterial() == Material.END_GATEWAY && block.getWorld().getEnvironment() == World.Environment.THE_END) { // force a location to prevent exit gateway generation - EndGateway gateway = (EndGateway) blk.getState(); - gateway.setExitLocation(blk.getWorld().getSpawnLocation()); + EndGateway gateway = (EndGateway) block.getState(); + gateway.setExitLocation(block.getWorld().getSpawnLocation()); gateway.setExactTeleport(true); gateway.update(false, false); - } else if (b.getAxis() != null) { - Orientable orientable = (Orientable) blk.getBlockData(); - orientable.setAxis(b.getAxis()); - blk.setBlockData(orientable); + } else if (bloxPopulator.getAxis() != null) { + Orientable orientable = (Orientable) block.getBlockData(); + orientable.setAxis(bloxPopulator.getAxis()); + block.setBlockData(orientable); } } } diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 234c370..98a826b 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -14,21 +14,24 @@ public class StarGateThread implements Runnable { long time = System.currentTimeMillis() / 1000; // Close open portals for (Iterator iterator = Stargate.openList.iterator(); iterator.hasNext(); ) { - Portal p = iterator.next(); - // Skip always open gates - if (p.isAlwaysOn()) continue; - if (!p.isOpen()) continue; - if (time > p.getOpenTime() + Stargate.getOpenTime()) { - p.close(false); + Portal portal = iterator.next(); + // Skip always open and non-open gates + if (portal.isAlwaysOn() || !portal.isOpen()) { + continue; + } + if (time > portal.getOpenTime() + Stargate.getOpenTime()) { + portal.close(false); iterator.remove(); } } // Deactivate active portals for (Iterator iterator = Stargate.activeList.iterator(); iterator.hasNext(); ) { - Portal p = iterator.next(); - if (!p.isActive()) continue; - if (time > p.getOpenTime() + Stargate.getActiveTime()) { - p.deactivate(); + Portal portal = iterator.next(); + if (!portal.isActive()) { + continue; + } + if (time > portal.getOpenTime() + Stargate.getActiveTime()) { + portal.deactivate(); iterator.remove(); } } From af693bddd2bd09c1f98e679b719d6eecb291980b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 23 Feb 2021 00:35:18 +0100 Subject: [PATCH 056/378] Fixes the timing of the block populator thread which caused a delay between opening a gate and it displaying as open --- src/main/java/net/knarcraft/stargate/Stargate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 6487083..5037c61 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -568,7 +568,7 @@ public class Stargate extends JavaPlugin { } getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); - getServer().getScheduler().runTaskTimer(this, new BlockPopulatorThread(), 0L, 100L); + getServer().getScheduler().runTaskTimer(this, new BlockPopulatorThread(), 0L, 1L); this.registerCommands(); } From 681014a431ff1c25ac35353166e63e4d2e202ae6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 23 Feb 2021 00:35:48 +0100 Subject: [PATCH 057/378] Improves some code formatting in the portal open method --- .../java/net/knarcraft/stargate/portal/Portal.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 4287748..f65517a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -371,15 +371,19 @@ public class Portal { // Call the StargateOpenEvent StargateOpenEvent event = new StargateOpenEvent(openFor, this, force); Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) return false; + if (event.isCancelled()) { + return false; + } force = event.getForce(); - if (isOpen() && !force) return false; + if (isOpen() && !force) { + return false; + } Material openType = gate.getPortalOpenBlock(); - Axis ax = openType == Material.NETHER_PORTAL ? rot : null; + Axis axis = openType == Material.NETHER_PORTAL ? rot : null; for (BlockLocation inside : getEntrances()) { - Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, ax)); + Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, axis)); } isOpen = true; From e42da6d6bd52926571757385eb3da55741efbf0b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 23 Feb 2021 00:41:40 +0100 Subject: [PATCH 058/378] Updates the README with some of the recent changes --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4f23123..9e8de53 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,10 @@ bungeeSign=Teleport to - Removes some pre-UUID code - Adds underwater portals - Makes it easier to add more default gates + - Adds a new default gate which can be used underwater + - Adds more items usable as buttons (corals, chest, shulker box), which allows underwater portals + - Splits a lot of the code into smaller objects + - Moves duplicated code into helper classes #### \[Version 0.8.0.3] PseudoKnight fork - Fix economy - Add custom buttons From 5f685b2460ff3297b1af1d57a168dc54a5460602 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 23 Feb 2021 19:17:05 +0100 Subject: [PATCH 059/378] Fixes some oddities regarding vehicle teleportation Accounts for size when blocking an entity near a portal from teleporting to the nether Ignores boats and minecarts when teleporting a vehicle after the player Makes it easy to get a portal by adjacent entrance for any given range --- .../listener/EntityEventListener.java | 7 ++- .../listener/PlayerEventsListener.java | 8 ++- .../listener/VehicleEventListener.java | 59 +++++++------------ .../stargate/portal/PortalHandler.java | 59 +++++++++++-------- 4 files changed, 68 insertions(+), 65 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 9d35ad2..22dfbe2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -27,8 +28,10 @@ public class EntityEventListener implements Listener { return; } - Portal portal = PortalHandler.getByAdjacentEntrance(event.getFrom()); - if (portal != null) { + Entity entity = event.getEntity(); + int entitySize = (int) Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), + entity.getBoundingBox().getWidthZ())); + if (PortalHandler.getByAdjacentEntrance(event.getFrom(), entitySize) != null) { event.setCancelled(true); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 7b36964..705ef5c 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -11,7 +11,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.Boat; import org.bukkit.entity.Entity; +import org.bukkit.entity.Minecart; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; import org.bukkit.event.Event; @@ -84,11 +86,13 @@ public class PlayerEventsListener implements Listener { Entity playerVehicle = event.getPlayer().getVehicle(); Portal portal = PortalHandler.getByEntrance(event.getFrom()); - if (playerVehicle != null && PortalHandler.getByEntrance(event.getFrom()) != null) { + if (playerVehicle != null && PortalHandler.getByEntrance(event.getFrom()) != null && + !(playerVehicle instanceof Minecart) && + !(playerVehicle instanceof Boat)) { Portal destinationPortal = portal.getDestination(); if (destinationPortal != null) { VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer()); - Stargate.log.info("Player was driving " + playerVehicle.getName()); + Stargate.debug("playerTeleport", "Player was driving " + playerVehicle.getName()); } } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 1888370..0ab7da2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -32,14 +32,26 @@ public class VehicleEventListener implements Listener { } /** - * Teleports a vehicle through a stargate + * Check for a vehicle moving through a portal * - * @param passengers

The passengers inside the vehicle

- * @param entrancePortal

The portal the vehicle is entering

- * @param vehicle

The vehicle passing through

+ * @param event

The triggered move event

*/ - public static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { - teleportVehicle(passengers, entrancePortal, vehicle, false); + @EventHandler + public void onVehicleMove(VehicleMoveEvent event) { + if (!Stargate.handleVehicles) { + return; + } + List passengers = event.getVehicle().getPassengers(); + Vehicle vehicle = event.getVehicle(); + + Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); + + //Return if the portal cannot be teleported through + if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { + return; + } + + teleportVehicle(passengers, entrancePortal, vehicle); } /** @@ -48,12 +60,11 @@ public class VehicleEventListener implements Listener { * @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) { + private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { Stargate.log.info(Stargate.getString("prefox") + "Found passenger vehicle"); - teleportPlayerAndVehicle(entrancePortal, vehicle, passengers, skipOpenCheck); + teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { Stargate.log.info(Stargate.getString("prefox") + "Found empty vehicle"); Portal destinationPortal = entrancePortal.getDestination(); @@ -72,10 +83,9 @@ public class VehicleEventListener implements Listener { * @param vehicle

The vehicle to teleport

* @param passengers

Any entities sitting in the minecart

*/ - private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers, - boolean skipOpenCheck) { + private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { Player player = (Player) passengers.get(0); - if (!skipOpenCheck && !entrancePortal.isOpenFor(player)) { + if (!entrancePortal.isOpenFor(player)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); return; } @@ -105,29 +115,4 @@ public class VehicleEventListener implements Listener { entrancePortal.close(false); } - /** - * Check for a vehicle moving through a portal - * - * @param event

The triggered move event

- */ - @EventHandler - public void onVehicleMove(VehicleMoveEvent event) { - if (!Stargate.handleVehicles) { - return; - } - List passengers = event.getVehicle().getPassengers(); - Vehicle vehicle = event.getVehicle(); - - Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); - - //Return if the portal cannot be teleported through - if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { - 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); - } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 4c38422..ab8ad8d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -555,33 +555,44 @@ public class PortalHandler { /** * Gets a portal given a location adjacent to its entrance * - * @param loc

A location adjacent to the portal's entrance

+ * @param location

A location adjacent to the portal's entrance

* @return

The portal adjacent to the given location

*/ - public static Portal getByAdjacentEntrance(Location loc) { - int centerX = loc.getBlockX(); - int centerY = loc.getBlockY(); - int centerZ = loc.getBlockZ(); - World world = loc.getWorld(); - Portal portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ)); - if (portal != null) { - return portal; + public static Portal getByAdjacentEntrance(Location location) { + return getByAdjacentEntrance(location, 1); + } + + /** + * Gets a portal given a location adjacent to its entrance + * + * @param location

A location adjacent to the portal's entrance

+ * @param range

The range to scan for portals

+ * @return

The portal adjacent to the given location

+ */ + public static Portal getByAdjacentEntrance(Location location, int range) { + List adjacentPositions = new ArrayList<>(); + BlockLocation centerLocation = new BlockLocation(location.getBlock()); + adjacentPositions.add(centerLocation); + + for (int index = 1; index <= range; index++) { + adjacentPositions.add(centerLocation.makeRelative(index, 0, 0)); + adjacentPositions.add(centerLocation.makeRelative(-index, 0, 0)); + adjacentPositions.add(centerLocation.makeRelative(0, 0, index)); + adjacentPositions.add(centerLocation.makeRelative(0, 0, -index)); + if (index < range) { + adjacentPositions.add(centerLocation.makeRelative(index, 0, index)); + adjacentPositions.add(centerLocation.makeRelative(-index, 0, -index)); + adjacentPositions.add(centerLocation.makeRelative(index, 0, -index)); + adjacentPositions.add(centerLocation.makeRelative(-index, 0, index)); + } } - portal = lookupEntrances.get(new BlockLocation(world, centerX + 1, centerY, centerZ)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX - 1, centerY, centerZ)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ + 1)); - if (portal != null) { - return portal; - } - portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ - 1)); - if (portal != null) { - return portal; + + for (BlockLocation adjacentPosition : adjacentPositions) { + Stargate.debug("getByAdjacentEntrance", "Testing" + adjacentPosition); + Portal portal = lookupEntrances.get(adjacentPosition); + if (portal != null) { + return portal; + } } return null; } From 4acea17ba3977724d305e45db9ae0fd8cd5d1ab1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 23 Feb 2021 19:43:49 +0100 Subject: [PATCH 060/378] Fixes boats sometimes not detecting the portal before the player detects the portal --- .../listener/EntityEventListener.java | 5 ++-- .../listener/VehicleEventListener.java | 9 ++++++- .../net/knarcraft/stargate/portal/Portal.java | 7 +++-- .../stargate/portal/PortalHandler.java | 1 - .../stargate/thread/StarGateThread.java | 1 + .../stargate/utility/EntityHelper.java | 27 +++++++++++++++++++ 6 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/EntityHelper.java diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 22dfbe2..700b90a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; @@ -29,9 +30,7 @@ public class EntityEventListener implements Listener { } Entity entity = event.getEntity(); - int entitySize = (int) Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), - entity.getBoundingBox().getWidthZ())); - if (PortalHandler.getByAdjacentEntrance(event.getFrom(), entitySize) != null) { + if (PortalHandler.getByAdjacentEntrance(event.getFrom(), (int) EntityHelper.getEntityMaxSize(entity)) != null) { event.setCancelled(true); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 0ab7da2..db71f90 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.EconomyHelper; +import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; @@ -44,7 +45,13 @@ public class VehicleEventListener implements Listener { List passengers = event.getVehicle().getPassengers(); Vehicle vehicle = event.getVehicle(); - Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); + Portal entrancePortal; + int entitySize = (int) EntityHelper.getEntityMaxSize(vehicle); + if (EntityHelper.getEntityMaxSize(vehicle) > 1) { + entrancePortal = PortalHandler.getByAdjacentEntrance(event.getTo(), entitySize - 1); + } else { + entrancePortal = PortalHandler.getByEntrance(event.getTo()); + } //Return if the portal cannot be teleported through if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index f65517a..df96cb9 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateOpenEvent; import net.knarcraft.stargate.event.StargatePortalEvent; +import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.Axis; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -595,8 +596,10 @@ public class Portal { if (gate.getLayout().getExit() != null) { BlockLocation exit = getBlockAt(gate.getLayout().getExit()); int back = (isBackwards()) ? -1 : 1; - 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); + //TODO: Improve positioning to place the entity just far enough from the portal not to suffocate + double entitySize = EntityHelper.getEntityMaxSize(entity); + 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()); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index ab8ad8d..d3b420e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -588,7 +588,6 @@ public class PortalHandler { } for (BlockLocation adjacentPosition : adjacentPositions) { - Stargate.debug("getByAdjacentEntrance", "Testing" + adjacentPosition); Portal portal = lookupEntrances.get(adjacentPosition); if (portal != null) { return portal; diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 98a826b..4b03cc0 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -10,6 +10,7 @@ import java.util.Iterator; */ public class StarGateThread implements Runnable { + @Override public void run() { long time = System.currentTimeMillis() / 1000; // Close open portals diff --git a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java new file mode 100644 index 0000000..2fd3342 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java @@ -0,0 +1,27 @@ +package net.knarcraft.stargate.utility; + +import org.bukkit.entity.Entity; + +/** + * This helper class helps with entity properties not immediately available + */ +public final class EntityHelper { + + private EntityHelper() { + + } + + /** + * Gets the max size of an entity along its x and z axis + * + *

This function gets the ceiling of the max size of an entity, thus calculating the smallest square needed to + * contain the entity.

+ * + * @param entity

The entity to get max size for

+ * @return

+ */ + public static double getEntityMaxSize(Entity entity) { + return Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ())); + } + +} From 2b52759e0035de2ab18599b72c3d9848dadeb842 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Feb 2021 17:45:53 +0100 Subject: [PATCH 061/378] Makes sure teleportation not from a plugin does not trigger vehicle teleportation --- .../knarcraft/stargate/listener/PlayerEventsListener.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 705ef5c..6673fd2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -80,19 +80,18 @@ public class PlayerEventsListener implements Listener { && PortalHandler.getByAdjacentEntrance(event.getFrom()) != null) { event.setCancelled(true); } - if (event.isCancelled()) { + if (event.isCancelled() || cause != PlayerTeleportEvent.TeleportCause.PLUGIN) { return; } Entity playerVehicle = event.getPlayer().getVehicle(); - Portal portal = PortalHandler.getByEntrance(event.getFrom()); - if (playerVehicle != null && PortalHandler.getByEntrance(event.getFrom()) != null && + Portal portal = PortalHandler.getByAdjacentEntrance(event.getFrom()); + if (playerVehicle != null && portal != null && !(playerVehicle instanceof Minecart) && !(playerVehicle instanceof Boat)) { Portal destinationPortal = portal.getDestination(); if (destinationPortal != null) { VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer()); - Stargate.debug("playerTeleport", "Player was driving " + playerVehicle.getName()); } } } From 378a59586d4164f8afdfc868c18cad8c5aa6fe24 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Feb 2021 17:48:01 +0100 Subject: [PATCH 062/378] Heavily simplifies sign drawing and cleans up vehicle teleportation code --- .../net/knarcraft/stargate/portal/Portal.java | 305 ++++++++++++------ 1 file changed, 198 insertions(+), 107 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index df96cb9..0e6e875 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -490,11 +490,7 @@ public class Portal { Location exit = getExit(player, traveller); //Rotate the player to face out from the portal - int adjust = 180; - if (isBackwards() != origin.isBackwards()) { - adjust = 0; - } - exit.setYaw(traveller.getYaw() - origin.getRotation() + this.getRotation() + adjust); + adjustRotation(traveller, exit, origin); // Call the StargatePortalEvent to allow plugins to change destination if (!origin.equals(this)) { @@ -519,15 +515,28 @@ public class Portal { } } + /** + * Adjusts the rotation of the player to face out from the portal + * + * @param entry

The location the player entered from

+ * @param exit

The location the player will exit from

+ * @param origin

The portal the player entered from

+ */ + private void adjustRotation(Location entry, Location exit, Portal origin) { + int adjust = 180; + if (isBackwards() != origin.isBackwards()) { + adjust = 0; + } + exit.setYaw(entry.getYaw() - origin.getRotation() + this.getRotation() + adjust); + } + /** * 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()); - Stargate.log.info(Stargate.getString("prefix") + "Location of vehicle is " + traveller); + Location traveller = vehicle.getLocation(); Location exit = getExit(vehicle, traveller); double velocity = vehicle.getVelocity().length(); @@ -548,36 +557,60 @@ public class Portal { if (!passengers.isEmpty()) { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { - putPlayerInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); - return; + putPassengersInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); + } else { + teleportLivingVehicle(vehicle, exit, passengers); } - 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, () -> { - vehicle.setVelocity(newVelocity); - }, 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.setVelocity(newVelocity), 1); } } - private void putPlayerInNewVehicle(Vehicle vehicle, List passengers, World vehicleWorld, Location exit, Vector newVelocity) { + /** + * Teleport a vehicle which is not a minecart or a boat + * + * @param vehicle

The vehicle to teleport

+ * @param exit

The location the vehicle will exit

+ * @param passengers

The passengers of the vehicle

+ */ + private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { + vehicle.eject(); + vehicle.teleport(exit); + handleVehiclePassengers(passengers, vehicle, exit); + } + + /** + * Creates a new vehicle equal to the player's previous vehicle and + * + * @param vehicle

The player's old vehicle

+ * @param passengers

A list of all passengers in the vehicle

+ * @param vehicleWorld

The world to spawn the new vehicle in

+ * @param exit

The exit location to spawn the new vehicle on

+ * @param newVelocity

The new velocity of the new vehicle

+ */ + private void putPassengersInNewVehicle(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); + vehicle.setRotation(exit.getYaw(), exit.getPitch()); + handleVehiclePassengers(passengers, newVehicle, exit); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); } - private void handleVehiclePassengers(Vehicle sourceVehicle, List passengers, Vehicle targetVehicle, Location exit) { + /** + * Ejects, teleports and adds all passengers to the target vehicle + * + * @param passengers

The passengers to handle

+ * @param targetVehicle

The vehicle the passengers should be put into

+ * @param exit

The exit location to teleport the passengers to

+ */ + private void handleVehiclePassengers(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.debug("handleVehiclePassengers", "Failed to teleport passenger"); } Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> targetVehicle.addPassenger(passenger), 1); } @@ -590,7 +623,7 @@ public class Portal { * @param traveller

The location of the entity travelling

* @return

The location the entity should be teleported to.

*/ - public Location getExit(Entity entity, Location traveller) { + private Location getExit(Entity entity, Location traveller) { Location exitLocation = null; // Check if the gate has an exit block if (gate.getLayout().getExit() != null) { @@ -790,6 +823,9 @@ public class Portal { drawSign(); } + /** + * Draws the sign on this portal + */ public final void drawSign() { BlockState state = id.getBlock().getState(); if (!(state instanceof Sign)) { @@ -797,97 +833,150 @@ public class Portal { Stargate.debug("Portal::drawSign", "Block: " + id.getBlock().getType() + " @ " + id.getBlock().getLocation()); return; } + Sign sign = (Sign) state; + + //Clear sign + for (int index = 0; index <= 3; index++) { + sign.setLine(index, ""); + } Stargate.setLine(sign, 0, "-" + name + "-"); - int max = destinations.size() - 1; - int done = 0; if (!isActive()) { - Stargate.setLine(sign, ++done, Stargate.getString("signRightClick")); - Stargate.setLine(sign, ++done, Stargate.getString("signToUse")); - if (!isNoNetwork()) { - Stargate.setLine(sign, ++done, "(" + network + ")"); - } + //Default sign text + drawInactiveSign(sign); } else { - // Awesome new logic for Bungee gates if (isBungee()) { - Stargate.setLine(sign, ++done, Stargate.getString("bungeeSign")); - Stargate.setLine(sign, ++done, ">" + destination + "<"); - Stargate.setLine(sign, ++done, "[" + network + "]"); + //Bungee sign + drawBungeeSign(sign); } else if (isFixed()) { - if (isRandom()) { - Stargate.setLine(sign, ++done, "> " + Stargate.getString("signRandom") + " <"); - } else { - Stargate.setLine(sign, ++done, ">" + destination + "<"); - } - if (isNoNetwork()) { - Stargate.setLine(sign, ++done, ""); - } else { - Stargate.setLine(sign, ++done, "(" + network + ")"); - } - Portal dest = PortalHandler.getByName(destination, network); - if (dest == null && !isRandom()) { - Stargate.setLine(sign, ++done, Stargate.getString("signDisconnected")); - } else { - Stargate.setLine(sign, ++done, ""); - } + //Sign pointing at one other portal + drawFixedSign(sign); } else { - int index = destinations.indexOf(destination); - if ((index == max) && (max > 1) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = PortalHandler.getByName(destinations.get(index - 2), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 2)); - } else { - Stargate.setLine(sign, done, destinations.get(index - 2)); - } - } - if ((index > 0) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = PortalHandler.getByName(destinations.get(index - 1), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index - 1)); - } else { - Stargate.setLine(sign, done, destinations.get(index - 1)); - } - } - if (++done <= 3) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = PortalHandler.getByName(destination, network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + ">" + destination + "<"); - } else { - Stargate.setLine(sign, done, " >" + destination + "< "); - } - } - if ((max >= index + 1) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = PortalHandler.getByName(destinations.get(index + 1), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 1)); - } else { - Stargate.setLine(sign, done, destinations.get(index + 1)); - } - } - if ((max >= index + 2) && (++done <= 3)) { - if (EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen) { - Portal dest = PortalHandler.getByName(destinations.get(index + 2), network); - boolean green = Stargate.isFree(activePlayer, this, dest); - Stargate.setLine(sign, done, (green ? ChatColor.DARK_GREEN : "") + destinations.get(index + 2)); - } else { - Stargate.setLine(sign, done, destinations.get(index + 2)); - } - } + //Networking stuff + drawNetworkSign(sign); } } - for (done++; done <= 3; done++) { - sign.setLine(done, ""); - } - sign.update(); } + /** + * Draws a sign with chooseable network locations + * + * @param sign

The sign to draw on

+ */ + private void drawNetworkSign(Sign sign) { + int maxIndex = destinations.size() - 1; + int signLineIndex = 0; + int destinationIndex = destinations.indexOf(destination); + boolean freeGatesGreen = EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen; + + //Last entry, and not only entry. Draw the entry two previously + if ((destinationIndex == maxIndex) && (maxIndex > 1)) { + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2); + } + //Not first entry. Draw the previous entry + if (destinationIndex > 0) { + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 1); + } + //Draw the chosen entry (line 2 or 3) + drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex); + //Has another entry and space on the sign + if ((maxIndex >= destinationIndex + 1) && (++signLineIndex <= 3)) { + drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 1); + } + //Has another entry and space on the sign + if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { + drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 2); + } + } + + /** + * Draws the chosen destination on one sign line + * + * @param freeGatesGreen

Whether to display free gates in a green color

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

+ */ + private void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex) { + if (freeGatesGreen) { + Portal destination = PortalHandler.getByName(this.destination, network); + boolean green = Stargate.isFree(activePlayer, this, destination); + Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + this.destination + "<"); + } else { + Stargate.setLine(sign, signLineIndex, " >" + destination + "< "); + } + } + + /** + * Draws one network destination on one sign line + * + * @param freeGatesGreen

Whether to display free gates in a green color

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

+ * @param destinationIndex

The index of the destination to draw

+ */ + private void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex) { + if (freeGatesGreen) { + Portal destination = PortalHandler.getByName(destinations.get(destinationIndex), network); + boolean green = Stargate.isFree(activePlayer, this, destination); + Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + destinations.get(destinationIndex)); + } else { + Stargate.setLine(sign, signLineIndex, destinations.get(destinationIndex)); + } + } + + /** + * Draws a bungee sign + * + * @param sign

The sign to draw on

+ */ + private void drawBungeeSign(Sign sign) { + Stargate.setLine(sign, 1, Stargate.getString("bungeeSign")); + Stargate.setLine(sign, 2, ">" + destination + "<"); + Stargate.setLine(sign, 3, "[" + network + "]"); + } + + /** + * Draws an inactive sign + * + * @param sign

The sign to draw on

+ */ + private void drawInactiveSign(Sign sign) { + Stargate.setLine(sign, 1, Stargate.getString("signRightClick")); + Stargate.setLine(sign, 2, Stargate.getString("signToUse")); + if (!isNoNetwork()) { + Stargate.setLine(sign, 3, "(" + network + ")"); + } else { + Stargate.setLine(sign, 3, ""); + } + } + + /** + * Draws a sign pointing to a fixed location + * + * @param sign

The sign to draw on

+ */ + private void drawFixedSign(Sign sign) { + if (isRandom()) { + Stargate.setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); + } else { + Stargate.setLine(sign, 1, ">" + destination + "<"); + } + if (isNoNetwork()) { + Stargate.setLine(sign, 2, ""); + } else { + Stargate.setLine(sign, 2, "(" + network + ")"); + } + Portal destination = PortalHandler.getByName(this.destination, network); + if (destination == null && !isRandom()) { + Stargate.setLine(sign, 3, Stargate.getString("signDisconnected")); + } else { + Stargate.setLine(sign, 3, ""); + } + } + /** * Gets the block at a relative block vector location * @@ -914,18 +1003,20 @@ public class Portal { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } Portal other = (Portal) obj; if (name == null) { - if (other.name != null) + if (other.name != null) { return false; - } else if (!name.equalsIgnoreCase(other.name)) + } + } else if (!name.equalsIgnoreCase(other.name)) { return false; + } if (network == null) { return other.network == null; } else { From 496b5d97799e58f0f10b2d49dc74fdc14988f517 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Feb 2021 18:12:26 +0100 Subject: [PATCH 063/378] Moves sign drawing to a helper class to reduce the complexity of the portal class --- .../net/knarcraft/stargate/portal/Portal.java | 162 ++---------------- .../stargate/utility/SignHelper.java | 160 +++++++++++++++++ 2 files changed, 178 insertions(+), 144 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/SignHelper.java diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 0e6e875..36650e0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -2,7 +2,6 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.BloxPopulator; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; @@ -11,8 +10,8 @@ import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateOpenEvent; import net.knarcraft.stargate.event.StargatePortalEvent; import net.knarcraft.stargate.utility.EntityHelper; +import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Axis; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -268,6 +267,10 @@ public class Portal { drawSign(); } + public List getDestinations() { + return new ArrayList<>(this.destinations); + } + public Portal getDestination(Player player) { if (isRandom()) { destinations = PortalHandler.getDestinations(this, player, getNetwork()); @@ -792,7 +795,17 @@ public class Portal { cycleDestination(player, 1); } - public void cycleDestination(Player player, int dir) { + /** + * Cycles destination for a network gate + * + * @param player

The player cycling destinations

+ * @param direction

The direction of the cycle (+1 for next, -1 for previous)

+ */ + public void cycleDestination(Player player, int direction) { + if (direction != 1 && direction != -1) { + throw new IllegalArgumentException("The destination direction must be 1 or -1."); + } + boolean activate = false; if (!isActive() || getActivePlayer() != player) { // If the event is cancelled, return @@ -811,7 +824,7 @@ public class Portal { if (!Stargate.destMemory || !activate || lastDestination.isEmpty()) { int index = destinations.indexOf(destination); - index += dir; + index += direction; if (index >= destinations.size()) index = 0; else if (index < 0) @@ -835,146 +848,7 @@ public class Portal { } Sign sign = (Sign) state; - - //Clear sign - for (int index = 0; index <= 3; index++) { - sign.setLine(index, ""); - } - Stargate.setLine(sign, 0, "-" + name + "-"); - - if (!isActive()) { - //Default sign text - drawInactiveSign(sign); - } else { - if (isBungee()) { - //Bungee sign - drawBungeeSign(sign); - } else if (isFixed()) { - //Sign pointing at one other portal - drawFixedSign(sign); - } else { - //Networking stuff - drawNetworkSign(sign); - } - } - - sign.update(); - } - - /** - * Draws a sign with chooseable network locations - * - * @param sign

The sign to draw on

- */ - private void drawNetworkSign(Sign sign) { - int maxIndex = destinations.size() - 1; - int signLineIndex = 0; - int destinationIndex = destinations.indexOf(destination); - boolean freeGatesGreen = EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen; - - //Last entry, and not only entry. Draw the entry two previously - if ((destinationIndex == maxIndex) && (maxIndex > 1)) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2); - } - //Not first entry. Draw the previous entry - if (destinationIndex > 0) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 1); - } - //Draw the chosen entry (line 2 or 3) - drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex); - //Has another entry and space on the sign - if ((maxIndex >= destinationIndex + 1) && (++signLineIndex <= 3)) { - drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 1); - } - //Has another entry and space on the sign - if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { - drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 2); - } - } - - /** - * Draws the chosen destination on one sign line - * - * @param freeGatesGreen

Whether to display free gates in a green color

- * @param sign

The sign to draw on

- * @param signLineIndex

The line to draw on

- */ - private void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex) { - if (freeGatesGreen) { - Portal destination = PortalHandler.getByName(this.destination, network); - boolean green = Stargate.isFree(activePlayer, this, destination); - Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + this.destination + "<"); - } else { - Stargate.setLine(sign, signLineIndex, " >" + destination + "< "); - } - } - - /** - * Draws one network destination on one sign line - * - * @param freeGatesGreen

Whether to display free gates in a green color

- * @param sign

The sign to draw on

- * @param signLineIndex

The line to draw on

- * @param destinationIndex

The index of the destination to draw

- */ - private void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex) { - if (freeGatesGreen) { - Portal destination = PortalHandler.getByName(destinations.get(destinationIndex), network); - boolean green = Stargate.isFree(activePlayer, this, destination); - Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + destinations.get(destinationIndex)); - } else { - Stargate.setLine(sign, signLineIndex, destinations.get(destinationIndex)); - } - } - - /** - * Draws a bungee sign - * - * @param sign

The sign to draw on

- */ - private void drawBungeeSign(Sign sign) { - Stargate.setLine(sign, 1, Stargate.getString("bungeeSign")); - Stargate.setLine(sign, 2, ">" + destination + "<"); - Stargate.setLine(sign, 3, "[" + network + "]"); - } - - /** - * Draws an inactive sign - * - * @param sign

The sign to draw on

- */ - private void drawInactiveSign(Sign sign) { - Stargate.setLine(sign, 1, Stargate.getString("signRightClick")); - Stargate.setLine(sign, 2, Stargate.getString("signToUse")); - if (!isNoNetwork()) { - Stargate.setLine(sign, 3, "(" + network + ")"); - } else { - Stargate.setLine(sign, 3, ""); - } - } - - /** - * Draws a sign pointing to a fixed location - * - * @param sign

The sign to draw on

- */ - private void drawFixedSign(Sign sign) { - if (isRandom()) { - Stargate.setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); - } else { - Stargate.setLine(sign, 1, ">" + destination + "<"); - } - if (isNoNetwork()) { - Stargate.setLine(sign, 2, ""); - } else { - Stargate.setLine(sign, 2, "(" + network + ")"); - } - Portal destination = PortalHandler.getByName(this.destination, network); - if (destination == null && !isRandom()) { - Stargate.setLine(sign, 3, Stargate.getString("signDisconnected")); - } else { - Stargate.setLine(sign, 3, ""); - } + SignHelper.drawSign(sign, this); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java new file mode 100644 index 0000000..e902770 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -0,0 +1,160 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; +import org.bukkit.ChatColor; +import org.bukkit.block.Sign; + +/** + * This class helps drawing the sign on a portal as it's a bit too complicated to be contained within the portal class + */ +public final class SignHelper { + + /** + * Draws the sign on this portal + */ + public static void drawSign(Sign sign, Portal portal) { + //Clear sign + for (int index = 0; index <= 3; index++) { + sign.setLine(index, ""); + } + Stargate.setLine(sign, 0, "-" + portal.getName() + "-"); + + if (!portal.isActive()) { + //Default sign text + drawInactiveSign(sign, portal); + } else { + if (portal.isBungee()) { + //Bungee sign + drawBungeeSign(sign, portal); + } else if (portal.isFixed()) { + //Sign pointing at one other portal + drawFixedSign(sign, portal); + } else { + //Networking stuff + drawNetworkSign(sign, portal); + } + } + + sign.update(); + } + + /** + * Draws a sign with chooseable network locations + * + * @param sign

The sign to draw on

+ */ + private static void drawNetworkSign(Sign sign, Portal portal) { + int maxIndex = portal.getDestinations().size() - 1; + int signLineIndex = 0; + int destinationIndex = portal.getDestinations().indexOf(portal.getDestinationName()); + boolean freeGatesGreen = EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen; + + //Last entry, and not only entry. Draw the entry two previously + if ((destinationIndex == maxIndex) && (maxIndex > 1)) { + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2, portal); + } + //Not first entry. Draw the previous entry + if (destinationIndex > 0) { + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 1, portal); + } + //Draw the chosen entry (line 2 or 3) + drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex, portal); + //Has another entry and space on the sign + if ((maxIndex >= destinationIndex + 1) && (++signLineIndex <= 3)) { + drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 1, portal); + } + //Has another entry and space on the sign + if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { + drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 2, portal); + } + } + + /** + * Draws the chosen destination on one sign line + * + * @param freeGatesGreen

Whether to display free gates in a green color

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

+ */ + private static void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex, Portal portal) { + if (freeGatesGreen) { + Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); + boolean green = Stargate.isFree(portal.getActivePlayer(), portal, destination); + Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + portal.getDestinationName() + "<"); + } else { + Stargate.setLine(sign, signLineIndex, " >" + portal.getDestinationName() + "< "); + } + } + + /** + * Draws one network destination on one sign line + * + * @param freeGatesGreen

Whether to display free gates in a green color

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

+ * @param destinationIndex

The index of the destination to draw

+ */ + private static void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex, + Portal portal) { + if (freeGatesGreen) { + Portal destination = PortalHandler.getByName(portal.getDestinations().get(destinationIndex), portal.getNetwork()); + boolean green = Stargate.isFree(portal.getActivePlayer(), portal, destination); + Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + portal.getDestinations().get(destinationIndex)); + } else { + Stargate.setLine(sign, signLineIndex, portal.getDestinations().get(destinationIndex)); + } + } + + /** + * Draws a bungee sign + * + * @param sign

The sign to draw on

+ */ + private static void drawBungeeSign(Sign sign, Portal portal) { + Stargate.setLine(sign, 1, Stargate.getString("bungeeSign")); + Stargate.setLine(sign, 2, ">" + portal.getDestinationName() + "<"); + Stargate.setLine(sign, 3, "[" + portal.getNetwork() + "]"); + } + + /** + * Draws an inactive sign + * + * @param sign

The sign to draw on

+ */ + private static void drawInactiveSign(Sign sign, Portal portal) { + Stargate.setLine(sign, 1, Stargate.getString("signRightClick")); + Stargate.setLine(sign, 2, Stargate.getString("signToUse")); + if (!portal.isNoNetwork()) { + Stargate.setLine(sign, 3, "(" + portal.getNetwork() + ")"); + } else { + Stargate.setLine(sign, 3, ""); + } + } + + /** + * Draws a sign pointing to a fixed location + * + * @param sign

The sign to draw on

+ */ + private static void drawFixedSign(Sign sign, Portal portal) { + if (portal.isRandom()) { + Stargate.setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); + } else { + Stargate.setLine(sign, 1, ">" + portal.getDestinationName() + "<"); + } + if (portal.isNoNetwork()) { + Stargate.setLine(sign, 2, ""); + } else { + Stargate.setLine(sign, 2, "(" + portal.getNetwork() + ")"); + } + Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); + if (destination == null && !portal.isRandom()) { + Stargate.setLine(sign, 3, Stargate.getString("signDisconnected")); + } else { + Stargate.setLine(sign, 3, ""); + } + } + +} From 79703e49afb076152506d4959784222b395106f0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 27 Feb 2021 21:15:39 +0100 Subject: [PATCH 064/378] Adds a class which helps with modZ and modX calculations --- .../stargate/utility/DirectionHelper.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java new file mode 100644 index 0000000..eb67b99 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -0,0 +1,37 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.BlockLocation; +import net.knarcraft.stargate.RelativeBlockVector; +import org.bukkit.Location; + +/** + * This class helps with direction-dependent (modX, modZ) calculations + */ +public class DirectionHelper { + + /** + * Gets the block at a relative block vector location + * + * @param vector

The relative block vector

+ * @return

The block at the given relative position

+ */ + public static BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, int modX, int modZ) { + return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); + } + + /** + * Adds a relative block vector to a location, accounting for direction + * @param location

The location to adjust

+ * @param right

The amount of blocks to the right to adjust

+ * @param depth

The amount of blocks upward to adjust

+ * @param distance

The distance outward to adjust

+ * @param modX

The x modifier to use

+ * @param modZ

The z modifier to use

+ * @return

The altered location

+ */ + public static Location adjustLocation(Location location, double right, double depth, double distance, int modX, + int modZ) { + return location.add(-right * modX + distance * modZ, depth, -right * modZ + -distance * modX); + } + +} From ba64572254acfdffd1a419eb90634877a8cc3819 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 27 Feb 2021 21:17:36 +0100 Subject: [PATCH 065/378] Adds more comments, simplifies some code and improves positioning of teleported large entities, like horses --- .../net/knarcraft/stargate/portal/Gate.java | 3 +- .../knarcraft/stargate/portal/GateLayout.java | 6 +- .../net/knarcraft/stargate/portal/Portal.java | 432 ++++++++++++++---- 3 files changed, 359 insertions(+), 82 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index f129ce0..c4fa646 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Material; @@ -271,7 +272,7 @@ public class Gate { * @return

The block at the given relative position

*/ private BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, int modX, int modZ) { - return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); + return DirectionHelper.getBlockAt(topLeft, vector, modX, modZ); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 9876439..ec22c81 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -18,7 +18,7 @@ import java.util.List; public class GateLayout { private Character [][] layout; - private final HashMap exits = new HashMap<>(); + private final List exits = new ArrayList<>(); private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; private RelativeBlockVector[] border = new RelativeBlockVector[0]; private RelativeBlockVector[] controls = new RelativeBlockVector[0]; @@ -78,7 +78,7 @@ public class GateLayout { * * @return

Other possible gate exits

*/ - public HashMap getExits() { + public List getExits() { return exits; } @@ -134,7 +134,7 @@ public class GateLayout { } if (exitDepths[x] > 0) { - this.exits.put(relativeExits[x], x); + this.exits.add(relativeExits[x]); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 36650e0..3515ead 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -9,6 +9,7 @@ import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateOpenEvent; import net.knarcraft.stargate.event.StargatePortalEvent; +import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Axis; @@ -19,6 +20,7 @@ import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Orientable; import org.bukkit.block.data.Powerable; import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; @@ -124,19 +126,6 @@ public class Portal { } } - /** - * Removes the special characters |, : and # from a portal name - * - * @param input

The name to filter

- * @return

The filtered name

- */ - public static String filterName(String input) { - if (input == null) { - return ""; - } - return input.replaceAll("[|:#]", "").trim(); - } - /** * Gets whether this portal is currently open * @@ -238,84 +227,181 @@ public class Portal { return rotX; } + /** + * Gets the axis the portal follows + * + *

If a relative vector's right is not zero, it will move along this axis. + * The axis is used to place the portal's open blocks correctly

+ * + * @return

The axis the portal follows

+ */ public Axis getAxis() { return rot; } + /** + * Gets the player currently using this portal + * + * @return

The player currently using this portal

+ */ public Player getActivePlayer() { return activePlayer; } + /** + * Gets the network this gate belongs to + * + * @return

The network this gate belongs to

+ */ public String getNetwork() { return network; } + /** + * Sets the network this gate belongs to + * + * @param network

The new network for this gate

+ */ public void setNetwork(String network) { this.network = network; } + /** + * Gets the time this portal opened + * + * @return

The time this portal opened

+ */ public long getOpenTime() { return openTime; } + /** + * Gets the name of this portal + * + * @return

The name of this portal

+ */ public String getName() { return name; } + /** + * Sets the name of this portal + * + * @param name

The new name of this portal

+ */ public void setName(String name) { this.name = filterName(name); drawSign(); } + /** + * Gets the destinations of this portal + * + * @return

The destinations of this portal

+ */ public List getDestinations() { return new ArrayList<>(this.destinations); } + /** + * Gets the portal destination given a player + * + * @param player

Used for random gates to determine which destinations are available

+ * @return

The destination portal the player should teleport to

+ */ public Portal getDestination(Player player) { if (isRandom()) { destinations = PortalHandler.getDestinations(this, player, getNetwork()); if (destinations.size() == 0) { return null; } - String dest = destinations.get((new Random()).nextInt(destinations.size())); + String destination = destinations.get((new Random()).nextInt(destinations.size())); destinations.clear(); - return PortalHandler.getByName(dest, getNetwork()); + return PortalHandler.getByName(destination, getNetwork()); } return PortalHandler.getByName(destination, getNetwork()); } + /** + * Gets the portal destination + * + *

If this portal is random, a player should be given to get correct destinations.

+ * + * @return

The portal destination

+ */ public Portal getDestination() { return getDestination(null); } + /** + * Sets the destination of this portal + * + * @param destination

The new destination of this portal

+ */ public void setDestination(Portal destination) { setDestination(destination.getName()); } + /** + * Sets the destination of this portal + * + * @param destination

The new destination of this portal

+ */ public void setDestination(String destination) { this.destination = destination; } + /** + * Gets the name of the destination of this portal + * + * @return

The name of this portal's destination

+ */ public String getDestinationName() { return destination; } + /** + * Gets the gate used by this portal + * + * @return

The gate used by this portal

+ */ public Gate getGate() { return gate; } + /** + * Gets the name of this portal's owner + * + * @return

The name of this portal's owner

+ */ public String getOwnerName() { return ownerName; } + /** + * Gets the UUID of this portal's owner + * + * @return

The UUID of this portal's owner

+ */ public UUID getOwnerUUID() { return ownerUUID; } + /** + * Sets the UUId of this portal's owner + * + * @param owner

The new UUID of this portal's owner

+ */ public void setOwner(UUID owner) { this.ownerUUID = owner; } + /** + * Checks whether a given player is the owner of this portal + * + * @param player

The player to check

+ * @return

True if the player is the owner of this portal

+ */ public boolean isOwner(Player player) { if (this.ownerUUID != null) { return player.getUniqueId().compareTo(this.ownerUUID) == 0; @@ -324,93 +410,134 @@ public class Portal { } } + /** + * Gets the locations of this portal's entrances + * + * @return

The locations of this portal's entrances

+ */ public BlockLocation[] getEntrances() { if (entrances == null) { - RelativeBlockVector[] space = gate.getLayout().getEntrances(); - entrances = new BlockLocation[space.length]; - int i = 0; - - for (RelativeBlockVector vector : space) { - entrances[i++] = getBlockAt(vector); - } + entrances = relativeBlockVectorsToBlockLocations(gate.getLayout().getEntrances()); } return entrances; } + /** + * Gets the locations of this portal's frame + * + * @return

The locations of this portal's frame

+ */ public BlockLocation[] getFrame() { if (frame == null) { - RelativeBlockVector[] border = gate.getLayout().getBorder(); - frame = new BlockLocation[border.length]; - int i = 0; - - for (RelativeBlockVector vector : border) { - frame[i++] = getBlockAt(vector); - } + frame = relativeBlockVectorsToBlockLocations(gate.getLayout().getBorder()); } return frame; } + /** + * Gets the location of this portal's sign + * + * @return

The location of this portal's sign

+ */ public BlockLocation getSign() { return id; } + /** + * Gets the world this portal belongs to + * + * @return

The world this portal belongs to

+ */ public World getWorld() { return world; } + /** + * Gets the location of this portal's button + * + * @return

The location of this portal's button

+ */ public BlockLocation getButton() { return button; } + /** + * Sets the location of this portal's button + * + * @param button

The location of this portal's button

+ */ public void setButton(BlockLocation button) { this.button = button; } + /** + * Open this portal + * + * @param force

Whether to force this portal open, even if it's already open for some player

+ * @return

True if the portal was opened

+ */ public boolean open(boolean force) { return open(null, force); } + /** + * Open this portal + * + * @param force

Whether to force this portal open, even if it's already open for some player

+ * @return

True if the portal was opened

+ */ public boolean open(Player openFor, boolean force) { - // Call the StargateOpenEvent + //Call the StargateOpenEvent StargateOpenEvent event = new StargateOpenEvent(openFor, this, force); Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return false; - } - force = event.getForce(); - - if (isOpen() && !force) { + if (event.isCancelled() || (isOpen() && !event.getForce())) { return false; } + //Change the opening blocks to the correct type Material openType = gate.getPortalOpenBlock(); - Axis axis = openType == Material.NETHER_PORTAL ? rot : null; + Axis axis = (openType.createBlockData() instanceof Orientable) ? rot : null; for (BlockLocation inside : getEntrances()) { Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, axis)); } + updatePortalOpenState(openFor); + return true; + } + + /** + * Updates this portal to be recognized as open and opens its destination portal + * + * @param openFor

The player to open this portal for

+ */ + private void updatePortalOpenState(Player openFor) { + //Update the open state of this portal isOpen = true; openTime = System.currentTimeMillis() / 1000; Stargate.openList.add(this); Stargate.activeList.remove(this); - // Open remote gate + //Open remote portal if (!isAlwaysOn()) { player = openFor; - Portal end = getDestination(); - // Only open dest if it's not-fixed or points at this gate - if (!isRandom() && end != null && (!end.isFixed() || end.getDestinationName().equalsIgnoreCase(getName())) && !end.isOpen()) { - end.open(openFor, false); - end.setDestination(this); - if (end.isVerified()) end.drawSign(); + Portal destination = getDestination(); + // Only open destination if it's not-fixed or points at this portal + if (!isRandom() && destination != null && (!destination.isFixed() || + destination.getDestinationName().equalsIgnoreCase(getName())) && !destination.isOpen()) { + destination.open(openFor, false); + destination.setDestination(this); + if (destination.isVerified()) destination.drawSign(); } } - - return true; } + /** + * Closes this portal + * + * @param force

Whether to force this portal closed, even if it's set as always on

+ */ public void close(boolean force) { if (!isOpen) return; // Call the StargateCloseEvent @@ -427,11 +554,21 @@ public class Portal { Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType)); } + updatePortalClosedState(); + deactivate(); + } + + /** + * Updates this portal to be recognized as closed and closes its destination portal + */ + private void updatePortalClosedState() { + //Update the closed state of this portal player = null; isOpen = false; Stargate.openList.remove(this); Stargate.activeList.remove(this); + //Close remote portal if (!isAlwaysOn()) { Portal end = getDestination(); @@ -440,33 +577,51 @@ public class Portal { end.close(false); } } - - deactivate(); } + /** + * Gets whether this portal is open for the given player + * + * @param player

The player to check portal state for

+ * @return

True if this portal is open to the given player

+ */ public boolean isOpenFor(Player player) { if (!isOpen) { return false; } - if ((isAlwaysOn()) || (this.player == null)) { + if (isAlwaysOn() || this.player == null) { return true; } - return (player != null) && (player.getName().equalsIgnoreCase(this.player.getName())); + return player != null && player.getName().equalsIgnoreCase(this.player.getName()); } /** * Gets whether this portal points to a fixed exit portal * + *

A portal where portals can be chosen from a network is not fixed.

+ * * @return

True if this portal points to a fixed exit portal

*/ public boolean isFixed() { return fixed; } + /** + * Sets whether this portal points to a fixed exit portal + * + *

A portal where portals can be chosen from a network is not fixed.

+ * + * @param fixed

True if this portal points to a fixed exit portal

+ */ public void setFixed(boolean fixed) { this.fixed = fixed; } + /** + * Gets whether at least one of this portal's control blocks are powered + * + * @return

True if at least one control block is powered

+ */ public boolean isPowered() { RelativeBlockVector[] controls = gate.getLayout().getControls(); @@ -521,8 +676,8 @@ public class Portal { /** * Adjusts the rotation of the player to face out from the portal * - * @param entry

The location the player entered from

- * @param exit

The location the player will exit from

+ * @param entry

The location the player entered from

+ * @param exit

The location the player will exit from

* @param origin

The portal the player entered from

*/ private void adjustRotation(Location entry, Location exit, Portal origin) { @@ -573,8 +728,8 @@ public class Portal { /** * Teleport a vehicle which is not a minecart or a boat * - * @param vehicle

The vehicle to teleport

- * @param exit

The location the vehicle will exit

+ * @param vehicle

The vehicle to teleport

+ * @param exit

The location the vehicle will exit

* @param passengers

The passengers of the vehicle

*/ private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { @@ -586,11 +741,11 @@ public class Portal { /** * Creates a new vehicle equal to the player's previous vehicle and * - * @param vehicle

The player's old vehicle

- * @param passengers

A list of all passengers in the vehicle

+ * @param vehicle

The player's old vehicle

+ * @param passengers

A list of all passengers in the vehicle

* @param vehicleWorld

The world to spawn the new vehicle in

- * @param exit

The exit location to spawn the new vehicle on

- * @param newVelocity

The new velocity of the new vehicle

+ * @param exit

The exit location to spawn the new vehicle on

+ * @param newVelocity

The new velocity of the new vehicle

*/ private void putPassengersInNewVehicle(Vehicle vehicle, List passengers, World vehicleWorld, Location exit, Vector newVelocity) { @@ -605,9 +760,9 @@ public class Portal { /** * Ejects, teleports and adds all passengers to the target vehicle * - * @param passengers

The passengers to handle

+ * @param passengers

The passengers to handle

* @param targetVehicle

The vehicle the passengers should be put into

- * @param exit

The exit location to teleport the passengers to

+ * @param exit

The exit location to teleport the passengers to

*/ private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, Location exit) { for (Entity passenger : passengers) { @@ -629,17 +784,86 @@ public class Portal { private Location getExit(Entity entity, Location traveller) { Location exitLocation = null; // Check if the gate has an exit block - if (gate.getLayout().getExit() != null) { - BlockLocation exit = getBlockAt(gate.getLayout().getExit()); + RelativeBlockVector relativeExit = gate.getLayout().getExit(); + if (relativeExit != null) { + BlockLocation exit = getBlockAt(relativeExit); int back = (isBackwards()) ? -1 : 1; - //TODO: Improve positioning to place the entity just far enough from the portal not to suffocate - double entitySize = EntityHelper.getEntityMaxSize(entity); - exitLocation = exit.modRelativeLoc(0D, 0D, entitySize, traveller.getYaw(), + exitLocation = exit.modRelativeLoc(0D, 0D, 1, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); + + double entitySize = EntityHelper.getEntityMaxSize(entity); + if (entitySize > 1) { + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entitySize); + } } else { Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); } + + return adjustExitLocation(traveller, exitLocation); + } + + /** + * Adjusts the positioning of the portal exit to prevent the given entity from suffocating + * + * @param relativeExit

The relative exit defined as the portal's exit

+ * @param exitLocation

The currently calculated portal exit

+ * @param entitySize

The size of the travelling entity

+ * @return

A location which won't suffocate the entity inside the portal

+ */ + private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, double entitySize) { + //Go left to find start of opening + RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); + + //Go right to find the end of the opening + RelativeBlockVector openingRight = getPortalExitEdge(relativeExit, 1); + + //Get the width to check if the entity fits + int openingWidth = openingRight.getRight() - openingLeft.getRight() + 1; + int existingOffset = relativeExit.getRight() - openingLeft.getRight(); + double newOffset = (openingWidth - existingOffset) / 2D; + + //Remove the half offset for better centering + if (openingWidth > 1) { + newOffset -= 0.5; + } + exitLocation = DirectionHelper.adjustLocation(exitLocation, newOffset, 0, 0, modX, modZ); + if (entitySize > openingWidth) { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D), modX, modZ); + } + + return exitLocation; + } + + /** + * Gets one of the edges of a portal's opening/exit + * + * @param relativeExit

The known exit to start from

+ * @param direction

The direction to move (+1 for right, -1 for left)

+ * @return

The right or left edge of the opening

+ */ + private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { + RelativeBlockVector openingEdge = relativeExit; + do { + RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, + openingEdge.getDepth(), openingEdge.getDistance()); + if (gate.getLayout().getExits().contains(possibleOpening)) { + openingEdge = possibleOpening; + } else { + break; + } + } while (true); + return openingEdge; + } + + /** + * Adjusts an exit location with rotation and slab height incrementation + * + * @param traveller

The location of the travelling entity

+ * @param exitLocation

The exit location generated

+ * @return

The location the travelling entity should be teleported to

+ */ + private Location adjustExitLocation(Location traveller, Location exitLocation) { if (exitLocation != null) { //Prevent traveller from spawning inside a slab BlockData blockData = getWorld().getBlockAt(exitLocation).getBlockData(); @@ -741,7 +965,7 @@ public class Portal { * @param player

The player to activate the portal for

* @return

True if the portal was activated

*/ - public boolean activate(Player player) { + private boolean activate(Player player) { destinations.clear(); destination = ""; Stargate.activeList.add(this); @@ -787,10 +1011,20 @@ public class Portal { drawSign(); } + /** + * Gets whether this portal is active + * + * @return

Whether this portal is active

+ */ public boolean isActive() { return isFixed() || (destinations.size() > 0); } + /** + * Cycles destination for a network gate forwards + * + * @param player

The player to cycle the gate for

+ */ public void cycleDestination(Player player) { cycleDestination(player, 1); } @@ -798,7 +1032,7 @@ public class Portal { /** * Cycles destination for a network gate * - * @param player

The player cycling destinations

+ * @param player

The player cycling destinations

* @param direction

The direction of the cycle (+1 for next, -1 for previous)

*/ public void cycleDestination(Player player, int direction) { @@ -808,7 +1042,7 @@ public class Portal { boolean activate = false; if (!isActive() || getActivePlayer() != player) { - // If the event is cancelled, return + //If the stargate activate event is cancelled, return if (!activate(player)) { return; } @@ -823,19 +1057,32 @@ public class Portal { } if (!Stargate.destMemory || !activate || lastDestination.isEmpty()) { - int index = destinations.indexOf(destination); - index += direction; - if (index >= destinations.size()) - index = 0; - else if (index < 0) - index = destinations.size() - 1; - destination = destinations.get(index); - lastDestination = destination; + cycleDestination(direction); } openTime = System.currentTimeMillis() / 1000; drawSign(); } + /** + * Performs the actual destination cycling with no input checks + * + * @param direction

The direction of the cycle (+1 for next, -1 for previous)

+ */ + private void cycleDestination(int direction) { + int index = destinations.indexOf(destination); + index += direction; + + //Wrap around + if (index >= destinations.size()) { + index = 0; + } else if (index < 0) { + index = destinations.size() - 1; + } + //Store selected destination + destination = destinations.get(index); + lastDestination = destination; + } + /** * Draws the sign on this portal */ @@ -857,8 +1104,37 @@ public class Portal { * @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); + public BlockLocation getBlockAt(RelativeBlockVector vector) { + return DirectionHelper.getBlockAt(topLeft, vector, modX, modZ); + } + + /** + * Removes the special characters |, : and # from a portal name + * + * @param input

The name to filter

+ * @return

The filtered name

+ */ + private static String filterName(String input) { + if (input == null) { + return ""; + } + return input.replaceAll("[|:#]", "").trim(); + } + + /** + * Gets a list of block locations from a list of relative block vectors + * + * @param vectors

The relative block vectors to convert

+ * @return

A list of block locations

+ */ + private BlockLocation[] relativeBlockVectorsToBlockLocations(RelativeBlockVector[] vectors) { + BlockLocation[] locations = new BlockLocation[vectors.length]; + int i = 0; + + for (RelativeBlockVector vector : vectors) { + locations[i++] = getBlockAt(vector); + } + return locations; } @Override From da32cf11d19142e40bf3bd7f92a4146f1ca1d406 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 27 Feb 2021 22:34:10 +0100 Subject: [PATCH 066/378] Fixes some things regarding vehicle teleportation Adds extra space between the portal and the vehicle if the destination portal is always on Fixes a bug causing vehicles not being detected soon enough Fixes boats facing into the portal rather than out from the portal Fixes boats spawning inside water rather than on top of it if water is in front of a portal --- .../listener/EntityEventListener.java | 2 +- .../listener/PlayerEventsListener.java | 3 ++- .../listener/VehicleEventListener.java | 11 ++++---- .../net/knarcraft/stargate/portal/Portal.java | 26 ++++++++++++++----- .../stargate/utility/DirectionHelper.java | 6 ++++- .../stargate/utility/EntityHelper.java | 14 ++++++++-- 6 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 700b90a..6fdeab6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -30,7 +30,7 @@ public class EntityEventListener implements Listener { } Entity entity = event.getEntity(); - if (PortalHandler.getByAdjacentEntrance(event.getFrom(), (int) EntityHelper.getEntityMaxSize(entity)) != null) { + if (PortalHandler.getByAdjacentEntrance(event.getFrom(), EntityHelper.getEntityMaxSizeInt(entity)) != null) { event.setCancelled(true); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 6673fd2..108470a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -91,7 +91,8 @@ public class PlayerEventsListener implements Listener { !(playerVehicle instanceof Boat)) { Portal destinationPortal = portal.getDestination(); if (destinationPortal != null) { - VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer()); + VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, + event.getPlayer(), portal); } } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index db71f90..b45c834 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -26,9 +26,10 @@ public class VehicleEventListener implements Listener { * @param vehicle

The vehicle to teleport

* @param destinationPortal

The portal the player teleported to

* @param player

The player who teleported

+ * @param origin

The portal the player entered

*/ - public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player) { - destinationPortal.teleport(vehicle); + public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player, Portal origin) { + destinationPortal.teleport(vehicle, origin); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6); } @@ -46,7 +47,7 @@ public class VehicleEventListener implements Listener { Vehicle vehicle = event.getVehicle(); Portal entrancePortal; - int entitySize = (int) EntityHelper.getEntityMaxSize(vehicle); + int entitySize = EntityHelper.getEntityMaxSizeInt(vehicle); if (EntityHelper.getEntityMaxSize(vehicle) > 1) { entrancePortal = PortalHandler.getByAdjacentEntrance(event.getTo(), entitySize - 1); } else { @@ -79,7 +80,7 @@ public class VehicleEventListener implements Listener { Stargate.log.warning(Stargate.getString("prefox") + "Unable to find portal destination"); return; } - destinationPortal.teleport(vehicle); + destinationPortal.teleport(vehicle, entrancePortal); } } @@ -118,7 +119,7 @@ public class VehicleEventListener implements Listener { } Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - destinationPortal.teleport(vehicle); + destinationPortal.teleport(vehicle, entrancePortal); entrancePortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 3515ead..9962413 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -692,11 +692,14 @@ public class Portal { * Teleports a vehicle to this portal * * @param vehicle

The vehicle to teleport

+ * @param origin

The portal the vehicle entered

*/ - public void teleport(final Vehicle vehicle) { + public void teleport(final Vehicle vehicle, Portal origin) { Location traveller = vehicle.getLocation(); Location exit = getExit(vehicle, traveller); + adjustRotation(traveller, exit, origin); + double velocity = vehicle.getVelocity().length(); // Stop and teleport @@ -793,13 +796,12 @@ public class Portal { double entitySize = EntityHelper.getEntityMaxSize(entity); if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entitySize); + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); } } else { Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); } - return adjustExitLocation(traveller, exitLocation); } @@ -808,10 +810,10 @@ public class Portal { * * @param relativeExit

The relative exit defined as the portal's exit

* @param exitLocation

The currently calculated portal exit

- * @param entitySize

The size of the travelling entity

+ * @param entity

The travelling entity

* @return

A location which won't suffocate the entity inside the portal

*/ - private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, double entitySize) { + private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { //Go left to find start of opening RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); @@ -828,8 +830,16 @@ public class Portal { newOffset -= 0.5; } exitLocation = DirectionHelper.adjustLocation(exitLocation, newOffset, 0, 0, modX, modZ); - if (entitySize > openingWidth) { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D), modX, modZ); + + //Move large entities further from the portal, especially if this portal will teleport them at once + double entitySize = EntityHelper.getEntityMaxSize(entity); + int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); + if (entitySize > 1) { + if (isAlwaysOn()) { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entityBoxSize / 2D), modX, modZ); + } else { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D) - 1, modX, modZ); + } } return exitLocation; @@ -869,6 +879,8 @@ public class Portal { BlockData blockData = getWorld().getBlockAt(exitLocation).getBlockData(); if (blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) { exitLocation.add(0, 0.5, 0); + } else if (blockData.getMaterial() == Material.WATER) { + exitLocation.add(0, 1, 0); } exitLocation.setPitch(traveller.getPitch()); diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index eb67b99..8c0c966 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -7,7 +7,11 @@ import org.bukkit.Location; /** * This class helps with direction-dependent (modX, modZ) calculations */ -public class DirectionHelper { +public final class DirectionHelper { + + private DirectionHelper() { + + } /** * Gets the block at a relative block vector location diff --git a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java index 2fd3342..157eb3c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java @@ -18,10 +18,20 @@ public final class EntityHelper { * contain the entity.

* * @param entity

The entity to get max size for

- * @return

+ * @return

The max size of the entity

+ */ + public static int getEntityMaxSizeInt(Entity entity) { + return (int) Math.ceil((float) getEntityMaxSize(entity)); + } + + /** + * Gets the max size of an entity along its x and z axis + * + * @param entity

The entity to get max size for

+ * @return

The max size of the entity

*/ public static double getEntityMaxSize(Entity entity) { - return Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ())); + return Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ()); } } From 504ef1b52f1ce2477f62a1a05c29d0c3defd8262 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 27 Feb 2021 22:50:44 +0100 Subject: [PATCH 067/378] Adds remaining missing comments to Portal --- .../net/knarcraft/stargate/portal/Portal.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 9962413..f252002 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -910,14 +910,29 @@ public class Portal { return this.id; } + /** + * Gets the x modifier used by this portal + * + * @return

The x modifier used by this portal

+ */ public int getModX() { return this.modX; } + /** + * Gets the z modifier used by this portal + * + * @return

The z modifier used by this portal

+ */ public int getModZ() { return this.modZ; } + /** + * Gets the rotation of this portal + * + * @return

The rotation of this portal

+ */ public float getRotX() { return this.rotX; } From 44dfa2a10d3b76ecf7fdfe391b74a2bc2c2bdbca Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 28 Feb 2021 21:53:27 +0100 Subject: [PATCH 068/378] Greatly refactors gate loading --- .../net/knarcraft/stargate/portal/Gate.java | 6 +- .../stargate/portal/GateHandler.java | 296 ++++++++++++------ .../knarcraft/stargate/portal/GateLayout.java | 1 - 3 files changed, 210 insertions(+), 93 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index c4fa646..cd1afb4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -23,7 +23,7 @@ public class Gate { private final String filename; private final GateLayout layout; - private final HashMap types; + private final Map types; //Gate materials private Material portalOpenBlock; @@ -50,7 +50,7 @@ public class Gate { * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

* @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

*/ - public Gate(String filename, GateLayout layout, HashMap types, Material portalOpenBlock, + public Gate(String filename, GateLayout layout, Map types, Material portalOpenBlock, Material portalClosedBlock, Material portalButton, int useCost, int createCost, int destroyCost, boolean toOwner) { this.filename = filename; @@ -79,7 +79,7 @@ public class Gate { * * @return

The material types each layout character represents

*/ - public HashMap getTypes() { + public Map getTypes() { return types; } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 521838c..5e62635 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -10,7 +10,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Scanner; +import java.util.Set; import java.util.logging.Level; /** @@ -72,7 +74,12 @@ public class GateHandler { return CONTROL_BLOCK; } - public static void registerGate(Gate gate) { + /** + * Register a gate into the list of available gates + * + * @param gate

The gate to register

+ */ + private static void registerGate(Gate gate) { gates.put(gate.getFilename(), gate); Material blockID = gate.getControlBlock(); @@ -84,7 +91,13 @@ public class GateHandler { controlBlocks.get(blockID).add(gate); } - public static Gate loadGate(File file) { + /** + * Loads a gate + * + * @param file

The file containing the gate's layout

+ * @return

The loaded gate or null if unable to load the gate

+ */ + private static Gate loadGate(File file) { try (Scanner scanner = new Scanner(file)) { return loadGate(file.getName(), file.getParent(), scanner); } catch (Exception ex) { @@ -93,88 +106,56 @@ public class GateHandler { } } - public static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { - boolean designing = false; + /** + * Loads a gate + * + * @param fileName

The name of the file containing the gate layout

+ * @param parentFolder

The parent folder of the layout file

+ * @param scanner

The scanner to use for reading the gate layout

+ * @return

The loaded gate or null if unable to load the gate

+ */ + private static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { List> design = new ArrayList<>(); - HashMap types = new HashMap<>(); - HashMap config = new HashMap<>(); - HashSet frameTypes = new HashSet<>(); - int cols = 0; + Map types = new HashMap<>(); + Map config = new HashMap<>(); + Set frameTypes = new HashSet<>(); - // Init types map + //Initialize types map types.put(ENTRANCE, Material.AIR); types.put(EXIT, Material.AIR); types.put(ANYTHING, Material.AIR); - try { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - - if (designing) { - List row = new ArrayList<>(); - - if (line.length() > cols) { - cols = line.length(); - } - - for (Character symbol : line.toCharArray()) { - if ((symbol.equals('?')) || (!types.containsKey(symbol))) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); - return null; - } - row.add(symbol); - } - - design.add(row); - } else { - if (!line.isEmpty() && !line.startsWith("#")) { - String[] split = line.split("="); - String key = split[0].trim(); - String value = split[1].trim(); - - if (key.length() == 1) { - Character symbol = key.charAt(0); - Material id = Material.getMaterial(value); - if (id == null) { - throw new Exception("Invalid material in line: " + line); - } - types.put(symbol, id); - frameTypes.add(id); - } else { - config.put(key, value); - } - } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { - designing = true; - } - } - } - } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + //Read the file into appropriate lists and maps + int cols = readGateFile(scanner, types, fileName, design, frameTypes, config); + if (cols < 0) { + return null; + } + Character[][] layout = generateLayoutMatrix(design, cols); + + //Create and validate the new gate + Gate gate = createGate(config, fileName, layout, types); + if (gate == null) { return null; - } finally { - if (scanner != null) { - scanner.close(); - } } - Character[][] layout = new Character[design.size()][cols]; + //Update list of all frame blocks + frameBlocks.addAll(frameTypes); - //y = relative line number of layout file - for (int y = 0; y < design.size(); y++) { - List row = design.get(y); - Character[] result = new Character[cols]; - - for (int x = 0; x < cols; x++) { - if (x < row.size()) { - result[x] = row.get(x); - } else { - result[x] = ' '; - } - } - - layout[y] = result; - } + gate.save(parentFolder + "/"); // Updates format for version changes + return gate; + } + /** + * Creates a new gate + * + * @param config

The config map to get configuration values from

+ * @param fileName

The name of the saved gate config file

+ * @param layout

The layout matrix of the new gate

+ * @param types

The mapping for used gate material types

+ * @return

A new gate or null if the config is invalid

+ */ + private static Gate createGate(Map config, String fileName, Character[][] layout, + Map types) { Material portalOpenBlock = readConfig(config, fileName, "portal-open", defaultPortalBlockOpen); Material portalClosedBlock = readConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); Material portalButton = readConfig(config, fileName, "button", defaultButton); @@ -186,26 +167,163 @@ public class GateHandler { Gate gate = new Gate(fileName, new GateLayout(layout), types, portalOpenBlock, portalClosedBlock, portalButton, useCost, createCost, destroyCost, toOwner); - - - if (gate.getLayout().getControls().length != 2) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); + if (!validateGate(gate, fileName)) { return null; } - - if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); - return null; - } - - // Merge frame types, add open mat to list - frameBlocks.addAll(frameTypes); - - gate.save(parentFolder + "/"); // Updates format for version changes return gate; } - private static int readConfig(HashMap config, String fileName, String key, int defaultInteger) { + /** + * Validate that a gate is valid + * + * @param gate

The gate to validate

+ * @param fileName

The filename of the loaded gate file

+ * @return

True if the gate is valid. False otherwise

+ */ + private static boolean validateGate(Gate gate, String fileName) { + if (gate.getLayout().getControls().length != 2) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + + " - Gates must have exactly 2 control points."); + return false; + } + + if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + + " - Gate button must be a type of button."); + return false; + } + return true; + } + + /** + * Generates a matrix storing the gate layout + * + * @param design

The design of the gate layout

+ * @param cols

The largest amount of columns in the design

+ * @return

A matrix containing the gate's layout

+ */ + private static Character[][] generateLayoutMatrix(List> design, int cols) { + Character[][] layout = new Character[design.size()][cols]; + for (int lineIndex = 0; lineIndex < design.size(); lineIndex++) { + List row = design.get(lineIndex); + Character[] result = new Character[cols]; + + for (int rowIndex = 0; rowIndex < cols; rowIndex++) { + if (rowIndex < row.size()) { + result[rowIndex] = row.get(rowIndex); + } else { + //Add spaces to all lines which are too short + result[rowIndex] = ' '; + } + } + + layout[lineIndex] = result; + } + return layout; + } + + /** + * Reads the gate file + * + * @param scanner

The scanner to read from

+ * @param types

The map of characters to store valid symbols in

+ * @param fileName

The filename of the loaded gate config file

+ * @param design

The list to store the loaded design to

+ * @param frameTypes

The set of gate frame types to store to

+ * @param config

The map of config values to store to

+ * @return

The column count/width of the loaded gate

+ */ + private static int readGateFile(Scanner scanner, Map types, String fileName, + List> design, Set frameTypes, Map config) { + boolean designing = false; + int cols = 0; + try { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + + if (designing) { + cols = readGateDesignLine(line, cols, types, fileName, design); + if (cols < 0) { + return -1; + } + } else { + if (!line.isEmpty() && !line.startsWith("#")) { + readGateConfigValue(line, types, frameTypes, config); + } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { + designing = true; + } + } + } + } catch (Exception ex) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + return -1; + } finally { + if (scanner != null) { + scanner.close(); + } + } + return cols; + } + + /** + * Reads one design line of the gate layout file + * + * @param line

The line to read

+ * @param cols

The current max columns value of the design

+ * @param types

The map of characters to check for valid symbols

+ * @param fileName

The filename of the loaded gate config file

+ * @param design

The list to store the loaded design to

+ * @return

The new max columns value of the design

+ */ + private static int readGateDesignLine(String line, int cols, Map types, String fileName, + List> design) { + List row = new ArrayList<>(); + + if (line.length() > cols) { + cols = line.length(); + } + + for (Character symbol : line.toCharArray()) { + if ((symbol.equals('?')) || (!types.containsKey(symbol))) { + Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); + return -1; + } + row.add(symbol); + } + + design.add(row); + return cols; + } + + /** + * Reads one config value from the gate layout file + * + * @param line

The line to read

+ * @param types

The map of characters to materials to store to

+ * @param frameTypes

The set of gate frame types to store to

+ * @param config

The map of config values to store to

+ * @throws Exception

If an invalid material is encountered

+ */ + private static void readGateConfigValue(String line, Map types, Set frameTypes, + Map config) throws Exception { + String[] split = line.split("="); + String key = split[0].trim(); + String value = split[1].trim(); + + if (key.length() == 1) { + Character symbol = key.charAt(0); + Material id = Material.getMaterial(value); + if (id == null) { + throw new Exception("Invalid material in line: " + line); + } + types.put(symbol, id); + frameTypes.add(id); + } else { + config.put(key, value); + } + } + + private static int readConfig(Map config, String fileName, String key, int defaultInteger) { if (config.containsKey(key)) { try { return Integer.parseInt(config.get(key)); @@ -226,7 +344,7 @@ public class GateHandler { * @param defaultMaterial

The default material to use, in case the config is invalid

* @return

The material to use

*/ - private static Material readConfig(HashMap config, String fileName, String key, Material defaultMaterial) { + private static Material readConfig(Map config, String fileName, String key, Material defaultMaterial) { if (config.containsKey(key)) { Material material = Material.getMaterial(config.get(key)); if (material != null) { diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index ec22c81..dfb5ab2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -5,7 +5,6 @@ import net.knarcraft.stargate.RelativeBlockVector; import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; /** From b1aa53c1a9fa75add654409d2fcd19417d338367 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 2 Mar 2021 17:55:14 +0100 Subject: [PATCH 069/378] Adds missing comments to BlockPopulatorThread and make end gateways teleport entities back to itself to prevent strange behavior Because of the teleport change, end gateways work to teleport player, and end gateways work to the end for vehicles, but vehicles cannot teleport back from the end --- .../stargate/thread/BlockPopulatorThread.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java index a37547b..61be215 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java @@ -8,27 +8,42 @@ import org.bukkit.block.Block; import org.bukkit.block.EndGateway; import org.bukkit.block.data.Orientable; +/** + * This thread changes gate blocks to display a gate as open or closed + * + *

This thread fetches some entries from blockPopulatorQueue each time it's called.

+ */ public class BlockPopulatorThread implements Runnable { + + @Override public void run() { long sTime = System.nanoTime(); + //Repeat for at most 0.025 seconds while (System.nanoTime() - sTime < 25000000) { + //Abort if there's no work to be done BloxPopulator bloxPopulator = Stargate.blockPopulatorQueue.poll(); if (bloxPopulator == null) { return; } + + //Change the material of the pulled block Block block = bloxPopulator.getBlockLocation().getBlock(); block.setType(bloxPopulator.getMaterial(), false); - if (bloxPopulator.getMaterial() == Material.END_GATEWAY && block.getWorld().getEnvironment() == World.Environment.THE_END) { - // force a location to prevent exit gateway generation + + if (bloxPopulator.getMaterial() == Material.END_GATEWAY && + block.getWorld().getEnvironment() == World.Environment.THE_END) { + //Force a specific location to prevent exit gateway generation EndGateway gateway = (EndGateway) block.getState(); - gateway.setExitLocation(block.getWorld().getSpawnLocation()); + gateway.setExitLocation(block.getLocation()); gateway.setExactTeleport(true); gateway.update(false, false); } else if (bloxPopulator.getAxis() != null) { + //If orientation is relevant, adjust the block's orientation Orientable orientable = (Orientable) block.getBlockData(); orientable.setAxis(bloxPopulator.getAxis()); block.setBlockData(orientable); } } } + } From 0fe2a5b38006bc0a8a827b2850b1b5eb4b099a62 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 11 Jun 2021 20:46:14 +0200 Subject: [PATCH 070/378] Adds some more fixes and improvements for vehicle teleportation --- .../net/knarcraft/stargate/BloxPopulator.java | 12 ------ .../listener/VehicleEventListener.java | 1 + .../stargate/portal/GateHandler.java | 2 +- .../knarcraft/stargate/portal/GateLayout.java | 12 ++++++ .../net/knarcraft/stargate/portal/Portal.java | 38 +++++++++++++------ .../stargate/portal/PortalDirection.java | 7 ++++ .../stargate/portal/GateLayoutTest.java | 3 +- 7 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalDirection.java diff --git a/src/main/java/net/knarcraft/stargate/BloxPopulator.java b/src/main/java/net/knarcraft/stargate/BloxPopulator.java index 130cf94..a375762 100644 --- a/src/main/java/net/knarcraft/stargate/BloxPopulator.java +++ b/src/main/java/net/knarcraft/stargate/BloxPopulator.java @@ -12,18 +12,6 @@ public class BloxPopulator { private Material nextMat; private Axis nextAxis; - /** - * Instantiates a new block populator - * - * @param blockLocation

The location to start from

- * @param material

The material to populate

- */ - public BloxPopulator(BlockLocation blockLocation, Material material) { - this.blockLocation = blockLocation; - nextMat = material; - nextAxis = null; - } - /** * Instantiates a new block populator * diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index b45c834..8ab5b3a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -80,6 +80,7 @@ public class VehicleEventListener implements Listener { Stargate.log.warning(Stargate.getString("prefox") + "Unable to find portal destination"); return; } + Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getId()); destinationPortal.teleport(vehicle, entrancePortal); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 5e62635..1e47965 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -391,7 +391,7 @@ public class GateHandler { * * @param gateFolder

The folder containing gate config files

*/ - public static void populateDefaults(String gateFolder) { + private static void populateDefaults(String gateFolder) { loadGateFromJar("nethergate.gate", gateFolder); loadGateFromJar("watergate.gate", gateFolder); } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index dfb5ab2..c0a103f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -33,6 +33,18 @@ public class GateLayout { readLayout(); } + /** + * Gets two of the corners of the gate layout creating the smallest box the gate can be contained within + * + * @return

Two of the gate's corners

+ */ + public RelativeBlockVector[] getCorners() { + return new RelativeBlockVector[] { + new RelativeBlockVector(0, 0, 0), + new RelativeBlockVector(layout[0].length - 1, layout.length - 1, 1) + }; + } + /** * Gets the character array describing this layout * diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index f252002..2b816d8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -13,6 +13,7 @@ import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Axis; +import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -38,6 +39,9 @@ import java.util.Random; import java.util.UUID; import java.util.logging.Level; +/** + * This class represents a portal in space which points to one or several other portals + */ public class Portal { // Gate location block info @@ -54,6 +58,7 @@ public class Portal { private BlockLocation button; private BlockLocation[] frame; private BlockLocation[] entrances; + // Gate information private String name; private String destination; @@ -551,7 +556,7 @@ public class Portal { // Close this gate, then the dest gate. Material closedType = gate.getPortalClosedBlock(); for (BlockLocation inside : getEntrances()) { - Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType)); + Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType, null)); } updatePortalClosedState(); @@ -663,6 +668,8 @@ public class Portal { exit = stargatePortalEvent.getExit(); } + loadChunks(); + // If no event is passed in, assume it's a teleport, and act as such if (event == null) { exit.setYaw(this.getRotation()); @@ -698,8 +705,6 @@ public class Portal { Location traveller = vehicle.getLocation(); Location exit = getExit(vehicle, traveller); - adjustRotation(traveller, exit, origin); - double velocity = vehicle.getVelocity().length(); // Stop and teleport @@ -707,7 +712,10 @@ public class Portal { // Get new velocity final Vector newVelocity = new Vector(modX, 0.0F, modZ); + //-z + Stargate.debug("teleport", modX + " " + modZ); newVelocity.multiply(velocity); + adjustRotation(traveller, exit, origin); List passengers = vehicle.getPassengers(); World vehicleWorld = exit.getWorld(); @@ -716,6 +724,8 @@ public class Portal { return; } + loadChunks(); + if (!passengers.isEmpty()) { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { putPassengersInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); @@ -770,6 +780,7 @@ public class Portal { private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, Location exit) { for (Entity passenger : passengers) { passenger.eject(); + //TODO: Fix random java.lang.IllegalStateException: Removing entity while ticking! if (!passenger.teleport(exit)) { Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); } @@ -794,9 +805,11 @@ public class Portal { exitLocation = exit.modRelativeLoc(0D, 0D, 1, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); - double entitySize = EntityHelper.getEntityMaxSize(entity); - if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); + if (entity != null) { + double entitySize = EntityHelper.getEntityMaxSize(entity); + if (entitySize > 1) { + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); + } } } else { Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); @@ -892,13 +905,16 @@ public class Portal { } /** - * Checks whether the chunk the portal is located at is loaded - * - * @return

True if the chunk containing the portal is loaded

+ * Loads the chunks at the portal's corners */ - public boolean isChunkLoaded() { + public void loadChunks() { //TODO: Improve this in the case where the portal sits between two chunks - return getWorld().isChunkLoaded(topLeft.getBlock().getChunk()); + for (RelativeBlockVector vector : gate.getLayout().getCorners()) { + Chunk chunk = getBlockAt(vector).getChunk(); + if (!getWorld().isChunkLoaded(chunk)) { + chunk.load(); + } + } } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java b/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java new file mode 100644 index 0000000..f509e21 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java @@ -0,0 +1,7 @@ +package net.knarcraft.stargate.portal; + +public class PortalDirection { + + + +} diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 537df09..94afc86 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -15,7 +15,6 @@ import be.seeseemelk.mockbukkit.MockBukkit; import java.util.ArrayList; import java.util.List; -import java.util.Set; public class GateLayoutTest { @@ -40,7 +39,7 @@ public class GateLayoutTest { expected.add(new RelativeBlockVector(1, 3, 0)); expected.add(new RelativeBlockVector(2, 3, 0)); - Set exits = layout.getExits().keySet(); + List exits = layout.getExits(); exits.forEach((blockVector) -> assertTrue(expected.contains(blockVector))); } From 75fbd44af7fec95bd0344cf23a5410f298a8084c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 2 Sep 2021 00:31:03 +0200 Subject: [PATCH 071/378] Removes an s in class name of PlayerEventsListener --- src/main/java/net/knarcraft/stargate/Stargate.java | 4 ++-- ...{PlayerEventsListener.java => PlayerEventListener.java} | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) rename src/main/java/net/knarcraft/stargate/listener/{PlayerEventsListener.java => PlayerEventListener.java} (98%) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 5037c61..ded5f53 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -6,7 +6,7 @@ import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; -import net.knarcraft.stargate.listener.PlayerEventsListener; +import net.knarcraft.stargate.listener.PlayerEventListener; import net.knarcraft.stargate.listener.PluginEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; @@ -535,7 +535,7 @@ public class Stargate extends JavaPlugin { log.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); // Register events before loading gates to stop weird things happening. - pm.registerEvents(new PlayerEventsListener(), this); + pm.registerEvents(new PlayerEventListener(), this); pm.registerEvents(new BlockEventListener(), this); pm.registerEvents(new VehicleEventListener(), this); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java rename to src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 108470a..298464a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -31,7 +31,7 @@ import java.util.Objects; * This listener listens to any player-related events related to stargates */ @SuppressWarnings("unused") -public class PlayerEventsListener implements Listener { +public class PlayerEventListener implements Listener { private static long eventTime; private static PlayerInteractEvent previousEvent; @@ -208,10 +208,7 @@ public class PlayerEventsListener implements Listener { * @return

True if the player should be denied

*/ private boolean cannotAccessPortal(Player player, Portal portal) { - boolean deny = false; - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - deny = true; - } + boolean deny = !Stargate.canAccessNetwork(player, portal.getNetwork()); if (!Stargate.canAccessPortal(player, portal, deny)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); From daa3c6f8680fc9f6dad39b1dbe797c25a7e215cb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 9 Sep 2021 15:25:08 +0200 Subject: [PATCH 072/378] Cleans up a bit and changes to compile for java 16 and spigot 1.17 --- pom.xml | 16 +++++++++++----- .../knarcraft/stargate/RelativeBlockVector.java | 6 +++--- .../java/net/knarcraft/stargate/Stargate.java | 10 +++++----- .../java/net/knarcraft/stargate/TwoTuple.java | 4 ++-- .../stargate/command/CommandReload.java | 2 +- .../stargate/command/CommandStarGate.java | 2 +- .../stargate/listener/BungeeCordListener.java | 2 +- .../java/net/knarcraft/stargate/portal/Gate.java | 10 +++++----- .../knarcraft/stargate/portal/GateHandler.java | 8 ++++---- .../knarcraft/stargate/portal/GateLayout.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 4 ++-- .../knarcraft/stargate/portal/PortalHandler.java | 2 +- .../stargate/portal/GateLayoutTest.java | 3 +-- 13 files changed, 38 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index f7d86c3..c4063b2 100644 --- a/pom.xml +++ b/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.8 - 1.8 + 16 + 16 @@ -33,7 +33,7 @@ org.spigotmc spigot-api - 1.16.5-R0.1-SNAPSHOT + 1.17.1-R0.1-SNAPSHOT net.milkbowl.vault @@ -48,8 +48,8 @@ com.github.seeseemelk - MockBukkit-v1.16 - 0.24.0 + MockBukkit-v1.17 + 1.7.0 test @@ -58,6 +58,12 @@ 19.0.0 compile + + junit + junit + 4.13.1 + test + diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java index 8bf2624..15c17ab 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java @@ -10,9 +10,9 @@ package net.knarcraft.stargate; */ public class RelativeBlockVector { - private int right; - private int depth; - private int distance; + private final int right; + private final int depth; + private final int distance; /** * Instantiates a new relative block vector diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index ded5f53..23cfe82 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -67,13 +67,13 @@ public class Stargate extends JavaPlugin { // Used for debug public static boolean debug = false; public static boolean permDebug = false; - public static ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); + public static final ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); // Used for populating gate open/closed material. - public static Queue blockPopulatorQueue = new LinkedList<>(); + public static final Queue blockPopulatorQueue = new LinkedList<>(); // HashMap of player names for Bungee support - public static Map bungeeQueue = new HashMap<>(); + public static final Map bungeeQueue = new HashMap<>(); // World names that contain stargates - public static HashSet managedWorlds = new HashSet<>(); + public static final HashSet managedWorlds = new HashSet<>(); private static String pluginVersion; private static String portalFolder; private static String gateFolder; @@ -656,7 +656,7 @@ public class Stargate extends JavaPlugin { File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); if (!newFile.exists()) { if (!newFile.getParentFile().mkdirs()) { - log.severe("Unable to create portal directory"); + log.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); } } } diff --git a/src/main/java/net/knarcraft/stargate/TwoTuple.java b/src/main/java/net/knarcraft/stargate/TwoTuple.java index 6167fac..438590d 100644 --- a/src/main/java/net/knarcraft/stargate/TwoTuple.java +++ b/src/main/java/net/knarcraft/stargate/TwoTuple.java @@ -8,8 +8,8 @@ package net.knarcraft.stargate; */ public class TwoTuple { - private K firstValue; - private L secondValue; + private final K firstValue; + private final L secondValue; /** * Instantiate a new TwoTuple diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index 3147062..2d4ea4d 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull; */ public class CommandReload implements CommandExecutor { - private Stargate plugin; + private final Stargate plugin; /** * Instantiates the reload command diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index bcc86ab..182e4c8 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; */ public class CommandStarGate implements CommandExecutor { - private Stargate plugin; + private final Stargate plugin; /** * Instantiates the stargate command diff --git a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java index 700fda4..0d58dda 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java @@ -23,7 +23,7 @@ public class BungeeCordListener implements PluginMessageListener { * @param message

The message received from the plugin

*/ @Override - public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, @NotNull byte[] message) { + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, byte[] message) { //Ignore plugin messages if bungee support is not enabled or some other plugin message is received if (!Stargate.enableBungee || !channel.equals("BungeeCord")) { return; diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index cd1afb4..3f43583 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -28,13 +28,13 @@ public class Gate { //Gate materials private Material portalOpenBlock; private Material portalClosedBlock; - private Material portalButton; + private final Material portalButton; // Economy information - private int useCost; - private int createCost; - private int destroyCost; - private boolean toOwner; + private final int useCost; + private final int createCost; + private final int destroyCost; + private final boolean toOwner; /** * Instantiates a new gate diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 5e62635..fb8867c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -25,9 +25,9 @@ public class GateHandler { private static final Character EXIT = '*'; private static final Character CONTROL_BLOCK = '-'; - private static Material defaultPortalBlockOpen = Material.NETHER_PORTAL; - private static Material defaultPortalBlockClosed = Material.AIR; - private static Material defaultButton = Material.STONE_BUTTON; + private static final Material defaultPortalBlockOpen = Material.NETHER_PORTAL; + private static final Material defaultPortalBlockClosed = Material.AIR; + private static final Material defaultButton = Material.STONE_BUTTON; private static final HashMap gates = new HashMap<>(); private static final HashMap> controlBlocks = new HashMap<>(); @@ -162,7 +162,7 @@ public class GateHandler { int useCost = readConfig(config, fileName, "usecost", -1); int createCost = readConfig(config, fileName, "createcost", -1); int destroyCost = readConfig(config, fileName, "destroycost", -1); - boolean toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner); + boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : EconomyHandler.toOwner); Gate gate = new Gate(fileName, new GateLayout(layout), types, portalOpenBlock, portalClosedBlock, portalButton, useCost, createCost, destroyCost, toOwner); diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index dfb5ab2..c7b1e81 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -16,7 +16,7 @@ import java.util.List; */ public class GateLayout { - private Character [][] layout; + private final Character [][] layout; private final List exits = new ArrayList<>(); private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; private RelativeBlockVector[] border = new RelativeBlockVector[0]; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index f252002..c386d1b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -59,11 +59,11 @@ public class Portal { private String destination; private String lastDestination = ""; private String network; - private String ownerName; + private final String ownerName; private UUID ownerUUID; private boolean verified; private boolean fixed; - private Map options; + private final Map options; // In-use information private Player player; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index d3b420e..cb61cbd 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -931,7 +931,7 @@ public class PortalHandler { } } PortalHandler.unregisterPortal(portal, false); - Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal.toString()); + Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal); } /** diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 537df09..94afc86 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -15,7 +15,6 @@ import be.seeseemelk.mockbukkit.MockBukkit; import java.util.ArrayList; import java.util.List; -import java.util.Set; public class GateLayoutTest { @@ -40,7 +39,7 @@ public class GateLayoutTest { expected.add(new RelativeBlockVector(1, 3, 0)); expected.add(new RelativeBlockVector(2, 3, 0)); - Set exits = layout.getExits().keySet(); + List exits = layout.getExits(); exits.forEach((blockVector) -> assertTrue(expected.contains(blockVector))); } From 8ae4ac3fc7802496e635f1680ce2b02a27343165 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 9 Sep 2021 15:42:30 +0200 Subject: [PATCH 073/378] Makes sure to only try and create the portal folder if it does not exist --- src/main/java/net/knarcraft/stargate/Stargate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 23cfe82..f51b64b 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -654,7 +654,7 @@ public class Stargate extends JavaPlugin { } } File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); - if (!newFile.exists()) { + if (!newFile.exists() && !newFile.getParentFile().exists()) { if (!newFile.getParentFile().mkdirs()) { log.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); } From 7b83b2440ce6ee7289eb125e2c1cb9218a4f1715 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 9 Sep 2021 15:43:50 +0200 Subject: [PATCH 074/378] Sets junit version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c4063b2..9cdaa33 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ org.junit.jupiter junit-jupiter-api - RELEASE + 5.8.0-M1 test From a86a5de8c3abe55e7728f8469e7c6879e367f496 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 10 Sep 2021 21:32:58 +0200 Subject: [PATCH 075/378] Fixes the bug with teleporting horses, but introduces a bug with teleporting minecarts --- .../listener/PlayerEventListener.java | 86 +++++++++++++------ .../listener/VehicleEventListener.java | 13 --- .../net/knarcraft/stargate/portal/Portal.java | 23 ++--- 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 298464a..e0f60f1 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -11,15 +11,17 @@ import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; -import org.bukkit.entity.Minecart; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; +import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; @@ -80,20 +82,15 @@ public class PlayerEventListener implements Listener { && PortalHandler.getByAdjacentEntrance(event.getFrom()) != null) { event.setCancelled(true); } - if (event.isCancelled() || cause != PlayerTeleportEvent.TeleportCause.PLUGIN) { - return; - } + } - Entity playerVehicle = event.getPlayer().getVehicle(); - Portal portal = PortalHandler.getByAdjacentEntrance(event.getFrom()); - if (playerVehicle != null && portal != null && - !(playerVehicle instanceof Minecart) && - !(playerVehicle instanceof Boat)) { - Portal destinationPortal = portal.getDestination(); - if (destinationPortal != null) { - VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, - event.getPlayer(), portal); - } + @EventHandler + public void onEntityTeleport(EntityTeleportEvent event) { + //Prevent any entities from teleporting through stargates + Portal entryPortal = PortalHandler.getByAdjacentEntrance(event.getFrom()); + Portal exitPortal = PortalHandler.getByAdjacentEntrance(event.getTo()); + if (!event.isCancelled() && entryPortal != null && exitPortal != null && exitPortal == entryPortal.getDestination()) { + event.setCancelled(true); } } @@ -108,34 +105,73 @@ public class PlayerEventListener implements Listener { return; } - //Check to see if the player moved to another block BlockLocation fromLocation = new BlockLocation(event.getFrom().getBlock()); BlockLocation toLocation = new BlockLocation(event.getTo().getBlock()); - if (fromLocation.equals(toLocation)) { + Player player = event.getPlayer(); + + //Check whether the event needs to be considered + if (!isRelevantMoveEvent(event, player, fromLocation, toLocation)) { return; } + Portal entrancePortal = PortalHandler.getByEntrance(toLocation); + Portal destination = entrancePortal.getDestination(player); - Player player = event.getPlayer(); + //Teleport the vehicle to the player + Entity playerVehicle = player.getVehicle(); + if (playerVehicle != null && !(playerVehicle instanceof Boat) && !(playerVehicle instanceof RideableMinecart)) { + + //Make sure the horse can be sat on + if (playerVehicle instanceof AbstractHorse) { + AbstractHorse horse = ((AbstractHorse) playerVehicle); + if (!horse.isTamed()) { + horse.setOwner(player); + } + } + destination.teleport((Vehicle) playerVehicle, entrancePortal); + } else { + destination.teleport(player, entrancePortal, event); + } + Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + entrancePortal.close(false); + } + + /** + * Checks whether a player move event is relevant for this plugin + * @param event

The player move event to check

+ * @param player

The player which moved

+ * @param fromLocation

The location the player is moving from

+ * @param toLocation

The location the player is moving to

+ * @return

True if the event is relevant

+ */ + private boolean isRelevantMoveEvent(PlayerMoveEvent event, Player player, BlockLocation fromLocation, BlockLocation toLocation) { + //Check to see if the player moved to another block + if (fromLocation.equals(toLocation)) { + return false; + } + + //Check if the player moved from a portal Portal entrancePortal = PortalHandler.getByEntrance(toLocation); if (entrancePortal == null) { - return; + return false; } Portal destination = entrancePortal.getDestination(player); //Decide if the anything stops the player from teleport if (!playerCanTeleport(entrancePortal, destination, player, event)) { - return; + return false; } - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - //Decide if the user should be teleported to another bungee server - if (entrancePortal.isBungee() && bungeeTeleport(player, entrancePortal, event)) { - return; + if (entrancePortal.isBungee()) { + if (bungeeTeleport(player, entrancePortal, event)) { + Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + return true; + } else { + return false; + } } - destination.teleport(player, entrancePortal, event); - entrancePortal.close(false); + return true; } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 8ab5b3a..6154b97 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -20,19 +20,6 @@ import java.util.List; @SuppressWarnings("unused") public class VehicleEventListener implements Listener { - /** - * If the player teleported, but its vehicle was left behind, make the vehicle teleport to the player - * - * @param vehicle

The vehicle to teleport

- * @param destinationPortal

The portal the player teleported to

- * @param player

The player who teleported

- * @param origin

The portal the player entered

- */ - public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player, Portal origin) { - destinationPortal.teleport(vehicle, origin); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6); - } - /** * Check for a vehicle moving through a portal * diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index ba44784..ee3c2c6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -699,7 +699,7 @@ public class Portal { * Teleports a vehicle to this portal * * @param vehicle

The vehicle to teleport

- * @param origin

The portal the vehicle entered

+ * @param origin

The portal the vehicle entered

*/ public void teleport(final Vehicle vehicle, Portal origin) { Location traveller = vehicle.getLocation(); @@ -734,7 +734,8 @@ public class Portal { } } else { vehicle.teleport(exit); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.setVelocity(newVelocity), 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + () -> vehicle.setVelocity(newVelocity), 1); } } @@ -748,7 +749,7 @@ public class Portal { private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { vehicle.eject(); vehicle.teleport(exit); - handleVehiclePassengers(passengers, vehicle, exit); + handleVehiclePassengers(passengers, vehicle); } /** @@ -766,7 +767,7 @@ public class Portal { vehicle.eject(); vehicle.remove(); vehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle, exit); + handleVehiclePassengers(passengers, newVehicle); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); } @@ -775,16 +776,16 @@ public class Portal { * * @param passengers

The passengers to handle

* @param targetVehicle

The vehicle the passengers should be put into

- * @param exit

The exit location to teleport the passengers to

*/ - private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, Location exit) { + private void handleVehiclePassengers(List passengers, Vehicle targetVehicle) { for (Entity passenger : passengers) { passenger.eject(); //TODO: Fix random java.lang.IllegalStateException: Removing entity while ticking! - if (!passenger.teleport(exit)) { + if (!passenger.teleport(targetVehicle.getLocation())) { Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); } - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> targetVehicle.addPassenger(passenger), 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + () -> targetVehicle.addPassenger(passenger), 6); } } @@ -823,7 +824,7 @@ public class Portal { * * @param relativeExit

The relative exit defined as the portal's exit

* @param exitLocation

The currently calculated portal exit

- * @param entity

The travelling entity

+ * @param entity

The travelling entity

* @return

A location which won't suffocate the entity inside the portal

*/ private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { @@ -862,7 +863,7 @@ public class Portal { * Gets one of the edges of a portal's opening/exit * * @param relativeExit

The known exit to start from

- * @param direction

The direction to move (+1 for right, -1 for left)

+ * @param direction

The direction to move (+1 for right, -1 for left)

* @return

The right or left edge of the opening

*/ private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { @@ -882,7 +883,7 @@ public class Portal { /** * Adjusts an exit location with rotation and slab height incrementation * - * @param traveller

The location of the travelling entity

+ * @param traveller

The location of the travelling entity

* @param exitLocation

The exit location generated

* @return

The location the travelling entity should be teleported to

*/ From b4059dd169e15b4409f3bb652aa4f823701e2c12 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 10 Sep 2021 23:35:27 +0200 Subject: [PATCH 076/378] Adds an event listener to prevent the nether portal stargates from creating actual nether portals --- .../listener/PortalEventListener.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java new file mode 100644 index 0000000..8b54f8e --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -0,0 +1,24 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.portal.PortalHandler; +import org.bukkit.block.BlockState; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.PortalCreateEvent; + +public class PortalEventListener implements Listener { + + @EventHandler + public void onPortalCreation(PortalCreateEvent event) { + if (event.isCancelled()) { + return; + } + for (BlockState block : event.getBlocks()) { + if (PortalHandler.getByBlock(block.getBlock()) != null) { + event.setCancelled(true); + return; + } + } + } + +} From 93f8f715e5a18b0a55274a26d109f85ad78bfd74 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 10 Sep 2021 23:38:56 +0200 Subject: [PATCH 077/378] Fixes some old bugs and renames rotX to yaw Fixes the direction of minecarts sent through a portal. This prevent the minecarts to go back through the portal and causing a lot of confusion --- .../net/knarcraft/stargate/BlockLocation.java | 12 +-- .../java/net/knarcraft/stargate/Stargate.java | 2 + .../listener/EntityEventListener.java | 1 + .../listener/PlayerEventListener.java | 11 --- .../net/knarcraft/stargate/portal/Portal.java | 75 ++++++++++++------- .../stargate/portal/PortalHandler.java | 18 ++--- 6 files changed, 67 insertions(+), 52 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/BlockLocation.java index 639072e..c81ec41 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/BlockLocation.java @@ -70,13 +70,13 @@ public class BlockLocation extends Location { * @param x

The x position relative to this block's position

* @param y

The y position relative to this block's position

* @param z

The z position relative to this block's position

- * @param rotX

The x rotation of the location

+ * @param yaw

The yaw of the location

* @param rotY

The y rotation of the location

* @return

A new location

*/ - public Location makeRelativeLoc(double x, double y, double z, float rotX, float rotY) { + public Location makeRelativeLoc(double x, double y, double z, float yaw, float rotY) { Location newLocation = this.clone(); - newLocation.setYaw(rotX); + newLocation.setYaw(yaw); newLocation.setPitch(rotY); return newLocation.add(x, y, z); } @@ -105,15 +105,15 @@ public class BlockLocation extends Location { * @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 rotX

The yaw of the location

+ * @param yaw

The yaw of the location

* @param rotY

Unused

* @param modX

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

* @param modY

Unused

* @param modZ

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

* @return A new location relative to this block location */ - public Location modRelativeLoc(double right, double depth, double distance, float rotX, float rotY, int modX, int modY, int modZ) { - return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); + public Location modRelativeLoc(double right, double depth, double distance, float yaw, float rotY, int modX, int modY, int modZ) { + return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, yaw, 0); } /** diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index f51b64b..5686cf7 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -8,6 +8,7 @@ import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; import net.knarcraft.stargate.listener.PlayerEventListener; import net.knarcraft.stargate.listener.PluginEventListener; +import net.knarcraft.stargate.listener.PortalEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; import net.knarcraft.stargate.portal.Gate; @@ -540,6 +541,7 @@ public class Stargate extends JavaPlugin { pm.registerEvents(new VehicleEventListener(), this); pm.registerEvents(new EntityEventListener(), this); + pm.registerEvents(new PortalEventListener(), this); pm.registerEvents(new WorldEventListener(), this); pm.registerEvents(new PluginEventListener(this), this); diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 6fdeab6..43f5fcb 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -61,4 +61,5 @@ public class EntityEventListener implements Listener { } } } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index e0f60f1..e4c2934 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -21,7 +21,6 @@ import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; -import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; @@ -84,16 +83,6 @@ public class PlayerEventListener implements Listener { } } - @EventHandler - public void onEntityTeleport(EntityTeleportEvent event) { - //Prevent any entities from teleporting through stargates - Portal entryPortal = PortalHandler.getByAdjacentEntrance(event.getFrom()); - Portal exitPortal = PortalHandler.getByAdjacentEntrance(event.getTo()); - if (!event.isCancelled() && entryPortal != null && exitPortal != null && exitPortal == entryPortal.getDestination()) { - event.setCancelled(true); - } - } - /** * This event handler detects if a player moves into a portal * diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index ee3c2c6..5f87928 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -48,7 +48,7 @@ public class Portal { private final BlockLocation topLeft; private final int modX; private final int modZ; - private final float rotX; + private final float yaw; private final Axis rot; // Block references @@ -83,7 +83,7 @@ public class Portal { * @param topLeft

The top-left block of the portal. This is used to decide the positions of the rest of the portal

* @param modX

* @param modZ

- * @param rotX

+ * @param yaw

* @param id

The location of the portal's id block, which is the sign which activated the portal

* @param button

The location of the portal's open button

* @param destination

The destination defined on the sign's destination line

@@ -95,14 +95,14 @@ public class Portal { * @param ownerName

The name of the gate's owner

* @param options

A map containing all possible portal options

*/ - Portal(BlockLocation topLeft, int modX, int modZ, float rotX, BlockLocation id, BlockLocation button, + Portal(BlockLocation topLeft, int modX, int modZ, float yaw, BlockLocation id, BlockLocation button, String destination, String name, boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, Map options) { this.topLeft = topLeft; this.modX = modX; this.modZ = modZ; - this.rotX = rotX; - this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; + this.yaw = yaw; + this.rot = yaw == 0.0F || yaw == 180.0F ? Axis.X : Axis.Z; this.id = id; this.destination = destination; this.button = button; @@ -229,7 +229,7 @@ public class Portal { * @return

The rotation of the portal

*/ public float getRotation() { - return rotX; + return yaw; } /** @@ -653,18 +653,18 @@ public class Portal { Location exit = getExit(player, traveller); //Rotate the player to face out from the portal - adjustRotation(traveller, exit, origin); + adjustRotation(exit, origin); - // Call the StargatePortalEvent to allow plugins to change destination + //Call the StargatePortalEvent to allow plugins to change destination if (!origin.equals(this)) { StargatePortalEvent stargatePortalEvent = new StargatePortalEvent(player, origin, this, exit); Stargate.server.getPluginManager().callEvent(stargatePortalEvent); - // Teleport is cancelled + //Teleport is cancelled. Teleport the player back to where it came from if (stargatePortalEvent.isCancelled()) { origin.teleport(player, origin, event); return; } - // Update exit if needed + //Update exit if needed exit = stargatePortalEvent.getExit(); } @@ -672,7 +672,6 @@ public class Portal { // If no event is passed in, assume it's a teleport, and act as such if (event == null) { - exit.setYaw(this.getRotation()); player.teleport(exit); } else { // The new method to teleport in a move event is set the "to" field. @@ -683,16 +682,17 @@ public class Portal { /** * Adjusts the rotation of the player to face out from the portal * - * @param entry

The location the player entered from

* @param exit

The location the player will exit from

* @param origin

The portal the player entered from

*/ - private void adjustRotation(Location entry, Location exit, Portal origin) { - int adjust = 180; + private void adjustRotation(Location exit, Portal origin) { + int adjust = 0; if (isBackwards() != origin.isBackwards()) { - adjust = 0; + adjust = 180; } - exit.setYaw(entry.getYaw() - origin.getRotation() + this.getRotation() + adjust); + float newYaw = (this.getRotation() + adjust) % 360; + Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); + exit.setYaw(newYaw); } /** @@ -707,15 +707,13 @@ public class Portal { double velocity = vehicle.getVelocity().length(); - // Stop and teleport + //Stop and teleport vehicle.setVelocity(new Vector()); - // Get new velocity - final Vector newVelocity = new Vector(modX, 0.0F, modZ); - //-z - Stargate.debug("teleport", modX + " " + modZ); - newVelocity.multiply(velocity); - adjustRotation(traveller, exit, origin); + //Get new velocity + Vector newVelocityDirection = getVectorFromYaw(this.getRotation()); + Vector newVelocity = newVelocityDirection.multiply(velocity); + adjustRotation(exit, origin); List passengers = vehicle.getPassengers(); World vehicleWorld = exit.getWorld(); @@ -739,6 +737,30 @@ public class Portal { } } + /** + * Gets a direction vector given a yaw + * @param yaw

The yaw to use

+ * @return

The direction vector of the yaw

+ */ + private Vector getVectorFromYaw(double yaw) { + while (yaw < 0) { + yaw += 360; + } + yaw = yaw % 360; + + if (yaw == 0) { + return new Vector(0, 0, 1); + } else if (yaw == 90) { + return new Vector(-1, 0, 0); + } else if (yaw == 180) { + return new Vector(0, 0, -1); + } else if (yaw == 270) { + return new Vector(1, 0, 0); + } else { + throw new IllegalArgumentException("Invalid yaw given"); + } + } + /** * Teleport a vehicle which is not a minecart or a boat * @@ -768,7 +790,8 @@ public class Portal { vehicle.remove(); vehicle.setRotation(exit.getYaw(), exit.getPitch()); handleVehiclePassengers(passengers, newVehicle); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + () -> newVehicle.setVelocity(newVelocity), 1); } /** @@ -950,8 +973,8 @@ public class Portal { * * @return

The rotation of this portal

*/ - public float getRotX() { - return this.rotX; + public float getYaw() { + return this.yaw; } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index cb61cbd..89c277a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -237,24 +237,24 @@ public class PortalHandler { // Moved the layout check so as to avoid invalid messages when not making a gate int modX = 0; int modZ = 0; - float rotX = 0f; + float yaw = 0f; BlockFace buttonFacing = BlockFace.DOWN; if (idParent.getX() > id.getBlock().getX()) { modZ -= 1; - rotX = 90f; + yaw = 90f; buttonFacing = BlockFace.WEST; } else if (idParent.getX() < id.getBlock().getX()) { modZ += 1; - rotX = 270f; + yaw = 270f; buttonFacing = BlockFace.EAST; } else if (idParent.getZ() > id.getBlock().getZ()) { modX += 1; - rotX = 180f; + yaw = 180f; buttonFacing = BlockFace.NORTH; } else if (idParent.getZ() < id.getBlock().getZ()) { modX -= 1; - rotX = 0f; + yaw = 0f; buttonFacing = BlockFace.SOUTH; } @@ -376,7 +376,7 @@ public class PortalHandler { BlockLocation button = null; Portal portal; - portal = new Portal(topLeft, modX, modZ, rotX, id, button, destinationName, name, false, network, + portal = new Portal(topLeft, modX, modZ, yaw, id, button, destinationName, name, false, network, gate, player.getUniqueId(), player.getName(), portalOptions); int cost = Stargate.getCreateCost(player, gate); @@ -654,7 +654,7 @@ public class PortalHandler { builder.append(':'); builder.append(portal.getModZ()); builder.append(':'); - builder.append(portal.getRotX()); + builder.append(portal.getYaw()); builder.append(':'); builder.append(portal.getTopLeft().toString()); builder.append(':'); @@ -829,7 +829,7 @@ public class PortalHandler { BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; int modX = Integer.parseInt(portalData[3]); int modZ = Integer.parseInt(portalData[4]); - float rotX = Float.parseFloat(portalData[5]); + float yaw = Float.parseFloat(portalData[5]); BlockLocation topLeft = new BlockLocation(world, portalData[6]); Gate gate = GateHandler.getGateByName(portalData[7]); if (gate == null) { @@ -864,7 +864,7 @@ public class PortalHandler { } //Creates the new portal - Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, destination, name, false, + Portal portal = new Portal(topLeft, modX, modZ, yaw, sign, button, destination, name, false, network, gate, ownerUUID, ownerName, getPortalOptions(portalData)); registerPortal(portal); From 87735e49358f8bfb754a8d40961321e0de9712cd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 11 Sep 2021 15:04:55 +0200 Subject: [PATCH 078/378] Adds some helper functions to make getting direction-related values easier Adds a function for getting the yaw given two locations Adds a function for getting a block face given a yaw --- .../net/knarcraft/stargate/portal/Portal.java | 26 +----- .../stargate/portal/PortalHandler.java | 33 +++----- .../stargate/utility/DirectionHelper.java | 83 +++++++++++++++++++ .../stargate/utility/DirectionHelperTest.java | 33 ++++++++ 4 files changed, 128 insertions(+), 47 deletions(-) create mode 100644 src/test/java/net/knarcraft/stargate/utility/DirectionHelperTest.java diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 5f87928..6069dbd 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -711,7 +711,7 @@ public class Portal { vehicle.setVelocity(new Vector()); //Get new velocity - Vector newVelocityDirection = getVectorFromYaw(this.getRotation()); + Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(this.getRotation()); Vector newVelocity = newVelocityDirection.multiply(velocity); adjustRotation(exit, origin); @@ -737,30 +737,6 @@ public class Portal { } } - /** - * Gets a direction vector given a yaw - * @param yaw

The yaw to use

- * @return

The direction vector of the yaw

- */ - private Vector getVectorFromYaw(double yaw) { - while (yaw < 0) { - yaw += 360; - } - yaw = yaw % 360; - - if (yaw == 0) { - return new Vector(0, 0, 1); - } else if (yaw == 90) { - return new Vector(-1, 0, 0); - } else if (yaw == 180) { - return new Vector(0, 0, -1); - } else if (yaw == 270) { - return new Vector(1, 0, 0); - } else { - throw new IllegalArgumentException("Invalid yaw given"); - } - } - /** * Teleport a vehicle which is not a minecart or a boat * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 89c277a..20db8bb 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.TwoTuple; import net.knarcraft.stargate.event.StargateCreateEvent; +import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHelper; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -17,6 +18,7 @@ import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Player; import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.util.Vector; import java.io.BufferedWriter; import java.io.File; @@ -234,29 +236,16 @@ public class PortalHandler { Map portalOptions = getPortalOptions(player, destinationName, options); - // Moved the layout check so as to avoid invalid messages when not making a gate - int modX = 0; - int modZ = 0; - float yaw = 0f; - BlockFace buttonFacing = BlockFace.DOWN; + //Get the yaw + float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), id.getLocation()); - if (idParent.getX() > id.getBlock().getX()) { - modZ -= 1; - yaw = 90f; - buttonFacing = BlockFace.WEST; - } else if (idParent.getX() < id.getBlock().getX()) { - modZ += 1; - yaw = 270f; - buttonFacing = BlockFace.EAST; - } else if (idParent.getZ() > id.getBlock().getZ()) { - modX += 1; - yaw = 180f; - buttonFacing = BlockFace.NORTH; - } else if (idParent.getZ() < id.getBlock().getZ()) { - modX -= 1; - yaw = 0f; - buttonFacing = BlockFace.SOUTH; - } + //Get the direction the button should be facing + BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw); + + //Get the x and z modifiers + Vector direction = DirectionHelper.getDirectionVectorFromYaw(yaw); + int modX = -direction.getBlockZ(); + int modZ = direction.getBlockX(); Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent); Gate gate = null; diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 8c0c966..104fa26 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -3,6 +3,8 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.RelativeBlockVector; import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.util.Vector; /** * This class helps with direction-dependent (modX, modZ) calculations @@ -13,6 +15,74 @@ public final class DirectionHelper { } + /** + * Gets a yaw by comparing two locations + * + *

The yaw here is the direction an observer a the first location has to look to face the second location. + * The yaw is only meant to be calculated for locations with equal x or equal z.

+ * + * @param location1

The first location, which works as the origin

+ * @param location2

The second location, which the yaw will point at

+ * @return

The yaw

+ */ + public static float getYawFromLocationDifference(Location location1, Location location2) { + Location difference = location1.clone().subtract(location2.clone()); + if (difference.getX() > 0) { + return 90; + } else if (difference.getX() < 0) { + return 270; + } else if (difference.getZ() > 0) { + return 180; + } else if (difference.getZ() < 0) { + return 0; + } + throw new IllegalArgumentException("Locations given are equal or at the same x and y axis"); + } + + /** + * Gets a block face given a yaw + * @param yaw

The yaw to use

+ * @return

The block face the yaw corresponds to

+ */ + public static BlockFace getBlockFaceFromYaw(double yaw) { + //Make sure the yaw is between 0 and 360 + yaw = normalizeYaw(yaw); + + if (yaw == 0) { + return BlockFace.SOUTH; + } else if (yaw == 90) { + return BlockFace.WEST; + } else if (yaw == 180) { + return BlockFace.NORTH; + } else if (yaw == 270) { + return BlockFace.EAST; + } else { + throw new IllegalArgumentException("Invalid yaw given"); + } + } + + /** + * Gets a direction vector given a yaw + * @param yaw

The yaw to use

+ * @return

The direction vector of the yaw

+ */ + public static Vector getDirectionVectorFromYaw(double yaw) { + //Make sure the yaw is between 0 and 360 + yaw = normalizeYaw(yaw); + + if (yaw == 0) { + return new Vector(0, 0, 1); + } else if (yaw == 90) { + return new Vector(-1, 0, 0); + } else if (yaw == 180) { + return new Vector(0, 0, -1); + } else if (yaw == 270) { + return new Vector(1, 0, 0); + } else { + throw new IllegalArgumentException("Invalid yaw given"); + } + } + /** * Gets the block at a relative block vector location * @@ -38,4 +108,17 @@ public final class DirectionHelper { return location.add(-right * modX + distance * modZ, depth, -right * modZ + -distance * modX); } + /** + * Normalizes a yaw to make it positive and no larger than 360 degrees + * @param yaw

The yaw to normalize

+ * @return

The normalized yaw

+ */ + private static double normalizeYaw(double yaw) { + while (yaw < 0) { + yaw += 360; + } + yaw = yaw % 360; + return yaw; + } + } diff --git a/src/test/java/net/knarcraft/stargate/utility/DirectionHelperTest.java b/src/test/java/net/knarcraft/stargate/utility/DirectionHelperTest.java new file mode 100644 index 0000000..6de3716 --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/utility/DirectionHelperTest.java @@ -0,0 +1,33 @@ +package net.knarcraft.stargate.utility; + +import be.seeseemelk.mockbukkit.WorldMock; +import org.bukkit.Location; +import org.bukkit.World; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DirectionHelperTest { + + @Test + public void getYawFromLocationTest() { + World world = new WorldMock(); + Location location1 = new Location(world, 100, 0, 100); + Location location2 = new Location(world, 100, 0, 101); + + double yaw = DirectionHelper.getYawFromLocationDifference(location1, location2); + Assertions.assertEquals(0, yaw); + + location2 = new Location(world, 100, 0, 99); + yaw = DirectionHelper.getYawFromLocationDifference(location1, location2); + Assertions.assertEquals(180, yaw); + + location2 = new Location(world, 101, 0, 100); + yaw = DirectionHelper.getYawFromLocationDifference(location1, location2); + Assertions.assertEquals(270, yaw); + + location2 = new Location(world, 99, 0, 100); + yaw = DirectionHelper.getYawFromLocationDifference(location1, location2); + Assertions.assertEquals(90, yaw); + } + +} From 1c3dbbe81d3b2db53e6249e39cda4a4d59d38414 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 11 Sep 2021 15:33:45 +0200 Subject: [PATCH 079/378] Renames the blox populator and block populator thread as I finally understand what they actually do --- .../stargate/BlockChangeRequest.java | 82 +++++++++++++++++++ .../net/knarcraft/stargate/BloxPopulator.java | 82 ------------------- .../java/net/knarcraft/stargate/Stargate.java | 6 +- .../net/knarcraft/stargate/portal/Portal.java | 25 ++---- .../stargate/thread/BlockChangeThread.java | 67 +++++++++++++++ .../stargate/thread/BlockPopulatorThread.java | 49 ----------- 6 files changed, 159 insertions(+), 152 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/BlockChangeRequest.java delete mode 100644 src/main/java/net/knarcraft/stargate/BloxPopulator.java create mode 100644 src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java delete mode 100644 src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java diff --git a/src/main/java/net/knarcraft/stargate/BlockChangeRequest.java b/src/main/java/net/knarcraft/stargate/BlockChangeRequest.java new file mode 100644 index 0000000..b6b0c3d --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/BlockChangeRequest.java @@ -0,0 +1,82 @@ +package net.knarcraft.stargate; + +import org.bukkit.Axis; +import org.bukkit.Material; + +/** + * Represents a request for changing a block into another material + */ +public class BlockChangeRequest { + + private BlockLocation blockLocation; + private Material newMaterial; + private Axis newAxis; + + /** + * Instantiates a new block change request + * + * @param blockLocation

The location of the block to change

+ * @param material

The new material to change the block to

+ * @param axis

The new axis to orient the block along

+ */ + public BlockChangeRequest(BlockLocation blockLocation, Material material, Axis axis) { + this.blockLocation = blockLocation; + newMaterial = material; + newAxis = axis; + } + + /** + * Gets the location of the block to change + * + * @return

The location of the block

+ */ + public BlockLocation getBlockLocation() { + return blockLocation; + } + + /** + * Sets the location of the block + * + * @param blockLocation

The new location of the block

+ */ + public void setBlockLocation(BlockLocation blockLocation) { + this.blockLocation = blockLocation; + } + + /** + * Gets the material to change the block into + * + * @return

The material to change the block into

+ */ + public Material getMaterial() { + return newMaterial; + } + + /** + * Sets the material to change the block into + * + * @param material

The new material

+ */ + public void setMaterial(Material material) { + newMaterial = material; + } + + /** + * Gets the axis to orient the block along + * + * @return

The axis to orient the block along

+ */ + public Axis getAxis() { + return newAxis; + } + + /** + * Sets the axis to orient the block along + * + * @param axis

The new axis to orient the block along

+ */ + public void setAxis(Axis axis) { + newAxis = axis; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/BloxPopulator.java b/src/main/java/net/knarcraft/stargate/BloxPopulator.java deleted file mode 100644 index a375762..0000000 --- a/src/main/java/net/knarcraft/stargate/BloxPopulator.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.knarcraft.stargate; - -import org.bukkit.Axis; -import org.bukkit.Material; - -/** - * Used to store information about a custom block populator - */ -public class BloxPopulator { - - private BlockLocation blockLocation; - private Material nextMat; - private Axis nextAxis; - - /** - * Instantiates a new block populator - * - * @param blockLocation

The location to start from

- * @param material

The material to populate

- * @param axis

The axis to populate along

- */ - public BloxPopulator(BlockLocation blockLocation, Material material, Axis axis) { - this.blockLocation = blockLocation; - nextMat = material; - nextAxis = axis; - } - - /** - * Gets the location to start from - * - * @return

The location to start from

- */ - public BlockLocation getBlockLocation() { - return blockLocation; - } - - /** - * Sets the location to start from - * - * @param blockLocation

The new start location

- */ - public void setBlockLocation(BlockLocation blockLocation) { - this.blockLocation = blockLocation; - } - - /** - * Gets the material used for population - * - * @return

The material used for population

- */ - public Material getMaterial() { - return nextMat; - } - - /** - * Sets the polulator material - * - * @param material

The new populator material

- */ - public void setMat(Material material) { - nextMat = material; - } - - /** - * Gets the current population axis - * - * @return

The current population axis

- */ - public Axis getAxis() { - return nextAxis; - } - - /** - * Sets the populator axis - * - * @param axis

The new populator axis

- */ - public void setAxis(Axis axis) { - nextAxis = axis; - } - -} diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 5686cf7..b584bff 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -16,7 +16,7 @@ import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalOption; -import net.knarcraft.stargate.thread.BlockPopulatorThread; +import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Bukkit; @@ -70,7 +70,7 @@ public class Stargate extends JavaPlugin { public static boolean permDebug = false; public static final ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); // Used for populating gate open/closed material. - public static final Queue blockPopulatorQueue = new LinkedList<>(); + public static final Queue blockChangeRequestQueue = new LinkedList<>(); // HashMap of player names for Bungee support public static final Map bungeeQueue = new HashMap<>(); // World names that contain stargates @@ -570,7 +570,7 @@ public class Stargate extends JavaPlugin { } getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); - getServer().getScheduler().runTaskTimer(this, new BlockPopulatorThread(), 0L, 1L); + getServer().getScheduler().runTaskTimer(this, new BlockChangeThread(), 0L, 1L); this.registerCommands(); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 6069dbd..663e778 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.BloxPopulator; +import net.knarcraft.stargate.BlockChangeRequest; import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; @@ -49,7 +49,8 @@ public class Portal { private final int modX; private final int modZ; private final float yaw; - private final Axis rot; + //The rotation axis is the axis along which the gate is placed. It's the cross axis of the button's axis + private final Axis rotationAxis; // Block references private final BlockLocation id; @@ -102,7 +103,7 @@ public class Portal { this.modX = modX; this.modZ = modZ; this.yaw = yaw; - this.rot = yaw == 0.0F || yaw == 180.0F ? Axis.X : Axis.Z; + this.rotationAxis = yaw == 0.0F || yaw == 180.0F ? Axis.X : Axis.Z; this.id = id; this.destination = destination; this.button = button; @@ -232,18 +233,6 @@ public class Portal { return yaw; } - /** - * Gets the axis the portal follows - * - *

If a relative vector's right is not zero, it will move along this axis. - * The axis is used to place the portal's open blocks correctly

- * - * @return

The axis the portal follows

- */ - public Axis getAxis() { - return rot; - } - /** * Gets the player currently using this portal * @@ -502,9 +491,9 @@ public class Portal { //Change the opening blocks to the correct type Material openType = gate.getPortalOpenBlock(); - Axis axis = (openType.createBlockData() instanceof Orientable) ? rot : null; + Axis axis = (openType.createBlockData() instanceof Orientable) ? rotationAxis : null; for (BlockLocation inside : getEntrances()) { - Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, axis)); + Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, openType, axis)); } updatePortalOpenState(openFor); @@ -556,7 +545,7 @@ public class Portal { // Close this gate, then the dest gate. Material closedType = gate.getPortalClosedBlock(); for (BlockLocation inside : getEntrances()) { - Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType, null)); + Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, closedType, null)); } updatePortalClosedState(); diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java new file mode 100644 index 0000000..7a4ab10 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -0,0 +1,67 @@ +package net.knarcraft.stargate.thread; + +import net.knarcraft.stargate.BlockChangeRequest; +import net.knarcraft.stargate.Stargate; +import org.bukkit.Axis; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.EndGateway; +import org.bukkit.block.data.Orientable; + +/** + * This thread changes gate blocks to display a gate as open or closed + * + *

This thread fetches some entries from blockPopulateQueue each time it's called.

+ */ +public class BlockChangeThread implements Runnable { + + @Override + public void run() { + long sTime = System.nanoTime(); + //Repeat for at most 0.025 seconds + while (System.nanoTime() - sTime < 25000000) { + //Abort if there's no work to be done + BlockChangeRequest blockChangeRequest = Stargate.blockChangeRequestQueue.poll(); + if (blockChangeRequest == null) { + return; + } + + //Change the material of the pulled block + Block block = blockChangeRequest.getBlockLocation().getBlock(); + block.setType(blockChangeRequest.getMaterial(), false); + + if (blockChangeRequest.getMaterial() == Material.END_GATEWAY && + block.getWorld().getEnvironment() == World.Environment.THE_END) { + //Force a specific location to prevent exit gateway generation + fixEndGatewayGate(block); + } else if (blockChangeRequest.getAxis() != null) { + //If orientation is relevant, adjust the block's orientation + orientBlock(block, blockChangeRequest.getAxis()); + } + } + } + + /** + * Prevents end gateway portal from behaving strangely + * @param block

The block to fix

+ */ + private void fixEndGatewayGate(Block block) { + EndGateway gateway = (EndGateway) block.getState(); + gateway.setExitLocation(block.getLocation()); + gateway.setExactTeleport(true); + gateway.update(false, false); + } + + /** + * Sets the orientation axis of the placed block + * @param block

The block to orient

+ * @param axis

The axis to use for orienting the block

+ */ + private void orientBlock(Block block, Axis axis) { + Orientable orientable = (Orientable) block.getBlockData(); + orientable.setAxis(axis); + block.setBlockData(orientable); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java deleted file mode 100644 index 61be215..0000000 --- a/src/main/java/net/knarcraft/stargate/thread/BlockPopulatorThread.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.knarcraft.stargate.thread; - -import net.knarcraft.stargate.BloxPopulator; -import net.knarcraft.stargate.Stargate; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.EndGateway; -import org.bukkit.block.data.Orientable; - -/** - * This thread changes gate blocks to display a gate as open or closed - * - *

This thread fetches some entries from blockPopulatorQueue each time it's called.

- */ -public class BlockPopulatorThread implements Runnable { - - @Override - public void run() { - long sTime = System.nanoTime(); - //Repeat for at most 0.025 seconds - while (System.nanoTime() - sTime < 25000000) { - //Abort if there's no work to be done - BloxPopulator bloxPopulator = Stargate.blockPopulatorQueue.poll(); - if (bloxPopulator == null) { - return; - } - - //Change the material of the pulled block - Block block = bloxPopulator.getBlockLocation().getBlock(); - block.setType(bloxPopulator.getMaterial(), false); - - if (bloxPopulator.getMaterial() == Material.END_GATEWAY && - block.getWorld().getEnvironment() == World.Environment.THE_END) { - //Force a specific location to prevent exit gateway generation - EndGateway gateway = (EndGateway) block.getState(); - gateway.setExitLocation(block.getLocation()); - gateway.setExactTeleport(true); - gateway.update(false, false); - } else if (bloxPopulator.getAxis() != null) { - //If orientation is relevant, adjust the block's orientation - Orientable orientable = (Orientable) block.getBlockData(); - orientable.setAxis(bloxPopulator.getAxis()); - block.setBlockData(orientable); - } - } - } - -} From 6005c2c6d1396e360a528993f78e46ffe2ffbce9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 11 Sep 2021 16:37:55 +0200 Subject: [PATCH 080/378] Adds some information about usable portal open/closed materials to the readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e8de53..cc4ef46 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,10 @@ X*.X XX ``` The keys `portal-open` and `portal-closed` are used to define the material in the gate when it is open or closed. +The material for `portal-closed` can be most things, including solid blocks. Some materials may act weirdly though. +The material for `portal-open` can be any block the player can partially enter, even things like `GLOW_LICHEN`. +`NETHER_PORTAL` and `END_GATEWAY` work, but `END_PORTAL` does not. + The key `button` is used to define the type of button that is generated for this gate. It can be a button (of any type), a type of wall coral (dead or alive), a type of shulker box or a chest. `X` and `-` are used to define block types for the layout (Any single-character can be used, such as `#`). @@ -197,7 +201,7 @@ There is a default gate type for underwater gates. There are no real restriction normal buttons cannot be used since they'd fall off. Using wall coral fans work much better, though `CHEST` and `SHULKER_BOX` works too. -Using `AIR` for a closed gate looks weird, so `WATER` might be better. +Using `AIR` for a closed underwater gate looks weird, so `WATER` might be better. # Configuration ``` From a6fb7dcb62f938ad883951e1be1495a33f951254 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 11 Sep 2021 16:43:31 +0200 Subject: [PATCH 081/378] Fixes some warnings --- .../stargate/portal/GateHandler.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 2840f6d..09df095 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -6,6 +6,7 @@ import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; import org.bukkit.block.Block; import java.io.File; +import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -159,9 +160,9 @@ public class GateHandler { Material portalOpenBlock = readConfig(config, fileName, "portal-open", defaultPortalBlockOpen); Material portalClosedBlock = readConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); Material portalButton = readConfig(config, fileName, "button", defaultButton); - int useCost = readConfig(config, fileName, "usecost", -1); - int createCost = readConfig(config, fileName, "createcost", -1); - int destroyCost = readConfig(config, fileName, "destroycost", -1); + int useCost = readConfig(config, fileName, "usecost"); + int createCost = readConfig(config, fileName, "createcost"); + int destroyCost = readConfig(config, fileName, "destroycost"); boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : EconomyHandler.toOwner); Gate gate = new Gate(fileName, new GateLayout(layout), types, portalOpenBlock, portalClosedBlock, portalButton, useCost, @@ -323,7 +324,14 @@ public class GateHandler { } } - private static int readConfig(Map config, String fileName, String key, int defaultInteger) { + /** + * Reads an integer configuration key + * @param config

The configuration to read

+ * @param fileName

The filename of the config file

+ * @param key

The config key to read

+ * @return

The read value, or -1 if it cannot be read

+ */ + private static int readConfig(Map config, String fileName, String key) { if (config.containsKey(key)) { try { return Integer.parseInt(config.get(key)); @@ -332,7 +340,7 @@ public class GateHandler { } } - return defaultInteger; + return -1; } /** @@ -403,10 +411,13 @@ public class GateHandler { * @param gateFolder

The folder containing gates

*/ private static void loadGateFromJar(String gateFile, String gateFolder) { - Scanner scanner = new Scanner(Gate.class.getResourceAsStream("/gates/" + gateFile)); - Gate gate = loadGate(gateFile, gateFolder, scanner); - if (gate != null) { - registerGate(gate); + InputStream gateFileStream = Gate.class.getResourceAsStream("/gates/" + gateFile); + if (gateFileStream != null) { + Scanner scanner = new Scanner(gateFileStream); + Gate gate = loadGate(gateFile, gateFolder, scanner); + if (gate != null) { + registerGate(gate); + } } } From 5c601710e7d6edc51b403ad05ca9921d7b2fbed7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 11 Sep 2021 16:44:55 +0200 Subject: [PATCH 082/378] Removes the unused frameBlocks variable and isGateBlock --- .../knarcraft/stargate/portal/GateHandler.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 09df095..1a90965 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -32,7 +32,6 @@ public class GateHandler { private static final HashMap gates = new HashMap<>(); private static final HashMap> controlBlocks = new HashMap<>(); - private static final HashSet frameBlocks = new HashSet<>(); private GateHandler() { @@ -139,9 +138,6 @@ public class GateHandler { return null; } - //Update list of all frame blocks - frameBlocks.addAll(frameTypes); - gate.save(parentFolder + "/"); // Updates format for version changes return gate; } @@ -470,23 +466,12 @@ public class GateHandler { return gates.size(); } - /** - * Checks whether the given material is used for the frame of any portals - * - * @param type

The material type to check

- * @return

True if the material is used for the frame of at least one portal

- */ - public static boolean isGateBlock(Material type) { - return frameBlocks.contains(type); - } - /** * Clears all loaded gates */ public static void clearGates() { gates.clear(); controlBlocks.clear(); - frameBlocks.clear(); } } From ec4ed1e0867a04e7e5a1cac412485183b72d9ff9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 11 Sep 2021 17:02:43 +0200 Subject: [PATCH 083/378] Fixes some more warnings --- .../java/net/knarcraft/stargate/Stargate.java | 56 +++++++++++++------ .../listener/PlayerEventListener.java | 4 +- .../listener/VehicleEventListener.java | 2 +- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index b584bff..00f2bd5 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -79,7 +79,7 @@ public class Stargate extends JavaPlugin { private static String portalFolder; private static String gateFolder; private static String langFolder; - private static String defNetwork = "central"; + private static String defaultGateNetwork = "central"; private static boolean destroyExplosion = false; private static String langName = "en"; private FileConfiguration newConfig; @@ -152,7 +152,7 @@ public class Stargate extends JavaPlugin { } public static String getDefaultNetwork() { - return defNetwork; + return defaultGateNetwork; } public static String getString(String name) { @@ -280,21 +280,32 @@ public class Stargate extends JavaPlugin { /* * Call the StargateAccessPortal event, used for other plugins to bypass Permissions checks */ - public static boolean canAccessPortal(Player player, Portal portal, boolean deny) { + + /** + * Creates a stargate access event and gives the result + * + *

The event is used for other plugins to bypass the permission checks

+ * + * @param player

The player trying to use the portal

+ * @param portal

The portal the player is trying to use

+ * @param deny

Whether the player's access has already been denied by a check

+ * @return

False if the player should be allowed through the portal

+ */ + public static boolean cannotAccessPortal(Player player, Portal portal, boolean deny) { StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); Stargate.server.getPluginManager().callEvent(event); - return !event.getDeny(); + return event.getDeny(); } /** - * Checks whether a given user can travel between two portals + * Checks whether a given user cannot 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

+ * @return

False if the user is allowed to access the portal

*/ - public static boolean canAccessPortal(Player player, Portal entrancePortal, Portal destination) { + public static boolean cannotAccessPortal(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())) { @@ -304,7 +315,7 @@ public class Stargate extends JavaPlugin { } else if (!Stargate.canAccessWorld(player, destination.getWorld().getName())) { deny = true; } - return Stargate.canAccessPortal(player, entrancePortal, deny); + return Stargate.cannotAccessPortal(player, entrancePortal, deny); } /* @@ -592,7 +603,9 @@ public class Stargate extends JavaPlugin { // Load values into variables portalFolder = newConfig.getString("portal-folder"); gateFolder = newConfig.getString("gate-folder"); - defNetwork = newConfig.getString("default-gate-network").trim(); + + String defaultNetwork = newConfig.getString("default-gate-network"); + defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; destroyExplosion = newConfig.getBoolean("destroyexplosion"); maxGates = newConfig.getInt("maxgates"); langName = newConfig.getString("lang"); @@ -604,13 +617,7 @@ public class Stargate extends JavaPlugin { enableBungee = newConfig.getBoolean("enableBungee"); verifyPortals = newConfig.getBoolean("verifyPortals"); // Sign color - String sc = newConfig.getString("signColor"); - try { - signColor = ChatColor.valueOf(sc.toUpperCase()); - } catch (Exception ignore) { - log.warning(Stargate.getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); - signColor = ChatColor.BLACK; - } + loadSignColor(newConfig.getString("signColor")); // Debug debug = newConfig.getBoolean("debug"); permDebug = newConfig.getBoolean("permdebug"); @@ -626,6 +633,23 @@ public class Stargate extends JavaPlugin { this.saveConfig(); } + /** + * Loads the correct sign color given a sign color string + * @param signColor

A string representing a sign color

+ */ + private void loadSignColor(String signColor) { + if (signColor != null) { + try { + Stargate.signColor = ChatColor.valueOf(signColor.toUpperCase()); + return; + } catch (IllegalArgumentException | NullPointerException ignored) { + } + } + log.warning(Stargate.getString("prefix") + "You have specified an invalid color in your config.yml." + + " Defaulting to BLACK"); + Stargate.signColor = ChatColor.BLACK; + } + public void closeAllPortals() { // Close all gates prior to reloading for (Portal p : openList) { diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index e4c2934..5fd5c4e 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -235,7 +235,7 @@ public class PlayerEventListener implements Listener { private boolean cannotAccessPortal(Player player, Portal portal) { boolean deny = !Stargate.canAccessNetwork(player, portal.getNetwork()); - if (!Stargate.canAccessPortal(player, portal, deny)) { + if (Stargate.cannotAccessPortal(player, portal, deny)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); return true; } @@ -369,7 +369,7 @@ public class PlayerEventListener implements Listener { } //Player cannot access portal - if (!Stargate.canAccessPortal(player, entrancePortal, destination)) { + if (Stargate.cannotAccessPortal(player, entrancePortal, destination)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); entrancePortal.teleport(player, entrancePortal, event); entrancePortal.close(false); diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 6154b97..5175517 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -92,7 +92,7 @@ public class VehicleEventListener implements Listener { } //Make sure the user can access the portal - if (!Stargate.canAccessPortal(player, entrancePortal, destinationPortal)) { + if (Stargate.cannotAccessPortal(player, entrancePortal, destinationPortal)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); entrancePortal.close(false); return; From 19018e46b8f6f1187dc95c5d0a97f19d7dedb311 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 12 Sep 2021 01:23:16 +0200 Subject: [PATCH 084/378] Fixes some bugs regarding bungee teleportation Fixes the server being teleported normally after it's teleported to another server Fixes a nullpointerexception --- .../java/net/knarcraft/stargate/Stargate.java | 33 ++++++++++++------- .../listener/PlayerEventListener.java | 7 ++-- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 00f2bd5..18790e9 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -217,21 +217,27 @@ public class Stargate extends JavaPlugin { return player.hasPermission(perm); } - /* + /** * Check a deep permission, this will check to see if the permissions is defined for this use - * If using Permissions it will return the same as hasPerm - * If using SuperPerms will return true if the node isn't defined - * Or the value of the node if it is + * + *

If using Permissions it will return the same as hasPerm. If using SuperPerms will return true if the node + * isn't defined, or the value of the node if it is

+ * + * @param player

The player to check

+ * @param permission

The permission to check

+ * @return

True if the player has the permission or it is not set

*/ - public static boolean hasPermDeep(Player player, String perm) { - if (!player.isPermissionSet(perm)) { - if (permDebug) - Stargate.debug("hasPermDeep::SuperPerm", perm + " => true"); + public static boolean hasPermDeep(Player player, String permission) { + if (!player.isPermissionSet(permission)) { + if (permDebug) { + Stargate.debug("hasPermDeep::SuperPerm", permission + " => true"); + } return true; } - if (permDebug) - Stargate.debug("hasPermDeep::SuperPerms", perm + " => " + player.hasPermission(perm)); - return player.hasPermission(perm); + if (permDebug) { + Stargate.debug("hasPermDeep::SuperPerms", permission + " => " + player.hasPermission(permission)); + } + return player.hasPermission(permission); } /* @@ -309,10 +315,13 @@ public class Stargate extends JavaPlugin { boolean deny = false; // Check if player has access to this server for Bungee gates if (entrancePortal.isBungee() && !Stargate.canAccessServer(player, entrancePortal.getNetwork())) { + Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; } else if (!Stargate.canAccessNetwork(player, entrancePortal.getNetwork())) { + Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (!Stargate.canAccessWorld(player, destination.getWorld().getName())) { + } else if (!entrancePortal.isBungee() && !Stargate.canAccessWorld(player, destination.getWorld().getName())) { + Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } return Stargate.cannotAccessPortal(player, entrancePortal, deny); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 5fd5c4e..8da8abc 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -155,10 +155,8 @@ public class PlayerEventListener implements Listener { if (entrancePortal.isBungee()) { if (bungeeTeleport(player, entrancePortal, event)) { Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - return true; - } else { - return false; } + return false; } return true; } @@ -328,15 +326,18 @@ public class PlayerEventListener implements Listener { //Send the SGBungee packet first, it will be queued by BC if required if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { + Stargate.debug("bungeeTeleport", "Unable to send teleportation message"); return false; } // Connect player to new server if (!BungeeHelper.changeServer(player, entrancePortal)) { + Stargate.debug("bungeeTeleport", "Unable to change server"); return false; } // Close portal if required (Should never be) + Stargate.debug("bungeeTeleport", "Teleported player to another server"); entrancePortal.close(false); return true; } From f2332badb69fde95393b25de98d27ee0fcf951f8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 12 Sep 2021 01:31:21 +0200 Subject: [PATCH 085/378] Adds some missing information about creating bungee gates --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cc4ef46..ee9d14c 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ This is the default gate configuration. See the Custom Gate Layout section on ho - 'S' is for showing an always-on gate in the network list - 'N' is for hiding the network name - 'R' is for random gates. These follow standard permissions of gates, but have a random exit location every time a player enters. + - 'U' is for a gate connecting to another through bungee The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. @@ -93,13 +94,15 @@ The options are the single letter, not the word. So to make a private hidden gat - Gates are all part of a network, by default this is "central". - You can specify (and create) your own network on the third line of the sign when making a new gate. - Gates on one network will not see gates on the second network, and vice versa. - - Gates on different worlds, but in the same network, will see eachother. + - Gates on different worlds, but in the same network, will see each other. + - If the gate is a bungee gate, the network name should be the name of the server as displayed when typing /servers #### Fixed gates: - Fixed gates go to only one set destination. - Fixed gates can be linked to other fixed gates, or normal gates. A normal gate cannot open a portal to a fixed gate however. - To create a fixed gate, specify a destination on the second line of the stargate sign. - Set the 4th line of the stargate sign to "A" to enable an always-open fixed gate. + - A bungee gate is always automatically a fixed gate #### Hidden Gates: - Hidden gates are like normal gates, but only show on the destination list of other gates under certain conditions. From abd48b646d058543906ad553a7844d3746decc2f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 12 Sep 2021 02:21:13 +0200 Subject: [PATCH 086/378] Fixes code for slab checking to prevent the player from teleporting underneath the block --- src/main/java/net/knarcraft/stargate/portal/Portal.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 663e778..6bfca78 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -23,6 +23,7 @@ import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Orientable; import org.bukkit.block.data.Powerable; +import org.bukkit.block.data.type.Slab; import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -879,7 +880,9 @@ public class Portal { 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) { + if ((blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) || + (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { + Stargate.debug("adjustExitLocation", "Added half a block to get above a slab"); exitLocation.add(0, 0.5, 0); } else if (blockData.getMaterial() == Material.WATER) { exitLocation.add(0, 1, 0); From 319849fd96931af52f643246911f72c518be95df Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 12 Sep 2021 06:02:10 +0200 Subject: [PATCH 087/378] Prevents suffocation when teleporting on a horse --- src/main/java/net/knarcraft/stargate/portal/Portal.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 6bfca78..a0a3686 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -24,6 +24,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Orientable; import org.bukkit.block.data.Powerable; import org.bukkit.block.data.type.Slab; +import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -844,6 +845,9 @@ public class Portal { exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D) - 1, modX, modZ); } } + if (entity instanceof AbstractHorse) { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, 1, modX, modZ); + } return exitLocation; } From c35378cfe0b7cd6cb3cabfd236fb3e2492873edc Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 12 Sep 2021 06:18:20 +0200 Subject: [PATCH 088/378] Improves pre-teleport chunk loading --- .../java/net/knarcraft/stargate/portal/Portal.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index a0a3686..1526d28 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -904,12 +904,22 @@ public class Portal { * Loads the chunks at the portal's corners */ public void loadChunks() { - //TODO: Improve this in the case where the portal sits between two chunks for (RelativeBlockVector vector : gate.getLayout().getCorners()) { Chunk chunk = getBlockAt(vector).getChunk(); + + //Get the chunk in front of the gate corner + Location cornerLocation = getBlockAt(vector).getLocation(); + int blockOffset = this.isBackwards() ? -5 : 5; + Location fiveBlocksForward = DirectionHelper.adjustLocation(cornerLocation, 0, 0, blockOffset, modX, modZ); + Chunk forwardChunk = fiveBlocksForward.getChunk(); + + //Load the chunks if (!getWorld().isChunkLoaded(chunk)) { chunk.load(); } + if (!getWorld().isChunkLoaded(forwardChunk)) { + forwardChunk.load(); + } } } From e253e95cecc69b05e27a2bf25ce4ae819076d5b2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 12 Sep 2021 15:23:22 +0200 Subject: [PATCH 089/378] Minor function cleaning --- .../java/net/knarcraft/stargate/Stargate.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 18790e9..956aa94 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -342,11 +342,25 @@ public class Stargate extends JavaPlugin { /* * Check whether the player can see this gate (Hidden property check) */ + + /** + * Checks whether the player can see this gate (Hidden property check) + * + *

This decides if the player can see the gate on the network selection screen

+ * + * @param player

The player to check

+ * @param portal

The portal to check

+ * @return

True if the given player can see the given portal

+ */ public static boolean canSee(Player player, Portal portal) { // The gate is not hidden - if (!portal.isHidden()) return true; + if (!portal.isHidden()) { + return true; + } // The player is an admin with the ability to see hidden gates - if (hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.hidden")) return true; + if (hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.hidden")) { + return true; + } // The player is the owner of the gate return portal.isOwner(player); } From 4851a0b5e22a2a988962aa1173f0bc15aea42875 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 16 Sep 2021 21:31:32 +0200 Subject: [PATCH 090/378] Only gets vehicle exit world when it's actually used --- .../net/knarcraft/stargate/portal/Portal.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 1526d28..265846b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -707,16 +707,16 @@ public class Portal { adjustRotation(exit, origin); List passengers = vehicle.getPassengers(); - World vehicleWorld = exit.getWorld(); - if (vehicleWorld == null) { - Stargate.log.warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); - return; - } loadChunks(); if (!passengers.isEmpty()) { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { + World vehicleWorld = exit.getWorld(); + if (vehicleWorld == null) { + Stargate.log.warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); + return; + } putPassengersInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); } else { teleportLivingVehicle(vehicle, exit, passengers); @@ -914,11 +914,19 @@ public class Portal { Chunk forwardChunk = fiveBlocksForward.getChunk(); //Load the chunks - if (!getWorld().isChunkLoaded(chunk)) { - chunk.load(); - } - if (!getWorld().isChunkLoaded(forwardChunk)) { - forwardChunk.load(); + loadOneChunk(chunk); + loadOneChunk(forwardChunk); + } + } + + /** + * Loads one chunk + * @param chunk

The chunk to load

+ */ + private void loadOneChunk(Chunk chunk) { + if (!getWorld().isChunkLoaded(chunk)) { + if (!chunk.load()) { + Stargate.debug("loadChunks", "Failed to load chunk " + chunk); } } } From b191ac1de52363d1015d2d6ec370a85a4408bb7a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 18 Sep 2021 21:51:29 +0200 Subject: [PATCH 091/378] Moves some classes to the new container package, and improves some code --- .../knarcraft/stargate/LanguageLoader.java | 6 +- .../java/net/knarcraft/stargate/Stargate.java | 103 +++++++----- .../{ => container}/BlockChangeRequest.java | 2 +- .../{ => container}/BlockLocation.java | 2 +- .../{ => container}/RelativeBlockVector.java | 2 +- .../stargate/{ => container}/TwoTuple.java | 2 +- .../listener/PlayerEventListener.java | 4 +- .../net/knarcraft/stargate/portal/Gate.java | 4 +- .../knarcraft/stargate/portal/GateLayout.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 6 +- .../stargate/portal/PortalHandler.java | 159 ++++++++++-------- .../stargate/thread/BlockChangeThread.java | 2 +- .../stargate/utility/DirectionHelper.java | 4 +- .../knarcraft/stargate/BlockLocationTest.java | 1 + .../stargate/RelativeBlockVectorTest.java | 1 + .../stargate/portal/GateLayoutTest.java | 2 +- 16 files changed, 171 insertions(+), 131 deletions(-) rename src/main/java/net/knarcraft/stargate/{ => container}/BlockChangeRequest.java (97%) rename src/main/java/net/knarcraft/stargate/{ => container}/BlockLocation.java (99%) rename src/main/java/net/knarcraft/stargate/{ => container}/RelativeBlockVector.java (98%) rename src/main/java/net/knarcraft/stargate/{ => container}/TwoTuple.java (95%) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index ecce367..9b6ab3f 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -41,7 +41,7 @@ public class LanguageLoader { File tmp = new File(languageFolder, chosenLanguage + ".txt"); if (!tmp.exists()) { - if (tmp.getParentFile().mkdirs() && Stargate.debug) { + if (tmp.getParentFile().mkdirs() && Stargate.debuggingEnabled) { Stargate.log.info("[stargate] Created language folder"); } } @@ -112,7 +112,7 @@ public class LanguageLoader { if (inputStream == null) { Stargate.log.info("[stargate] The language " + language + " is not available. Falling back to " + "english, You can add a custom language by creating a new text file in the lang directory."); - if (Stargate.debug) { + if (Stargate.debuggingEnabled) { Stargate.log.info("[stargate] Unable to load /lang/" + language + ".txt"); } return; @@ -242,7 +242,7 @@ public class LanguageLoader { } readLanguageFile(inputStreamReader, strings); } catch (Exception e) { - if (Stargate.debug) { + if (Stargate.debuggingEnabled) { Stargate.log.info("Unable to load chosen language"); } return null; diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 956aa94..64f8e92 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; +import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; @@ -66,19 +67,18 @@ public class Stargate extends JavaPlugin { // Temp workaround for snowmen, don't check gate entrance public static boolean ignoreEntrance = false; // Used for debug - public static boolean debug = false; - public static boolean permDebug = false; + public static boolean debuggingEnabled = false; + public static boolean permissionDebuggingEnabled = false; public static final ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); // Used for populating gate open/closed material. public static final Queue blockChangeRequestQueue = new LinkedList<>(); // HashMap of player names for Bungee support public static final Map bungeeQueue = new HashMap<>(); - // World names that contain stargates + //World names that contain stargates public static final HashSet managedWorlds = new HashSet<>(); private static String pluginVersion; private static String portalFolder; private static String gateFolder; - private static String langFolder; private static String defaultGateNetwork = "central"; private static boolean destroyExplosion = false; private static String langName = "en"; @@ -119,7 +119,7 @@ public class Stargate extends JavaPlugin { } public static void debug(String rout, String msg) { - if (Stargate.debug) { + if (Stargate.debuggingEnabled) { log.info("[stargate::" + rout + "] " + msg); } else { log.log(Level.FINEST, "[stargate::" + rout + "] " + msg); @@ -211,9 +211,20 @@ public class Stargate extends JavaPlugin { /* * Check whether the player has the given permissions. */ - public static boolean hasPerm(Player player, String perm) { - if (permDebug) + + /** + * Checks whether a player has the given permission + * + *

This is the same as player.hasPermission(), but this function allows for printing permission debugging info.

+ * + * @param player

The player to check

+ * @param perm

The permission to check

+ * @return

True if the player has the permission

+ */ + public static boolean hasPermission(Player player, String perm) { + if (permissionDebuggingEnabled) { Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); + } return player.hasPermission(perm); } @@ -229,12 +240,12 @@ public class Stargate extends JavaPlugin { */ public static boolean hasPermDeep(Player player, String permission) { if (!player.isPermissionSet(permission)) { - if (permDebug) { + if (permissionDebuggingEnabled) { Stargate.debug("hasPermDeep::SuperPerm", permission + " => true"); } return true; } - if (permDebug) { + if (permissionDebuggingEnabled) { Stargate.debug("hasPermDeep::SuperPerms", permission + " => " + player.hasPermission(permission)); } return player.hasPermission(permission); @@ -243,31 +254,31 @@ public class Stargate extends JavaPlugin { /* * Check whether player can teleport to dest world */ - public static boolean canAccessWorld(Player player, String world) { + public static boolean cannotAccessWorld(Player player, String world) { // Can use all stargate player features or access all worlds - if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.world")) { + if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.world")) { // Do a deep check to see if the player lacks this specific world node - return hasPermDeep(player, "stargate.world." + world); + return !hasPermDeep(player, "stargate.world." + world); } // Can access dest world - return hasPerm(player, "stargate.world." + world); + return !hasPermission(player, "stargate.world." + world); } /* * Check whether player can use network */ - public static boolean canAccessNetwork(Player player, String network) { + public static boolean cannotAccessNetwork(Player player, String network) { // Can user all stargate player features, or access all networks - if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.network")) { + if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.network")) { // Do a deep check to see if the player lacks this specific network node - return hasPermDeep(player, "stargate.network." + network); + return !hasPermDeep(player, "stargate.network." + network); } // Can access this network - if (hasPerm(player, "stargate.network." + network)) return true; + if (hasPermission(player, "stargate.network." + network)) return false; // Is able to create personal gates (Assumption is made they can also access them) String playerName = player.getName(); if (playerName.length() > 11) playerName = playerName.substring(0, 11); - return network.equals(playerName) && hasPerm(player, "stargate.create.personal"); + return !network.equals(playerName) || !hasPermission(player, "stargate.create.personal"); } /* @@ -275,12 +286,12 @@ public class Stargate extends JavaPlugin { */ public static boolean canAccessServer(Player player, String server) { // Can user all stargate player features, or access all servers - if (hasPerm(player, "stargate.use") || hasPerm(player, "stargate.servers")) { + if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.servers")) { // Do a deep check to see if the player lacks this specific server node return hasPermDeep(player, "stargate.server." + server); } // Can access this server - return hasPerm(player, "stargate.server." + server); + return hasPermission(player, "stargate.server." + server); } /* @@ -317,10 +328,10 @@ public class Stargate extends JavaPlugin { if (entrancePortal.isBungee() && !Stargate.canAccessServer(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; - } else if (!Stargate.canAccessNetwork(player, entrancePortal.getNetwork())) { + } else if (Stargate.cannotAccessNetwork(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (!entrancePortal.isBungee() && !Stargate.canAccessWorld(player, destination.getWorld().getName())) { + } else if (!entrancePortal.isBungee() && Stargate.cannotAccessWorld(player, destination.getWorld().getName())) { Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } @@ -334,7 +345,7 @@ public class Stargate extends JavaPlugin { // This gate is free if (src.isFree()) return true; // Player gets free use - if (hasPerm(player, "stargate.free") || Stargate.hasPerm(player, "stargate.free.use")) return true; + if (hasPermission(player, "stargate.free") || Stargate.hasPermission(player, "stargate.free.use")) return true; // Don't charge for free destination gates return dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree(); } @@ -358,7 +369,7 @@ public class Stargate extends JavaPlugin { return true; } // The player is an admin with the ability to see hidden gates - if (hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.hidden")) { + if (hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.hidden")) { return true; } // The player is the owner of the gate @@ -372,7 +383,7 @@ public class Stargate extends JavaPlugin { // Check if the player is the owner of the gate if (portal.isOwner(player)) return true; // The player is an admin with the ability to use private gates - return hasPerm(player, "stargate.admin") || hasPerm(player, "stargate.admin.private"); + return hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.private"); } /* @@ -380,11 +391,11 @@ public class Stargate extends JavaPlugin { */ public static boolean canOption(Player player, PortalOption option) { // Check if the player can use all options - if (hasPerm(player, "stargate.option") || option == PortalOption.BUNGEE) { + if (hasPermission(player, "stargate.option") || option == PortalOption.BUNGEE) { return true; } // Check if they can use this specific option - return hasPerm(player, option.getPermissionString()); + return hasPermission(player, option.getPermissionString()); } /* @@ -392,14 +403,14 @@ public class Stargate extends JavaPlugin { */ public static boolean canCreate(Player player, String network) { // Check for general create - if (hasPerm(player, "stargate.create")) return true; + if (hasPermission(player, "stargate.create")) return true; // Check for all network create permission - if (hasPerm(player, "stargate.create.network")) { + if (hasPermission(player, "stargate.create.network")) { // Do a deep check to see if the player lacks this specific network node return hasPermDeep(player, "stargate.create.network." + network); } // Check for this specific network - return hasPerm(player, "stargate.create.network." + network); + return hasPermission(player, "stargate.create.network." + network); } @@ -408,9 +419,9 @@ public class Stargate extends JavaPlugin { */ public static boolean canCreatePersonal(Player player) { // Check for general create - if (hasPerm(player, "stargate.create")) return true; + if (hasPermission(player, "stargate.create")) return true; // Check for personal - return hasPerm(player, "stargate.create.personal"); + return hasPermission(player, "stargate.create.personal"); } /* @@ -418,14 +429,14 @@ public class Stargate extends JavaPlugin { */ public static boolean canCreateGate(Player player, String gate) { // Check for general create - if (hasPerm(player, "stargate.create")) return true; + if (hasPermission(player, "stargate.create")) return true; // Check for all gate create permissions - if (hasPerm(player, "stargate.create.gate")) { + if (hasPermission(player, "stargate.create.gate")) { // Do a deep check to see if the player lacks this specific gate node return hasPermDeep(player, "stargate.create.gate." + gate); } // Check for this specific gate - return hasPerm(player, "stargate.create.gate." + gate); + return hasPermission(player, "stargate.create.gate." + gate); } /* @@ -434,16 +445,16 @@ public class Stargate extends JavaPlugin { public static boolean canDestroy(Player player, Portal portal) { String network = portal.getNetwork(); // Check for general destroy - if (hasPerm(player, "stargate.destroy")) return true; + if (hasPermission(player, "stargate.destroy")) return true; // Check for all network destroy permission - if (hasPerm(player, "stargate.destroy.network")) { + if (hasPermission(player, "stargate.destroy.network")) { // Do a deep check to see if the player lacks permission for this network node return hasPermDeep(player, "stargate.destroy.network." + network); } // Check for this specific network - if (hasPerm(player, "stargate.destroy.network." + network)) return true; + if (hasPermission(player, "stargate.destroy.network." + network)) return true; // Check for personal gate - return portal.isOwner(player) && hasPerm(player, "stargate.destroy.personal"); + return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); } /* @@ -483,7 +494,7 @@ public class Stargate extends JavaPlugin { // Cost is 0 if the player owns this gate and funds go to the owner if (src.getGate().getToOwner() && src.isOwner(player)) return 0; // Player gets free gate use - if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.use")) return 0; + if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.use")) return 0; return src.getGate().getUseCost(); } @@ -495,7 +506,7 @@ public class Stargate extends JavaPlugin { // Not using Economy if (!EconomyHandler.useEconomy()) return 0; // Player gets free gate destruction - if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.create")) return 0; + if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.create")) return 0; return gate.getCreateCost(); } @@ -507,7 +518,7 @@ public class Stargate extends JavaPlugin { // Not using Economy if (!EconomyHandler.useEconomy()) return 0; // Player gets free gate destruction - if (hasPerm(player, "stargate.free") || hasPerm(player, "stargate.free.destroy")) return 0; + if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.destroy")) return 0; return gate.getDestroyCost(); } @@ -563,7 +574,7 @@ public class Stargate extends JavaPlugin { String dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); portalFolder = dataFolderPath + "/portals/"; gateFolder = dataFolderPath + "/gates/"; - langFolder = dataFolderPath + "/lang/"; + String languageFolder = dataFolderPath + "/lang/"; pluginVersion = pluginDescriptionFile.getVersion(); @@ -588,7 +599,7 @@ public class Stargate extends JavaPlugin { } // It is important to load languages here, as they are used during reloadGates() - languageLoader = new LanguageLoader(langFolder, Stargate.langName); + languageLoader = new LanguageLoader(languageFolder, Stargate.langName); this.migrate(); this.loadGates(); @@ -642,8 +653,8 @@ public class Stargate extends JavaPlugin { // Sign color loadSignColor(newConfig.getString("signColor")); // Debug - debug = newConfig.getBoolean("debug"); - permDebug = newConfig.getBoolean("permdebug"); + debuggingEnabled = newConfig.getBoolean("debug"); + permissionDebuggingEnabled = newConfig.getBoolean("permdebug"); // Economy EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); EconomyHandler.setCreateCost(newConfig.getInt("createcost")); diff --git a/src/main/java/net/knarcraft/stargate/BlockChangeRequest.java b/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java similarity index 97% rename from src/main/java/net/knarcraft/stargate/BlockChangeRequest.java rename to src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java index b6b0c3d..57008c4 100644 --- a/src/main/java/net/knarcraft/stargate/BlockChangeRequest.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.container; import org.bukkit.Axis; import org.bukkit.Material; diff --git a/src/main/java/net/knarcraft/stargate/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/BlockLocation.java rename to src/main/java/net/knarcraft/stargate/container/BlockLocation.java index c81ec41..e5ea6b6 100644 --- a/src/main/java/net/knarcraft/stargate/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.container; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/RelativeBlockVector.java rename to src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 15c17ab..6c1a8bf 100644 --- a/src/main/java/net/knarcraft/stargate/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.container; /** * This stores a block location as a vector relative to a position diff --git a/src/main/java/net/knarcraft/stargate/TwoTuple.java b/src/main/java/net/knarcraft/stargate/container/TwoTuple.java similarity index 95% rename from src/main/java/net/knarcraft/stargate/TwoTuple.java rename to src/main/java/net/knarcraft/stargate/container/TwoTuple.java index 438590d..89c4d23 100644 --- a/src/main/java/net/knarcraft/stargate/TwoTuple.java +++ b/src/main/java/net/knarcraft/stargate/container/TwoTuple.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.container; /** * This class allows storing two values of any type diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 8da8abc..e8b88de 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.BlockLocation; +import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; @@ -231,7 +231,7 @@ public class PlayerEventListener implements Listener { * @return

True if the player should be denied

*/ private boolean cannotAccessPortal(Player player, Portal portal) { - boolean deny = !Stargate.canAccessNetwork(player, portal.getNetwork()); + boolean deny = Stargate.cannotAccessNetwork(player, portal.getNetwork()); if (Stargate.cannotAccessPortal(player, portal, deny)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 3f43583..29090a6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 61e31a3..402946f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.container.RelativeBlockVector; import java.io.BufferedWriter; import java.io.IOException; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 265846b..839a881 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.BlockChangeRequest; -import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.BlockChangeRequest; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 20db8bb..62cb745 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -1,9 +1,9 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.TwoTuple; +import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHelper; @@ -38,8 +38,8 @@ public class PortalHandler { private static final Map lookupEntrances = new HashMap<>(); private static final Map lookupControls = new HashMap<>(); private static final List allPortals = new ArrayList<>(); - private static final HashMap> allPortalsNet = new HashMap<>(); - private static final HashMap> lookupNamesNet = new HashMap<>(); + private static final HashMap> allPortalNetworks = new HashMap<>(); + private static final HashMap> portalLookupByNetwork = new HashMap<>(); // A list of Bungee gates private static final Map bungeePortals = new HashMap<>(); @@ -49,7 +49,7 @@ public class PortalHandler { } public static List getNetwork(String network) { - return allPortalsNet.get(network.toLowerCase()); + return allPortalNetworks.get(network.toLowerCase()); } /** @@ -62,7 +62,7 @@ public class PortalHandler { */ public static List getDestinations(Portal entrancePortal, Player player, String network) { List destinations = new ArrayList<>(); - for (String destination : allPortalsNet.get(network.toLowerCase())) { + for (String destination : allPortalNetworks.get(network.toLowerCase())) { Portal portal = getByName(destination, network); if (portal == null) { continue; @@ -89,7 +89,7 @@ public class PortalHandler { continue; } // Check if this player can access the dest world - if (!Stargate.canAccessWorld(player, portal.getWorld().getName())) { + if (Stargate.cannotAccessWorld(player, portal.getWorld().getName())) { Stargate.log.info("cannot access world"); continue; } @@ -111,10 +111,15 @@ public class PortalHandler { Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); portal.close(true); + String portalName = portal.getName().toLowerCase(); + String networkName = portal.getNetwork().toLowerCase(); + + //Remove portal from lookup blocks for (BlockLocation block : portal.getFrame()) { lookupBlocks.remove(block); } - // Include the sign and button + + //Remove registered info about the lookup controls and blocks lookupBlocks.remove(portal.getId()); lookupControls.remove(portal.getId()); if (portal.getButton() != null) { @@ -122,30 +127,42 @@ public class PortalHandler { lookupControls.remove(portal.getButton()); } + //Remove entrances for (BlockLocation entrance : portal.getEntrances()) { lookupEntrances.remove(entrance); } + //Remove the portal from the list of all portals if (removeAll) { allPortals.remove(portal); } if (portal.isBungee()) { - bungeePortals.remove(portal.getName().toLowerCase()); + //Remove the bungee listing + bungeePortals.remove(portalName); } else { - lookupNamesNet.get(portal.getNetwork().toLowerCase()).remove(portal.getName().toLowerCase()); - allPortalsNet.get(portal.getNetwork().toLowerCase()).remove(portal.getName().toLowerCase()); + //Remove from network lists + portalLookupByNetwork.get(networkName).remove(portalName); + allPortalNetworks.get(networkName).remove(portalName); - for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { + //Update all portals in the same network with this portal as its destination + for (String originName : allPortalNetworks.get(networkName)) { Portal origin = getByName(originName, portal.getNetwork()); - if (origin == null) continue; - if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; - if (!origin.isVerified()) continue; - if (origin.isFixed()) origin.drawSign(); - if (origin.isAlwaysOn()) origin.close(true); + if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || !origin.isVerified()) { + continue; + } + //Update the portal's sign + if (origin.isFixed()) { + origin.drawSign(); + } + //Close portal without destination + if (origin.isAlwaysOn()) { + origin.close(true); + } } } + //Clear sign data if (portal.getId().getBlock().getBlockData() instanceof WallSign) { Sign sign = (Sign) portal.getId().getBlock().getState(); sign.setLine(0, portal.getName()); @@ -166,29 +183,34 @@ public class PortalHandler { private static void registerPortal(Portal portal) { portal.setFixed(portal.getDestinationName().length() > 0 || portal.isRandom() || portal.isBungee()); + String portalName = portal.getName().toLowerCase(); + String networkName = portal.getNetwork().toLowerCase(); + // Bungee gates are stored in their own list if (portal.isBungee()) { - bungeePortals.put(portal.getName().toLowerCase(), portal); + bungeePortals.put(portalName, portal); } else { - // Check if network exists in our network list - if (!lookupNamesNet.containsKey(portal.getNetwork().toLowerCase())) { + //Check if network exists in the lookup list. If not, register the new network + if (!portalLookupByNetwork.containsKey(networkName)) { Stargate.debug("register", "Network " + portal.getNetwork() + " not in lookupNamesNet, adding"); - lookupNamesNet.put(portal.getNetwork().toLowerCase(), new HashMap<>()); + portalLookupByNetwork.put(networkName, new HashMap<>()); } - lookupNamesNet.get(portal.getNetwork().toLowerCase()).put(portal.getName().toLowerCase(), portal); - - // Check if this network exists - if (!allPortalsNet.containsKey(portal.getNetwork().toLowerCase())) { + //Check if this network exists in the network list. If not, register the network + if (!allPortalNetworks.containsKey(networkName)) { Stargate.debug("register", "Network " + portal.getNetwork() + " not in allPortalsNet, adding"); - allPortalsNet.put(portal.getNetwork().toLowerCase(), new ArrayList<>()); + allPortalNetworks.put(networkName, new ArrayList<>()); } - allPortalsNet.get(portal.getNetwork().toLowerCase()).add(portal.getName().toLowerCase()); + + //Register the portal + portalLookupByNetwork.get(networkName).put(portalName, portal); + allPortalNetworks.get(networkName).add(portalName); } + //Register all frame blocks to the lookup list for (BlockLocation block : portal.getFrame()) { lookupBlocks.put(block, portal); } - // Include the sign and button + //Register the sign and button to the lookup lists lookupBlocks.put(portal.getId(), portal); lookupControls.put(portal.getId(), portal); if (portal.getButton() != null) { @@ -196,7 +218,7 @@ public class PortalHandler { lookupControls.put(portal.getButton(), portal); } - + //Register entrances to the lookup list for (BlockLocation entrance : portal.getEntrances()) { lookupEntrances.put(entrance, portal); } @@ -227,6 +249,7 @@ public class PortalHandler { return null; } + //Get necessary information from the gate's sign BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); BlockLocation topLeft = null; String name = filterName(event.getLine(0)); @@ -234,6 +257,7 @@ public class PortalHandler { String network = filterName(event.getLine(2)); String options = filterName(event.getLine(3)).toLowerCase(); + //Get portal options available to the player creating the portal Map portalOptions = getPortalOptions(player, destinationName, options); //Get the yaw @@ -247,34 +271,38 @@ public class PortalHandler { int modX = -direction.getBlockZ(); int modZ = direction.getBlockX(); + //Get all gates with the used type of control blocks Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent); Gate gate = null; RelativeBlockVector buttonVector = null; + RelativeBlockVector signVector = null; - for (Gate possibility : possibleGates) { - if (gate != null || buttonVector != null) { - break; - } - RelativeBlockVector[] vectors = possibility.getLayout().getControls(); - RelativeBlockVector otherControl = null; + //Try to find a matching gate configuration + for (Gate possibleGate : possibleGates) { + //Get gate controls + RelativeBlockVector[] vectors = possibleGate.getLayout().getControls(); - for (RelativeBlockVector vector : vectors) { - BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ); - - if (gate == null) { - if (possibility.matches(tl, modX, modZ, true)) { - gate = possibility; - topLeft = tl; - - if (otherControl != null) { - buttonVector = otherControl; - } - } - } else if (otherControl != null) { - buttonVector = vector; + for (RelativeBlockVector controlVector : vectors) { + //Assuming the top-left location is pointing to the gate's top-left location, check if it's a match + BlockLocation possibleTopLocation = parent.modRelative(-controlVector.getRight(), + -controlVector.getDepth(), -controlVector.getDistance(), modX, 1, modZ); + if (possibleGate.matches(possibleTopLocation, modX, modZ, true)) { + gate = possibleGate; + topLeft = possibleTopLocation; + signVector = controlVector; + break; } + } + } - otherControl = vector; + //Find the button position if a match was found + if (gate != null) { + RelativeBlockVector[] vectors = gate.getLayout().getControls(); + for (RelativeBlockVector controlVector : vectors) { + if (!controlVector.equals(signVector)) { + buttonVector = controlVector; + break; + } } } @@ -283,10 +311,9 @@ public class PortalHandler { return null; } - // If the player is trying to create a Bungee gate without permissions, drop out here - // Do this after the gate layout check, in the least + //If the player is trying to create a Bungee gate without permissions, drop out here if (options.indexOf(PortalOption.BUNGEE.getCharacterRepresentation()) != -1) { - if (!Stargate.hasPerm(player, "stargate.admin.bungee")) { + if (!Stargate.hasPermission(player, "stargate.admin.bungee")) { Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); return null; } @@ -345,7 +372,7 @@ public class PortalHandler { Portal p = getByName(destinationName, network); if (p != null) { String world = p.getWorld().getName(); - if (!Stargate.canAccessWorld(player, world)) { + if (Stargate.cannotAccessWorld(player, world)) { Stargate.debug("canCreate", "Player does not have access to destination world"); deny = true; denyMsg = Stargate.getString("createWorldDeny"); @@ -405,7 +432,7 @@ public class PortalHandler { } // Check if there are too many gates in this network - List netList = allPortalsNet.get(portal.getNetwork().toLowerCase()); + List netList = allPortalNetworks.get(portal.getNetwork().toLowerCase()); if (Stargate.maxGates > 0 && netList != null && netList.size() >= Stargate.maxGates) { Stargate.sendMessage(player, Stargate.getString("createFull")); return null; @@ -451,7 +478,7 @@ public class PortalHandler { // Don't do network stuff for bungee gates if (!portal.isBungee()) { // Open any always on gate pointing at this gate - for (String originName : allPortalsNet.get(portal.getNetwork().toLowerCase())) { + for (String originName : allPortalNetworks.get(portal.getNetwork().toLowerCase())) { Portal origin = getByName(originName, portal.getNetwork()); if (origin == null) continue; if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; @@ -513,10 +540,10 @@ public class PortalHandler { * @return

The portal with the given name or null

*/ public static Portal getByName(String name, String network) { - if (!lookupNamesNet.containsKey(network.toLowerCase())) { + if (!portalLookupByNetwork.containsKey(network.toLowerCase())) { return null; } - return lookupNamesNet.get(network.toLowerCase()).get(name.toLowerCase()); + return portalLookupByNetwork.get(network.toLowerCase()).get(name.toLowerCase()); } @@ -695,11 +722,11 @@ public class PortalHandler { */ public static void clearGates() { lookupBlocks.clear(); - lookupNamesNet.clear(); + portalLookupByNetwork.clear(); lookupEntrances.clear(); lookupControls.clear(); allPortals.clear(); - allPortalsNet.clear(); + allPortalNetworks.clear(); } /** @@ -728,16 +755,16 @@ public class PortalHandler { List portalNames = new ArrayList<>(); portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); - lookupNamesNet.keySet().forEach((network) -> lookupNamesNet.get(network).keySet().removeIf((key) -> - portalsToRemove.contains(lookupNamesNet.get(network).get(key)))); + portalLookupByNetwork.keySet().forEach((network) -> portalLookupByNetwork.get(network).keySet().removeIf((key) -> + portalsToRemove.contains(portalLookupByNetwork.get(network).get(key)))); //Remove any networks with no portals - lookupNamesNet.keySet().removeIf((key) -> lookupNamesNet.get(key).isEmpty()); + portalLookupByNetwork.keySet().removeIf((key) -> portalLookupByNetwork.get(key).isEmpty()); lookupEntrances.keySet().removeIf((key) -> portalsToRemove.contains(lookupEntrances.get(key))); lookupControls.keySet().removeIf((key) -> portalsToRemove.contains(lookupControls.get(key))); allPortals.removeIf(portalsToRemove::contains); - allPortalsNet.keySet().forEach((network) -> allPortalsNet.get(network).removeIf(portalNames::contains)); + allPortalNetworks.keySet().forEach((network) -> allPortalNetworks.get(network).removeIf(portalNames::contains)); //Remove any networks with no portals - allPortalsNet.keySet().removeIf((network) -> allPortalsNet.get(network).isEmpty()); + allPortalNetworks.keySet().removeIf((network) -> allPortalNetworks.get(network).isEmpty()); } /** diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index 7a4ab10..3a5bfdd 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.thread; -import net.knarcraft.stargate.BlockChangeRequest; +import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.Stargate; import org.bukkit.Axis; import org.bukkit.Material; diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 104fa26..6db573d 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.utility; -import net.knarcraft.stargate.BlockLocation; -import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; diff --git a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java index 60a6e89..8dd6426 100644 --- a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java +++ b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.WorldMock; +import net.knarcraft.stargate.container.BlockLocation; import org.bukkit.Material; import org.junit.After; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java index f4eb05c..8310474 100644 --- a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java +++ b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate; +import net.knarcraft.stargate.container.RelativeBlockVector; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 94afc86..7e767c9 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -2,7 +2,7 @@ package net.knarcraft.stargate.portal; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.WorldMock; -import net.knarcraft.stargate.RelativeBlockVector; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.Stargate; import org.bukkit.Material; import org.junit.jupiter.api.BeforeAll; From 8835e69e3c96683873c4d735221d9cdceef04932 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 19 Sep 2021 15:05:19 +0200 Subject: [PATCH 092/378] Moves some code from Stargate to EconomyHandler --- .../java/net/knarcraft/stargate/Stargate.java | 79 +-------- .../stargate/listener/BlockEventListener.java | 14 +- .../listener/PlayerEventListener.java | 3 +- .../listener/VehicleEventListener.java | 3 +- .../net/knarcraft/stargate/portal/Gate.java | 5 +- .../stargate/portal/PortalHandler.java | 5 +- .../stargate/utility/EconomyHandler.java | 166 +++++++++++++++--- .../stargate/utility/EconomyHelper.java | 4 +- 8 files changed, 166 insertions(+), 113 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 64f8e92..d0f02a9 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -264,8 +264,11 @@ public class Stargate extends JavaPlugin { return !hasPermission(player, "stargate.world." + world); } - /* - * Check whether player can use network + /** + * Checks whether a player can access the given network + * @param player

The player to check

+ * @param network

The network to check

+ * @return

True if the player is denied from accessing the network

*/ public static boolean cannotAccessNetwork(Player player, String network) { // Can user all stargate player features, or access all networks @@ -273,8 +276,10 @@ public class Stargate extends JavaPlugin { // Do a deep check to see if the player lacks this specific network node return !hasPermDeep(player, "stargate.network." + network); } - // Can access this network - if (hasPermission(player, "stargate.network." + network)) return false; + //Check if the player can access this network + if (hasPermission(player, "stargate.network." + network)) { + return false; + } // Is able to create personal gates (Assumption is made they can also access them) String playerName = player.getName(); if (playerName.length() > 11) playerName = playerName.substring(0, 11); @@ -457,72 +462,6 @@ public class Stargate extends JavaPlugin { return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); } - /* - * Charge player for {action} if required, true on success, false if can't afford - */ - public static boolean chargePlayer(Player player, UUID target, int cost) { - // If cost is 0 - if (cost == 0) return true; - // Economy is disabled - if (!EconomyHandler.useEconomy()) return true; - // Charge player - return EconomyHandler.chargePlayer(player, target, cost); - } - - /* - * Charge player for {action} if required, true on success, false if can't afford - */ - public static boolean chargePlayer(Player player, int cost) { - // If cost is 0 - if (cost == 0) return true; - // Economy is disabled - if (!EconomyHandler.useEconomy()) return true; - // Charge player - return EconomyHandler.chargePlayer(player, cost); - } - - /* - * Determine the cost of a gate - */ - public static int getUseCost(Player player, Portal src, Portal dest) { - // Not using Economy - if (!EconomyHandler.useEconomy()) return 0; - // Portal is free - if (src.isFree()) return 0; - // Not charging for free destinations - if (dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree()) return 0; - // Cost is 0 if the player owns this gate and funds go to the owner - if (src.getGate().getToOwner() && src.isOwner(player)) return 0; - // Player gets free gate use - if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.use")) return 0; - - return src.getGate().getUseCost(); - } - - /* - * Determine the cost to create the gate - */ - public static int getCreateCost(Player player, Gate gate) { - // Not using Economy - if (!EconomyHandler.useEconomy()) return 0; - // Player gets free gate destruction - if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.create")) return 0; - - return gate.getCreateCost(); - } - - /* - * Determine the cost to destroy the gate - */ - public static int getDestroyCost(Player player, Gate gate) { - // Not using Economy - if (!EconomyHandler.useEconomy()) return 0; - // Player gets free gate destruction - if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.destroy")) return 0; - - return gate.getDestroyCost(); - } - /** * Replaces a list of variables in a string in the order they are given * diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 99ff498..cc5eb9e 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateDestroyEvent; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; @@ -89,7 +90,7 @@ public class BlockEventListener implements Listener { Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); } - int cost = Stargate.getDestroyCost(player, portal.getGate()); + int cost = EconomyHandler.getDestroyCost(player, portal.getGate()); //Create and call a StarGateDestroyEvent StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); @@ -128,16 +129,19 @@ public class BlockEventListener implements Listener { BlockBreakEvent event) { int cost = destroyEvent.getCost(); if (cost != 0) { - if (!Stargate.chargePlayer(player, cost)) { + String portalName = portal.getName(); + //Cannot pay + if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { Stargate.debug("onBlockBreak", "Insufficient Funds"); - EconomyHelper.sendInsufficientFundsMessage(portal.getName(), player, cost); + EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); event.setCancelled(true); return false; } + //Tell the player they've paid or deceived money if (cost > 0) { - EconomyHelper.sendDeductMessage(portal.getName(), player, cost); + EconomyHelper.sendDeductMessage(portalName, player, cost); } else { - EconomyHelper.sendRefundMessage(portal.getName(), player, cost); + EconomyHelper.sendRefundMessage(portalName, player, cost); } } return true; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index e8b88de..f7ac066 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.BungeeHelper; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.GameMode; @@ -378,7 +379,7 @@ public class PlayerEventListener implements Listener { } //Player cannot pay for teleportation - int cost = Stargate.getUseCost(player, entrancePortal, destination); + int cost = EconomyHandler.getUseCost(player, entrancePortal, destination); if (cost > 0) { return EconomyHelper.payTeleportFee(entrancePortal, player, cost); } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 5175517..eba8466 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.entity.Entity; @@ -99,7 +100,7 @@ public class VehicleEventListener implements Listener { } //Transfer payment if necessary - int cost = Stargate.getUseCost(player, entrancePortal, destinationPortal); + int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { return; diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 29090a6..55673fc 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -161,7 +161,7 @@ public class Gate { * @return

The cost of creating a portal with this gate

*/ public Integer getCreateCost() { - return createCost < 0 ? EconomyHandler.getCreateCost() : createCost; + return createCost < 0 ? EconomyHandler.getDefaultCreateCost() : createCost; } /** @@ -170,8 +170,7 @@ public class Gate { * @return

The cost of destroying a portal with this gate

*/ public Integer getDestroyCost() { - if (destroyCost < 0) return EconomyHandler.getDestroyCost(); - return destroyCost; + return destroyCost < 0 ? EconomyHandler.getDefaultDestroyCost() : destroyCost; } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 62cb745..ac7f41d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -6,6 +6,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.utility.DirectionHelper; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -395,7 +396,7 @@ public class PortalHandler { portal = new Portal(topLeft, modX, modZ, yaw, id, button, destinationName, name, false, network, gate, player.getUniqueId(), player.getName(), portalOptions); - int cost = Stargate.getCreateCost(player, gate); + int cost = EconomyHandler.getCreateCost(player, gate); // Call StargateCreateEvent StargateCreateEvent cEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); @@ -440,7 +441,7 @@ public class PortalHandler { } if (cost > 0) { - if (!Stargate.chargePlayer(player, cost)) { + if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { EconomyHelper.sendInsufficientFundsMessage(name, player, cost); Stargate.debug("createPortal", "Insufficient Funds"); return null; diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 0a614e2..315996e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -1,6 +1,8 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Gate; +import net.knarcraft.stargate.portal.Portal; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -53,7 +55,7 @@ public final class EconomyHandler { * * @return

The gate creation cost

*/ - public static int getCreateCost() { + public static int getDefaultCreateCost() { return createCost; } @@ -73,7 +75,7 @@ public final class EconomyHandler { * * @return

The gate destruction cost

*/ - public static int getDestroyCost() { + public static int getDefaultDestroyCost() { return destroyCost; } @@ -101,40 +103,32 @@ public final class EconomyHandler { } /** - * Charges a player, giving the charge to a target - * - * @param player

The player to charge

- * @param target

The UUID of the player to pay

- * @param amount

The amount to charge

- * @return

True if the payment succeeded, or if no payment was necessary

+ * Charges the player for an action, if required + * @param player

The player to take money from

+ * @param cost

The cost of the transaction

+ * @return

True if the player was charged successfully

*/ - public static boolean chargePlayer(Player player, UUID target, double amount) { - if (economyEnabled && player.getUniqueId().compareTo(target) != 0 && economy != null) { - if (!economy.has(player, amount)) { - return false; - } - //Take money from the user and give to the owner - economy.withdrawPlayer(player, amount); - economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); + public static boolean chargePlayerIfNecessary(Player player, int cost) { + if (skipPayment(cost)) { + return true; } - return true; + // Charge player + return EconomyHandler.chargePlayer(player, cost); } /** - * Charges a player - * - * @param player

The player to charge

- * @param amount

The amount to charge

- * @return

True if the payment succeeded, or if no payment was necessary

+ * Charges the player for an action, if required + * @param player

The player to take money from

+ * @param target

The target to pay

+ * @param cost

The cost of the transaction

+ * @return

True if the player was charged successfully

*/ - public static boolean chargePlayer(Player player, double amount) { - if (economyEnabled && economy != null) { - if (!economy.has(player, amount)) { - return false; - } - economy.withdrawPlayer(player, amount); + public static boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { + if (skipPayment(cost)) { + return true; } - return true; + // Charge player + return EconomyHandler.chargePlayer(player, target, cost); } /** @@ -188,4 +182,118 @@ public final class EconomyHandler { return economyEnabled && economy != null; } + /** + * Checks whether a payment transaction should be skipped + * @param cost

The cost of the transaction

+ * @return

True if the transaction should be skipped

+ */ + private static boolean skipPayment(int cost) { + return cost == 0 || !EconomyHandler.useEconomy(); + } + + /** + * Determines the cost of using a gate + * + * @param player

The player trying to use the gate

+ * @param source

The source/entry portal

+ * @param destination

The destination portal

+ * @return

The cost of using the portal

+ */ + public static int getUseCost(Player player, Portal source, Portal destination) { + //No payment required + if (!EconomyHandler.useEconomy() || source.isFree()) { + return 0; + } + //Not charging for free destinations + if (destination != null && !EconomyHandler.chargeFreeDestination && destination.isFree()) { + return 0; + } + //Cost is 0 if the player owns this gate and funds go to the owner + if (source.getGate().getToOwner() && source.isOwner(player)) { + return 0; + } + //Player gets free gate use + if (Stargate.hasPermission(player, "stargate.free") || Stargate.hasPermission(player, "stargate.free.use")) { + return 0; + } + + return source.getGate().getUseCost(); + } + + /** + * Gets the cost of creating the given gate + * @param player

The player creating the gate

+ * @param gate

The gate type used

+ * @return

The cost of creating the gate

+ */ + public static int getCreateCost(Player player, Gate gate) { + if (isFree(player, "create")) { + return 0; + } else { + return gate.getCreateCost(); + } + } + + /** + * Gets the cost of destroying the given gate + * @param player

The player creating the gate

+ * @param gate

The gate type used

+ * @return

The cost of destroying the gate

+ */ + public static int getDestroyCost(Player player, Gate gate) { + if (isFree(player, "destroy")) { + return 0; + } else { + return gate.getDestroyCost(); + } + } + + /** + * Determines if a player can do a gate action for free + * @param player

The player to check

+ * @param permissionNode

The free.permissionNode necessary to allow free gate {action}

+ * @return

+ */ + private static boolean isFree(Player player, String permissionNode) { + return !EconomyHandler.useEconomy() || Stargate.hasPermission(player, "stargate.free") || + Stargate.hasPermission(player, "stargate.free." + permissionNode); + } + + /** + * Charges a player + * + * @param player

The player to charge

+ * @param amount

The amount to charge

+ * @return

True if the payment succeeded, or if no payment was necessary

+ */ + private static boolean chargePlayer(Player player, double amount) { + if (economyEnabled && economy != null) { + if (!economy.has(player, amount)) { + return false; + } + economy.withdrawPlayer(player, amount); + } + return true; + } + + /** + * Charges a player, giving the charge to a target + * + * @param player

The player to charge

+ * @param target

The UUID of the player to pay

+ * @param amount

The amount to charge

+ * @return

True if the payment succeeded, or if no payment was necessary

+ */ + private static boolean chargePlayer(Player player, UUID target, double amount) { + if (economyEnabled && player.getUniqueId().compareTo(target) != 0 && economy != null) { + if (!economy.has(player, amount)) { + return false; + } + //Take money from the user and give to the owner + economy.withdrawPlayer(player, amount); + economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); + } + return true; + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 3df2b1f..25db29f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -26,10 +26,10 @@ public final class EconomyHelper { //Try to charge the player if (entrancePortal.getGate().getToOwner()) { - success = entrancePortal.getOwnerUUID() != null && Stargate.chargePlayer(player, + success = entrancePortal.getOwnerUUID() != null && EconomyHandler.chargePlayerIfNecessary(player, entrancePortal.getOwnerUUID(), cost); } else { - success = Stargate.chargePlayer(player, cost); + success = EconomyHandler.chargePlayerIfNecessary(player, cost); } // Insufficient Funds From d5e6f1145c3a53a3a3b4d1cf1307fd09416cc306 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 19 Sep 2021 15:06:41 +0200 Subject: [PATCH 093/378] Removes unused getBalance method --- .../knarcraft/stargate/utility/EconomyHandler.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 315996e..27908aa 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -88,20 +88,6 @@ public final class EconomyHandler { EconomyHandler.destroyCost = destroyCost; } - /** - * Gets the balance (money) of the given player - * - * @param player

The player to get balance for

- * @return

The current balance of the player. Returns 0 if economy is disabled

- */ - public static double getBalance(Player player) { - if (economyEnabled) { - return economy.getBalance(player); - } else { - return 0; - } - } - /** * Charges the player for an action, if required * @param player

The player to take money from

From 8ff30ed03facbd41b0e91fa65ae8b043a7aed7bc Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 19 Sep 2021 17:46:20 +0200 Subject: [PATCH 094/378] Improves config readability, but breaks backwards compatibility --- .../java/net/knarcraft/stargate/Stargate.java | 162 ++++++++++-------- .../net/knarcraft/stargate/portal/Portal.java | 6 +- src/main/resources/config.yml | 98 ++++++----- 3 files changed, 143 insertions(+), 123 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index d0f02a9..6cb4d43 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -12,7 +12,6 @@ import net.knarcraft.stargate.listener.PluginEventListener; import net.knarcraft.stargate.listener.PortalEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; -import net.knarcraft.stargate.portal.Gate; import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; @@ -34,6 +33,7 @@ import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; +import org.bukkit.plugin.messaging.Messenger; import java.io.File; import java.util.HashMap; @@ -41,7 +41,6 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Queue; -import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; import java.util.logging.Logger; @@ -57,9 +56,9 @@ public class Stargate extends JavaPlugin { public static Stargate stargate; public static LanguageLoader languageLoader; public static int maxGates = 0; - public static boolean destMemory = false; + public static boolean rememberDestination = false; public static boolean handleVehicles = true; - public static boolean sortLists = false; + public static boolean sortNetworkDestinations = false; public static boolean protectEntrance = false; public static boolean enableBungee = true; public static boolean verifyPortals = true; @@ -81,9 +80,9 @@ public class Stargate extends JavaPlugin { private static String gateFolder; private static String defaultGateNetwork = "central"; private static boolean destroyExplosion = false; - private static String langName = "en"; + private static String languageName = "en"; private FileConfiguration newConfig; - private PluginManager pm; + private PluginManager pluginManager; public Stargate() { super(); @@ -503,7 +502,7 @@ public class Stargate extends JavaPlugin { @Override public void onEnable() { PluginDescriptionFile pluginDescriptionFile = this.getDescription(); - pm = getServer().getPluginManager(); + pluginManager = getServer().getPluginManager(); newConfig = this.getConfig(); log = Logger.getLogger("Minecraft"); Stargate.server = getServer(); @@ -520,38 +519,31 @@ public class Stargate extends JavaPlugin { log.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); // Register events before loading gates to stop weird things happening. - pm.registerEvents(new PlayerEventListener(), this); - pm.registerEvents(new BlockEventListener(), this); + pluginManager.registerEvents(new PlayerEventListener(), this); + pluginManager.registerEvents(new BlockEventListener(), this); - pm.registerEvents(new VehicleEventListener(), this); - pm.registerEvents(new EntityEventListener(), this); - pm.registerEvents(new PortalEventListener(), this); - pm.registerEvents(new WorldEventListener(), this); - pm.registerEvents(new PluginEventListener(this), this); + pluginManager.registerEvents(new VehicleEventListener(), this); + pluginManager.registerEvents(new EntityEventListener(), this); + pluginManager.registerEvents(new PortalEventListener(), this); + pluginManager.registerEvents(new WorldEventListener(), this); + pluginManager.registerEvents(new PluginEventListener(this), this); this.loadConfig(); // Enable the required channels for Bungee support if (enableBungee) { - Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordListener()); + startStopBungeeListener(true); } // It is important to load languages here, as they are used during reloadGates() - languageLoader = new LanguageLoader(languageFolder, Stargate.langName); + languageLoader = new LanguageLoader(languageFolder, Stargate.languageName); this.migrate(); this.loadGates(); this.loadAllPortals(); // Check to see if Economy is loaded yet. - if (EconomyHandler.setupEconomy(pm)) { - if (EconomyHandler.economy != null) { - String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); - log.info(Stargate.getString("prefix") + - replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); - } - } + setupVaultEconomy(); getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); getServer().getScheduler().runTaskTimer(this, new BlockChangeThread(), 0L, 1L); @@ -574,34 +566,34 @@ public class Stargate extends JavaPlugin { newConfig.options().copyDefaults(true); // Load values into variables - portalFolder = newConfig.getString("portal-folder"); - gateFolder = newConfig.getString("gate-folder"); + portalFolder = newConfig.getString("folders.portalFolder"); + gateFolder = newConfig.getString("folders.gateFolder"); - String defaultNetwork = newConfig.getString("default-gate-network"); + String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; - destroyExplosion = newConfig.getBoolean("destroyexplosion"); - maxGates = newConfig.getInt("maxgates"); - langName = newConfig.getString("lang"); - destMemory = newConfig.getBoolean("destMemory"); - ignoreEntrance = newConfig.getBoolean("ignoreEntrance"); - handleVehicles = newConfig.getBoolean("handleVehicles"); - sortLists = newConfig.getBoolean("sortLists"); - protectEntrance = newConfig.getBoolean("protectEntrance"); - enableBungee = newConfig.getBoolean("enableBungee"); - verifyPortals = newConfig.getBoolean("verifyPortals"); + destroyExplosion = newConfig.getBoolean("gates.destroyedByExplosion"); + maxGates = newConfig.getInt("gates.maxGatesEachNetwork"); + languageName = newConfig.getString("language"); + rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); + ignoreEntrance = newConfig.getBoolean("gates.integrity.ignoreEntrance"); + handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); + sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); + protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); + enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); + verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); // Sign color - loadSignColor(newConfig.getString("signColor")); + loadSignColor(newConfig.getString("gates.cosmetic.signColor")); // Debug - debuggingEnabled = newConfig.getBoolean("debug"); - permissionDebuggingEnabled = newConfig.getBoolean("permdebug"); + debuggingEnabled = newConfig.getBoolean("debugging.debug"); + permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug"); // Economy - EconomyHandler.economyEnabled = newConfig.getBoolean("useeconomy"); - EconomyHandler.setCreateCost(newConfig.getInt("createcost")); - EconomyHandler.setDestroyCost(newConfig.getInt("destroycost")); - EconomyHandler.setUseCost(newConfig.getInt("usecost")); - EconomyHandler.toOwner = newConfig.getBoolean("toowner"); - EconomyHandler.chargeFreeDestination = newConfig.getBoolean("chargefreedestination"); - EconomyHandler.freeGatesGreen = newConfig.getBoolean("freegatesgreen"); + EconomyHandler.economyEnabled = newConfig.getBoolean("economy.useEconomy"); + EconomyHandler.setCreateCost(newConfig.getInt("economy.createCost")); + EconomyHandler.setDestroyCost(newConfig.getInt("economy.destroyCost")); + EconomyHandler.setUseCost(newConfig.getInt("economy.useCost")); + EconomyHandler.toOwner = newConfig.getBoolean("economy.toOwner"); + EconomyHandler.chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination"); + EconomyHandler.freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen"); this.saveConfig(); } @@ -618,8 +610,7 @@ public class Stargate extends JavaPlugin { } catch (IllegalArgumentException | NullPointerException ignored) { } } - log.warning(Stargate.getString("prefix") + "You have specified an invalid color in your config.yml." + - " Defaulting to BLACK"); + log.warning(getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); Stargate.signColor = ChatColor.BLACK; } @@ -664,7 +655,7 @@ public class Stargate extends JavaPlugin { * Check if a plugin is loaded/enabled already. Returns the plugin if so, null otherwise */ private Plugin checkPlugin(String p) { - Plugin plugin = pm.getPlugin(p); + Plugin plugin = pluginManager.getPlugin(p); return checkPlugin(plugin); } @@ -683,8 +674,8 @@ public class Stargate extends JavaPlugin { */ public void reload(CommandSender sender) { // Deactivate portals - for (Portal p : activeList) { - p.deactivate(); + for (Portal activePortal : activeList) { + activePortal.deactivate(); } // Close portals closeAllPortals(); @@ -701,36 +692,57 @@ public class Stargate extends JavaPlugin { loadConfig(); loadGates(); loadAllPortals(); - languageLoader.setChosenLanguage(langName); + languageLoader.setChosenLanguage(languageName); 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; - } + //Load Economy support if enabled/clear if disabled + reloadEconomy(); - // Enable the required channels for Bungee support + //Enable or disable 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"); - } + startStopBungeeListener(enableBungee); } sendMessage(sender, "stargate reloaded"); } + /** + * Reloads economy by enabling or disabling it as necessary + */ + private void reloadEconomy() { + if (EconomyHandler.economyEnabled && EconomyHandler.economy == null) { + setupVaultEconomy(); + } else if (!EconomyHandler.economyEnabled) { + EconomyHandler.vault = null; + EconomyHandler.economy = null; + } + } + + /** + * Loads economy from Vault + */ + private void setupVaultEconomy() { + if (EconomyHandler.setupEconomy(pluginManager) && EconomyHandler.economy != null) { + String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + log.info(Stargate.getString("prefix") + Stargate.replaceVars( + Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + } + } + + /** + * Starts the listener for listening to BungeeCord messages + */ + private void startStopBungeeListener(boolean start) { + Messenger messenger = Bukkit.getMessenger(); + String bungeeChannel = "BungeeCord"; + + if (start) { + messenger.registerOutgoingPluginChannel(this, bungeeChannel); + messenger.registerIncomingPluginChannel(this, bungeeChannel, new BungeeCordListener()); + } else { + messenger.unregisterIncomingPluginChannel(this, bungeeChannel); + messenger.unregisterOutgoingPluginChannel(this, bungeeChannel); + } + } + } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 839a881..001634c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -1029,10 +1029,10 @@ public class Portal { activePlayer = player; String network = getNetwork(); destinations = PortalHandler.getDestinations(this, player, network); - if (Stargate.sortLists) { + if (Stargate.sortNetworkDestinations) { Collections.sort(destinations); } - if (Stargate.destMemory && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { + if (Stargate.rememberDestination && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { destination = lastDestination; } @@ -1113,7 +1113,7 @@ public class Portal { return; } - if (!Stargate.destMemory || !activate || lastDestination.isEmpty()) { + if (!Stargate.rememberDestination || !activate || lastDestination.isEmpty()) { cycleDestination(direction); } openTime = System.currentTimeMillis() / 1000; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 75997b3..605386f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,54 +1,62 @@ # stargate Configuration File # Main stargate config -# -# portal-folder - The folder for storing portals -# gate-folder - The folder for storing gate layouts -# default-gate-network - The default gate network -# destroyexplosion - Whether or not to destroy gates with explosions (Creeper, TNT, etc) -# maxgates - The maximum number of gates allowed on a network - 0 for unlimited -# lang - The language file to load for messages -# destMemory - Whether to remember the cursor location between uses +# I----------I----------I # +# portalFolder - The folder for storing portals +# gateFolder - The folder for storing gate layouts +# defaultGateNetwork - The default gate network +# destroyedByExplosion - Whether to destroy gates with explosions (Creeper, TNT, etc.) +# maxGatesEachNetwork - The maximum number of gates allowed on a network - 0 for unlimited +# language - The language file to load for messages +# rememberDestination - Whether to remember the cursor location between uses # ignoreEntrance - Ignore the entrance blocks of a gate when checking. Used to work around snowmen # handleVehicles - Whether to allow vehicles through gates -# sortLists - Whether to sort network lists alphabetically +# sortNetworkDestinations - Whether to sort network lists alphabetically # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) # signColor - The color used for drawing signs (Default: BLACK). -# verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when a stargate is loaded. -############################ +# verifyPortals - Whether all the non-sign blocks are checked to match the gate layout when a stargate is loaded. +# I------------I-------------I # # stargate economy options # -############################ -# useeconomy - Whether to use an economy plugin -# createcost - The cost to create a gate -# destroycost - The cost to destroy a gate -# usecost - The cost to use a gate -# toowner - Whether the charge for using a gate goes to the gates owner -# chargefreedestination - Whether a gate whose destination is a free gate is still charged -# freegatesgreen - Whether a free gate in the destination list is drawn green -################# +# I------------I-------------I # +# useEconomy - Whether to use an economy plugin +# createCost - The cost to create a gate +# destroyCost - The cost to destroy a gate +# useCost - The cost to use a gate +# toOwner - Whether the charge for using a gate goes to the gate's owner +# chargeFreeDestination - Whether a gate whose destination is a free gate is still charged +# freeGatesGreen - Whether a free gate in the destination list is drawn green +# I-------I-------I # # Debug options # -################# +# I-------I-------I # # debug - Debug -- Only enable if you have issues, massive console output -# permdebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) -portal-folder: plugins/stargate/portals/ -gate-folder: plugins/stargate/gates/ -default-gate-network: central -destroyexplosion: false -maxgates: 0 -lang: en -destMemory: false -ignoreEntrance: false -handleVehicles: true -sortLists: false -protectEntrance: false -signColor: BLACK -useeconomy: false -createcost: 0 -destroycost: 0 -usecost: 0 -toowner: false -chargefreedestination: true -freegatesgreen: false -debug: false -permdebug: false -enableBungee: false -verifyPortals: false \ No newline at end of file +# permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) + +language: en +folders: + portalFolder: plugins/stargate/portals/ + gateFolder: plugins/stargate/gates/ +gates: + maxGatesEachNetwork: 0 + defaultGateNetwork: central + cosmetic: + rememberDestination: false + sortNetworkDestinations: false + signColor: BLACK + integrity: + destroyedByExplosion: false + verifyPortals: false + protectEntrance: false + ignoreEntrance: false + functionality: + enableBungee: false + handleVehicles: true +economy: + useEconomy: false + createCost: 0 + destroyCost: 0 + useCost: 0 + toOwner: false + chargeFreeDestination: true + freeGatesGreen: false +debugging: + debug: false + permissionDebug: false \ No newline at end of file From f12306426bf8e853074559413fb1e6d373d9c25b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 13:46:20 +0200 Subject: [PATCH 095/378] Renames strings in onCommand to args for consistency --- .../knarcraft/stargate/command/CommandReload.java | 2 +- .../knarcraft/stargate/command/CommandStarGate.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index 2d4ea4d..dfd3d74 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -25,7 +25,7 @@ public class CommandReload implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, - @NotNull String[] strings) { + @NotNull String[] args) { if (commandSender instanceof Player) { Player player = (Player) commandSender; if (!player.hasPermission("stargate.reload")) { diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index 182e4c8..e94fe6a 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -28,12 +28,12 @@ public class CommandStarGate implements CommandExecutor { @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); + @NotNull String[] args) { + if (args.length > 0) { + if (args[0].equalsIgnoreCase("about")) { + return new CommandAbout().onCommand(commandSender, command, s, args); + } else if (args[0].equalsIgnoreCase("reload")) { + return new CommandReload(plugin).onCommand(commandSender, command, s, args); } return false; } else { From b57f988b62430009b128e88c9e0011f546de2f4f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 13:48:03 +0200 Subject: [PATCH 096/378] Improves formatting for some files --- README.md | 875 ++++++++++++------ pom.xml | 101 +- src/main/resources/config.yml | 18 +- src/main/resources/plugin.yml | 4 +- .../stargate/portal/GateLayoutTest.java | 11 +- 5 files changed, 639 insertions(+), 370 deletions(-) diff --git a/README.md b/README.md index ee9d14c..3f3535d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Description -Create gates that allow for instant-teleportation between large distances. Gates can be always-open or triggered; they can share a network or be split into clusters; they can be hidden on a network or accessible to everybody. + +Create gates that allow for instant-teleportation between large distances. Gates can be always-open or triggered; they +can share a network or be split into clusters; they can be hidden on a network or accessible to everybody. - Player permissions -- let players build their own networks. - Vault economy support -- can add costs for create, destroy and use. @@ -7,11 +9,13 @@ Create gates that allow for instant-teleportation between large distances. Gates - Message customization ## Background -This was originally TheDgtl's Bukkit port of the Stargate plugin for hMod by Dinnerbone. -This is a fork of [PseudoKnight's fork](https://github.com/PseudoKnight/Stargate-Bukkit). -This fork's main purpose is to create a clean version of Stargate compliant with Spigot 1.16, even if it means changing the entire project's previous structure. + +This was originally TheDgtl's Bukkit port of the Stargate plugin for hMod by Dinnerbone. This is a fork +of [PseudoKnight's fork](https://github.com/PseudoKnight/Stargate-Bukkit). This fork's main purpose is to create a clean +version of Stargate compliant with Spigot 1.16, even if it means changing the entire project's previous structure. # Permissions + ``` stargate.use -- Allow use of all gates linking to any world in any network (Override ALL network/world permissions. Set to false to use network/world specific permissions) stargate.world -- Allow use of gates linking to any world @@ -51,7 +55,9 @@ stargate.admin -- Allow all admin features (Hidden/Private only so far) stargate.admin.hidden -- Allow access to Hidden gates not ownerd by user stargate.admin.reload -- Allow use of /sg reload ``` + ## Default Permissions + ``` stargate.use -- Everyone stargate.create -- Op @@ -62,8 +68,11 @@ stargate.admin -- Op ``` # Instructions + ## Building a gate: + This is the default gate configuration. See the Custom Gate Layout section on how to change this. + ``` OO O O - These are Obsidian blocks. You need 10. @@ -78,44 +87,55 @@ This is the default gate configuration. See the Custom Gate Layout section on ho - Line 2: Destination Name \[Optional] (Max 12 characters, used for fixed-gates only) - Line 3: Network name \[Optional] (Max 12 characters) - Line 4: Options \[Optional] : - - 'A' for always-on fixed gate - - 'H' for hidden networked gate - - 'P' for a private gate - - 'F' for a free gate - - 'B' is for a backwards facing gate (You will exit the back) - - 'S' is for showing an always-on gate in the network list - - 'N' is for hiding the network name - - 'R' is for random gates. These follow standard permissions of gates, but have a random exit location every time a player enters. - - 'U' is for a gate connecting to another through bungee + - 'A' for always-on fixed gate + - 'H' for hidden networked gate + - 'P' for a private gate + - 'F' for a free gate + - 'B' is for a backwards facing gate (You will exit the back) + - 'S' is for showing an always-on gate in the network list + - 'N' is for hiding the network name + - 'R' is for random gates. These follow standard permissions of gates, but have a random exit location every time a + player enters. + - 'U' is for a gate connecting to another through bungee The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. #### Gate networks: - - Gates are all part of a network, by default this is "central". - - You can specify (and create) your own network on the third line of the sign when making a new gate. - - Gates on one network will not see gates on the second network, and vice versa. - - Gates on different worlds, but in the same network, will see each other. - - If the gate is a bungee gate, the network name should be the name of the server as displayed when typing /servers + +- Gates are all part of a network, by default this is "central". +- You can specify (and create) your own network on the third line of the sign when making a new gate. +- Gates on one network will not see gates on the second network, and vice versa. +- Gates on different worlds, but in the same network, will see each other. +- If the gate is a bungee gate, the network name should be the name of the server as displayed when typing /servers #### Fixed gates: - - Fixed gates go to only one set destination. - - Fixed gates can be linked to other fixed gates, or normal gates. A normal gate cannot open a portal to a fixed gate however. - - To create a fixed gate, specify a destination on the second line of the stargate sign. - - Set the 4th line of the stargate sign to "A" to enable an always-open fixed gate. - - A bungee gate is always automatically a fixed gate - + +- Fixed gates go to only one set destination. +- Fixed gates can be linked to other fixed gates, or normal gates. A normal gate cannot open a portal to a fixed gate + however. +- To create a fixed gate, specify a destination on the second line of the stargate sign. +- Set the 4th line of the stargate sign to "A" to enable an always-open fixed gate. +- A bungee gate is always automatically a fixed gate + #### Hidden Gates: - - Hidden gates are like normal gates, but only show on the destination list of other gates under certain conditions. - - A hidden gate is only visible to the creator of the gate, or somebody with the stargate.hidden permission. - - Set the 4th line of the stargate sign to 'H' to make it a hidden gate. + +- Hidden gates are like normal gates, but only show on the destination list of other gates under certain conditions. +- A hidden gate is only visible to the creator of the gate, or somebody with the stargate.hidden permission. +- Set the 4th line of the stargate sign to 'H' to make it a hidden gate. ## Using a gate: - - Right click the sign to choose a destination. - - Right click the button to open up a portal. - - Step through. - + +- Right click the sign to choose a destination. +- Right click the button to open up a portal. +- Step through. + ## Economy Support: -The latest version of Stargate has support for Vault. Gate creation, destruction and use can all have different costs associated with them. You can also define per-gate layout costs. The default cost is assigned in the config.yml file, while the per-gate costs re defined in the .gate files. To define a certain cost to a gate just add these lines to your .gate file: + +The latest version of Stargate has support for Vault. Gate creation, destruction and use can all have different costs +associated with them. You can also define per-gate layout costs. The default cost is assigned in the config.yml file, +while the per-gate costs re defined in the .gate files. To define a certain cost to a gate just add these lines to your +.gate file: + ``` usecost=5 destroycost=5 @@ -124,9 +144,11 @@ toowner=true ``` # Custom Gate Layout + You can create as many gate formats as you want, the gate layouts are stored in `plugins/Stargate/gates/`. -The .gate file must be laid out a specific way, the first lines will be config information, -and after a blank line you will lay out the gate format. Here is the default nether.gate file: +The .gate file must be laid out a specific way, the first lines will be config information, and after a blank line you +will lay out the gate format. Here is the default nether.gate file: + ``` portal-open=NETHER_PORTAL portal-closed=AIR @@ -140,18 +162,21 @@ X..X X*.X XX ``` -The keys `portal-open` and `portal-closed` are used to define the material in the gate when it is open or closed. -The material for `portal-closed` can be most things, including solid blocks. Some materials may act weirdly though. -The material for `portal-open` can be any block the player can partially enter, even things like `GLOW_LICHEN`. + +The keys `portal-open` and `portal-closed` are used to define the material in the gate when it is open or closed. The +material for `portal-closed` can be most things, including solid blocks. Some materials may act weirdly though. The +material for `portal-open` can be any block the player can partially enter, even things like `GLOW_LICHEN`. `NETHER_PORTAL` and `END_GATEWAY` work, but `END_PORTAL` does not. -The key `button` is used to define the type of button that is generated for this gate. It can be a button (of any type), +The key `button` is used to define the type of button that is generated for this gate. It can be a button (of any type), a type of wall coral (dead or alive), a type of shulker box or a chest. `X` and `-` are used to define block types for the layout (Any single-character can be used, such as `#`). In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. -You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will teleport in front of. +You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will +teleport in front of. ## Buttons + The actual buttons cannot be used underwater, but all the other items in the button list can be.
The entire list of button types is as follows: (Click to expand) @@ -197,16 +222,19 @@ DEAD_BUBBLE_CORAL_WALL_FAN DEAD_FIRE_CORAL_WALL_FAN DEAD_HORN_CORAL_WALL_FAN ``` +
## Underwater Portals + There is a default gate type for underwater gates. There are no real restrictions on underwater gate materials, except -normal buttons cannot be used since they'd fall off. Using wall coral fans work much better, though `CHEST` and +normal buttons cannot be used since they'd fall off. Using wall coral fans work much better, though `CHEST` and `SHULKER_BOX` works too. Using `AIR` for a closed underwater gate looks weird, so `WATER` might be better. # Configuration + ``` default-gate-network - The default gate network portal-folder - The folder your portal databases are saved in @@ -234,13 +262,16 @@ permdebug: Whether to show massive permission debug output ``` # Message Customization -It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/lang/chosenLanguage.txt. -If a string is removed, or left blank, it will default to the default english string. -There are some special cases when it comes to messages. -When you see %variableName%, you need to keep this part in your string, as it will be replaced with relevant values. +It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the +strings in plugins/Stargate/lang/chosenLanguage.txt. + +If a string is removed, or left blank, it will default to the default english string. There are some special cases when +it comes to messages. When you see %variableName%, you need to keep this part in your string, as it will be replaced +with relevant values. The full list of strings is as follows: + ``` prefix=[Stargate] teleportMsg=Teleported @@ -278,379 +309,617 @@ bungeeDeny=You do not have permission to create BungeeCord gates. bungeeEmpty=BungeeCord gates require both a destination and network. bungeeSign=Teleport to ``` + # Changes + #### \[Version 0.9.0.0] (WIP) EpicKnarvik97 fork - - Changes entire path structure to a more modern and maven-compliant one - - Changes package structure to net.knarcaft.stargate.* - - Moves language files into the resources folder - - Fixes some bugs caused by language files not being read as UTF-8 - - Makes Blox into BlockLocation which now extends Location - - Adds JavaDoc to a lot of the code - - Adds Norwegian translation for both Norwegian languages - - Adds missing dependency information to plugin.yml - - Uses text from the language files in more places - - Changes how backup language works, causing english strings to be shown if not available from the chosen language - - Removes some pre-UUID code - - Adds underwater portals - - Makes it easier to add more default gates - - Adds a new default gate which can be used underwater - - Adds more items usable as buttons (corals, chest, shulker box), which allows underwater portals - - Splits a lot of the code into smaller objects - - Moves duplicated code into helper classes + +- Changes entire path structure to a more modern and maven-compliant one +- Changes package structure to net.knarcaft.stargate.* +- Moves language files into the resources folder +- Fixes some bugs caused by language files not being read as UTF-8 +- Makes Blox into BlockLocation which now extends Location +- Adds JavaDoc to a lot of the code +- Adds Norwegian translation for both Norwegian languages +- Adds missing dependency information to plugin.yml +- Uses text from the language files in more places +- Changes how backup language works, causing english strings to be shown if not available from the chosen language +- Removes some pre-UUID code +- Adds underwater portals +- Makes it easier to add more default gates +- Adds a new default gate which can be used underwater +- Adds more items usable as buttons (corals, chest, shulker box), which allows underwater portals +- Splits a lot of the code into smaller objects +- Moves duplicated code into helper classes + #### \[Version 0.8.0.3] PseudoKnight fork - - Fix economy - - Add custom buttons + +- Fix economy +- Add custom buttons + #### \[Version 0.8.0.2] PseudoKnight fork - - Fix player relative yaw when exiting portal - - Add color code support in lang files + +- Fix player relative yaw when exiting portal +- Add color code support in lang files + #### \[Version 0.8.0.1] PseudoKnight fork - - Fix slab check for portal exits - - Improve material checks for gate configuration + +- Fix slab check for portal exits +- Improve material checks for gate configuration + #### \[Version 0.8.0.0] PseudoKnight fork - - Update for 1.13/1.14 compatibility. This changes gate layouts to use new material names instead of numeric ids. You need to update your gate layout configs. - - Adds "verifyPortals" config option, which sets whether an old stargate's blocks are verified when loaded. - - Adds UUID support. (falls back to player names) + +- Update for 1.13/1.14 compatibility. This changes gate layouts to use new material names instead of numeric ids. You + need to update your gate layout configs. +- Adds "verifyPortals" config option, which sets whether an old stargate's blocks are verified when loaded. +- Adds UUID support. (falls back to player names) + #### \[Version 0.7.9.11] PseudoKnight fork - - Removed iConomy support. Updated Vault support. Changed setting from "useiconomy" to "useeconomy". - - Updated to support Metrics for 1.7.10 + +- Removed iConomy support. Updated Vault support. Changed setting from "useiconomy" to "useeconomy". +- Updated to support Metrics for 1.7.10 + #### \[Version 0.7.9.10] - - Fix personal gate permission check for players with mixed-case names + +- Fix personal gate permission check for players with mixed-case names + #### \[Version 0.7.9.9] - - Remove "Permissions" support, we now only support SuperPerms handlers. + +- Remove "Permissions" support, we now only support SuperPerms handlers. + #### \[Version 0.7.9.8] - - Make sure buttons stay where they should + +- Make sure buttons stay where they should + #### \[Version 0.7.9.7] - - Do the Bungee check after the gate layout check. + +- Do the Bungee check after the gate layout check. + #### \[Version 0.7.9.6] - - Actually remove the player from the BungeeQueue when they connect. Oops :) - - Implement stargate.server nodes - - Improve the use of negation. You can now negate networks/worlds/servers while using stargate.use permissions. + +- Actually remove the player from the BungeeQueue when they connect. Oops :) +- Implement stargate.server nodes +- Improve the use of negation. You can now negate networks/worlds/servers while using stargate.use permissions. + #### \[Version 0.7.9.5] - - Fixed an issue with portal material not showing up (Oh, that code WAS useful) + +- Fixed an issue with portal material not showing up (Oh, that code WAS useful) + #### \[Version 0.7.9.4] - - Fixed an issue where water gates broke, oops + +- Fixed an issue where water gates broke, oops + #### \[Version 0.7.9.3] - - Update BungeeCord integration for b152+ + +- Update BungeeCord integration for b152+ + #### \[Version 0.7.9.2] - - Remove my custom sign class. Stupid Bukkit team. - - Will work with CB 1.4.5 builds, but now will break randomly due to Bukkit screwup - - Update MetricsLite to R6 + +- Remove my custom sign class. Stupid Bukkit team. +- Will work with CB 1.4.5 builds, but now will break randomly due to Bukkit screwup +- Update MetricsLite to R6 + #### \[Version 0.7.9.1] - - Optimize gate lookup in onPlayerMove - - Resolve issue where Stargates would teleport players to the nether + +- Optimize gate lookup in onPlayerMove +- Resolve issue where Stargates would teleport players to the nether + #### \[Version 0.7.9.0] - - Added BungeeCord multi-server support (Requires Stargate-Bungee for BungeeCord) - - Updated Spanish language file - - Added basic plugin metrics via http://mcstats.org/ - - Resolve issue where language updating overwrote custom strings + +- Added BungeeCord multi-server support (Requires Stargate-Bungee for BungeeCord) +- Updated Spanish language file +- Added basic plugin metrics via http://mcstats.org/ +- Resolve issue where language updating overwrote custom strings + #### \[Version 0.7.8.1] - - Resolve issue of language file being overwritten as ANSI instead of UTF8 + +- Resolve issue of language file being overwritten as ANSI instead of UTF8 + #### \[Version 0.7.8.0] - - Updated languages to include sign text (Please update any languages you are able!) - - Resolved NPE due to Bukkit bug with signs - - Resolved issue regarding new getTargetBlock code throwing an exception - - Languages now auto-update based on the .JAR version (New entries only, doesn't overwrite customization) - - New command "/sg about", will list the author of the current language file if available - - Language now has a fallback to English for missing lines (It's the only language I can personally update on release) - - Added Spanish (Thanks Manuestaire) and Hungarian (Thanks HPoltergeist) - - Added portal.setOwner(String) API + +- Updated languages to include sign text (Please update any languages you are able!) +- Resolved NPE due to Bukkit bug with signs +- Resolved issue regarding new getTargetBlock code throwing an exception +- Languages now auto-update based on the .JAR version (New entries only, doesn't overwrite customization) +- New command "/sg about", will list the author of the current language file if available +- Language now has a fallback to English for missing lines (It's the only language I can personally update on release) +- Added Spanish (Thanks Manuestaire) and Hungarian (Thanks HPoltergeist) +- Added portal.setOwner(String) API + #### \[Version 0.7.7.5] - - Resolve issue of right clicking introduced in 1.3.1/2 + +- Resolve issue of right clicking introduced in 1.3.1/2 + #### \[Version 0.7.7.4] - - Removed try/catch, it was still segfaulting. - - Built against 1.3.1 + +- Removed try/catch, it was still segfaulting. +- Built against 1.3.1 + #### \[Version 0.7.7.3] - - Wrap sign changing in try/catch. Stupid Bukkit + +- Wrap sign changing in try/catch. Stupid Bukkit + #### \[Version 0.7.7.2] - - Load chunk before trying to draw signs - - Implement a workaround for BUKKIT-1033 + +- Load chunk before trying to draw signs +- Implement a workaround for BUKKIT-1033 + #### \[Version 0.7.7.1] - - Permission checking for 'R'andom gates. - - Random now implies AlwaysOn - - Added all languages to JAR + +- Permission checking for 'R'andom gates. +- Random now implies AlwaysOn +- Added all languages to JAR + #### \[Version 0.7.7.0] - - Added 'R'andom option - This still follows the permission rules defined for normal gate usage - - Added a bit more debug output + +- Added 'R'andom option - This still follows the permission rules defined for normal gate usage +- Added a bit more debug output + #### \[Version 0.7.6.8] - - Hopefully fix backwards gate exiting + +- Hopefully fix backwards gate exiting + #### \[Version 0.7.6.7] - - Reload all gates on world unload, this stops gates with invalid destinations being in memory. + +- Reload all gates on world unload, this stops gates with invalid destinations being in memory. + #### \[Version 0.7.6.6] - - Check move/portal/interact/signchange events for cancellation + +- Check move/portal/interact/signchange events for cancellation + #### \[Version 0.7.6.5] - - Resolve issue with buttons on glass gates falling off - - /sg reload can now be used ingame (stargate.admin.reload permission) + +- Resolve issue with buttons on glass gates falling off +- /sg reload can now be used ingame (stargate.admin.reload permission) + #### \[Version 0.7.6.4] - - Move blockBreak to HIGHEST priority, this resolves issues with region protection plugins + +- Move blockBreak to HIGHEST priority, this resolves issues with region protection plugins + #### \[Version 0.7.6.3] - - Fixed issue with displaying iConomy prices - - iConomy is now hooked on "sg reload" if not already hooked and enabled - - iConomy is now unhooked on "sg reload" if hooked and disabled + +- Fixed issue with displaying iConomy prices +- iConomy is now hooked on "sg reload" if not already hooked and enabled +- iConomy is now unhooked on "sg reload" if hooked and disabled + #### \[Version 0.7.6.2] - - Button now activates if gate is opened, allowing redstone interaction - - Fixed issue with sign line lengths. All sign text should now fit with color codes. + +- Button now activates if gate is opened, allowing redstone interaction +- Fixed issue with sign line lengths. All sign text should now fit with color codes. + #### \[Version 0.7.6.1] - - Update API for StargateCommand - - Resolved issue with block data on explosion - - Added signColor option - - Added protectEntrance option + +- Update API for StargateCommand +- Resolved issue with block data on explosion +- Added signColor option +- Added protectEntrance option + #### \[Version 0.7.6] - - Moved gate opening/closing to a Queue/Runnable system to resolve server lag issues with very large gates + +- Moved gate opening/closing to a Queue/Runnable system to resolve server lag issues with very large gates + #### \[Version 0.7.5.11] - - PEX now returns accurate results without requiring use of the bridge. + +- PEX now returns accurate results without requiring use of the bridge. + #### \[Version 0.7.5.10] - - Added sortLists options + +- Added sortLists options + #### \[Version 0.7.5.9] - - Quick event fix for latest dev builds - - Fix for sign ClassCastException + +- Quick event fix for latest dev builds +- Fix for sign ClassCastException + #### \[Version 0.7.5.8] - - Fixed an exploit with pistons to destroy gates + +- Fixed an exploit with pistons to destroy gates + #### \[Version 0.7.5.7] - - Removed SignPost class - - Resolved issues with signs in 1.2 + +- Removed SignPost class +- Resolved issues with signs in 1.2 + #### \[Version 0.7.5.6] - - Quick update to the custom event code, works with R5+ now. + +- Quick update to the custom event code, works with R5+ now. + #### \[Version 0.7.5.5] - - PEX is built of fail, if we have it, use bridge instead. + +- PEX is built of fail, if we have it, use bridge instead. + #### \[Version 0.7.5.4] - - Fix issue with private gates for players with long names + +- Fix issue with private gates for players with long names + #### \[Version 0.7.5.3] - - Added another check for Perm bridges. + +- Added another check for Perm bridges. + #### \[Version 0.7.5.2] - - Make sure our timer is stopped on disable - - Move Event reg before loading gates to stop portal material vanishing + +- Make sure our timer is stopped on disable +- Move Event reg before loading gates to stop portal material vanishing + #### \[Version 0.7.5.1] - - Don't create button on failed creation + +- Don't create button on failed creation + #### \[Version 0.7.5.0] - - Refactored creation code a bit - - Added StargateCreateEvent, see Stargate-API for usage. - - Added StargateDestroyEvent, see Stargate-API for usage. - - Updated Event API to the new standard, please see: http://wiki.bukkit.org/Introduction_to_the_New_Event_System - - Added handleVehicles option. - - Added 'N'o Network option (Hides the network from the sign) + +- Refactored creation code a bit +- Added StargateCreateEvent, see Stargate-API for usage. +- Added StargateDestroyEvent, see Stargate-API for usage. +- Updated Event API to the new standard, please see: http://wiki.bukkit.org/Introduction_to_the_New_Event_System +- Added handleVehicles option. +- Added 'N'o Network option (Hides the network from the sign) + #### \[Version 0.7.4.4] - - Changed the implementation of StargateAccessEvent. - - Disable Permissions if version is 2.7.2 (Common version used between bridges) - - Fix long-standing bug with hasPermDeep check. Oops. + +- Changed the implementation of StargateAccessEvent. +- Disable Permissions if version is 2.7.2 (Common version used between bridges) +- Fix long-standing bug with hasPermDeep check. Oops. + #### \[Version 0.7.4.3] - - Implement StargateAccessEvent, used for bypassing permission checks/denying access to gates. + +- Implement StargateAccessEvent, used for bypassing permission checks/denying access to gates. + #### \[Version 0.7.4.2] - - stargate.create.personal permission now also allows user to use personal gates + +- stargate.create.personal permission now also allows user to use personal gates + #### \[Version 0.7.4.1] - - Quick API update to add player to the activate event + +- Quick API update to add player to the activate event + #### \[Version 0.7.4.0] - - Fixed issue with non-air closed portal blocks - - Added StargatePortalEvent/onStargatePortal event + +- Fixed issue with non-air closed portal blocks +- Added StargatePortalEvent/onStargatePortal event + #### \[Version 0.7.3.3] - - Added "ignoreEntrance" option to not check entrance to gate on integrity check (Workaround for snowmen until event is pulled) + +- Added "ignoreEntrance" option to not check entrance to gate on integrity check (Workaround for snowmen until event is + pulled) + #### \[Version 0.7.3.2] - - Actually fixed "><" issue with destMemory + +- Actually fixed "><" issue with destMemory + #### \[Version 0.7.3.1] - - Hopefully fixed "><" issue with destMemory + +- Hopefully fixed "><" issue with destMemory + #### \[Version 0.7.3] - - Lava and water gates no longer destroy on reload - - "sg reload" now closes gates before reloading - - Added Vault support - - Added missing "useiConomy" option in config + +- Lava and water gates no longer destroy on reload +- "sg reload" now closes gates before reloading +- Added Vault support +- Added missing "useiConomy" option in config + #### \[Version 0.7.2.1] - - Quick fix for an NPE + +- Quick fix for an NPE + #### \[Version 0.7.2] - - Make it so you can still destroy gates in Survival mode + +- Make it so you can still destroy gates in Survival mode + #### \[Version 0.7.1] - - Added destMemory option - - Switched to sign.update() as Bukkit implemented my fix - - Threw in a catch for a null from location for portal events + +- Added destMemory option +- Switched to sign.update() as Bukkit implemented my fix +- Threw in a catch for a null from location for portal events + #### \[Version 0.7.0] - - Minecraft 1.0.0 support - - New FileConfiguration implemented - - Stop gates being destroyed on right-click in Creative mode - - Fixed signs not updating with a hackish workaround until Bukkit is fixed + +- Minecraft 1.0.0 support +- New FileConfiguration implemented +- Stop gates being destroyed on right-click in Creative mode +- Fixed signs not updating with a hackish workaround until Bukkit is fixed + #### \[Version 0.6.10] - - Added Register support as opposed to iConomy + +- Added Register support as opposed to iConomy + #### \[Version 0.6.9] - - Added UTF8 support for lang files (With or without BOM) + +- Added UTF8 support for lang files (With or without BOM) + #### \[Version 0.6.8] - - Fixed unmanned carts losing velocity through gates - - /sg reload now properly switches languages + +- Fixed unmanned carts losing velocity through gates +- /sg reload now properly switches languages + #### \[Version 0.6.7] - - Added lang option - - Removed language debug output - - Added German language (lang=de) -- Thanks EduardBaer + +- Added lang option +- Removed language debug output +- Added German language (lang=de) -- Thanks EduardBaer + #### \[Version 0.6.6] - - Added %cost% and %portal% to all eco* messages - - Fixed an issue when creating a gate on a network you don't have access to + +- Added %cost% and %portal% to all eco* messages +- Fixed an issue when creating a gate on a network you don't have access to + #### \[Version 0.6.5] - - Moved printed message config to a seperate file - - Added permdebug option - - Hopefully fix path issues some people were having - - Fixed iConomy creation cost - - Added 'S'how option for Always-On gates - - Added 'stargate.create.gate' permissions + +- Moved printed message config to a seperate file +- Added permdebug option +- Hopefully fix path issues some people were having +- Fixed iConomy creation cost +- Added 'S'how option for Always-On gates +- Added 'stargate.create.gate' permissions + #### \[Version 0.6.4] - - Fixed iConomy handling + +- Fixed iConomy handling + #### \[Version 0.6.3] - - Fixed (Not Connected) showing on inter-world gate loading - - Added the ability to negate Network/World permissions (Use, Create and Destroy) - - Fixed Lockette compatibility - - More stringent verification checks + +- Fixed (Not Connected) showing on inter-world gate loading +- Added the ability to negate Network/World permissions (Use, Create and Destroy) +- Fixed Lockette compatibility +- More stringent verification checks + #### \[Version 0.6.2] - - Fixed an issue with private gates - - Added default permissions + +- Fixed an issue with private gates +- Added default permissions + #### \[Version 0.6.1] - - Stop destruction of open gates on startup + +- Stop destruction of open gates on startup + #### \[Version 0.6.0] - - Completely re-wrote Permission handling (REREAD/REDO YOUR PERMISSIONS!!!!!!!!) - - Added custom Stargate events (See Stargate-DHD code for use) - - Fixed portal event cancellation - - Umm... Lots of other small things. + +- Completely re-wrote Permission handling (REREAD/REDO YOUR PERMISSIONS!!!!!!!!) +- Added custom Stargate events (See Stargate-DHD code for use) +- Fixed portal event cancellation +- Umm... Lots of other small things. + #### \[Version 0.5.5] - - Added 'B'ackwards option - - Fixed opening of gates with a fixed gate as a destination - - Added block metadata support to gates + +- Added 'B'ackwards option +- Fixed opening of gates with a fixed gate as a destination +- Added block metadata support to gates + #### \[Version 0.5.1] - - Take into account world/network restrictions for Vehicles - - Properly teleport empty vehicles between worlds - - Properly teleport StoreageMinecarts between worlds - - Take into account vehicle type when teleporting + +- Take into account world/network restrictions for Vehicles +- Properly teleport empty vehicles between worlds +- Properly teleport StoreageMinecarts between worlds +- Take into account vehicle type when teleporting + #### \[Version 0.5.0] - - Updated the teleport method - - Remove always-open gates from lists - - Hopefully stop Stargate and Nether interference + +- Updated the teleport method +- Remove always-open gates from lists +- Hopefully stop Stargate and Nether interference + #### \[Version 0.4.9] - - Left-click to scroll signs up - - Show "(Not Connected)" on fixed-gates with a non-existant destination - - Added "maxgates" option - - Removed debug message - - Started work on disabling damage for lava gates, too much work to finish with the current implementation of EntityDamageByBlock + +- Left-click to scroll signs up +- Show "(Not Connected)" on fixed-gates with a non-existant destination +- Added "maxgates" option +- Removed debug message +- Started work on disabling damage for lava gates, too much work to finish with the current implementation of + EntityDamageByBlock + #### \[Version 0.4.8] - - Added chargefreedestination option - - Added freegatesgreen option + +- Added chargefreedestination option +- Added freegatesgreen option + #### \[Version 0.4.7] - - Added debug option - - Fixed gates will now show in the list of gates they link to. - - iConomy no longer touched if not enabled in config + +- Added debug option +- Fixed gates will now show in the list of gates they link to. +- iConomy no longer touched if not enabled in config + #### \[Version 0.4.6] - - Fixed a bug in iConomy handling. + +- Fixed a bug in iConomy handling. + #### \[Version 0.4.5] - - Owner of gate now isn't charged for use if target is owner - - Updated for iConomy 5.x - - Fixed random iConomy bugs + +- Owner of gate now isn't charged for use if target is owner +- Updated for iConomy 5.x +- Fixed random iConomy bugs + #### \[Version 0.4.4] - - Added a check for stargate.network.*/stargate.world.* on gate creation - - Check for stargate.world.*/stargate.network.* on gate entrance - - Warp player outside of gate on access denied + +- Added a check for stargate.network.*/stargate.world.* on gate creation +- Check for stargate.world.*/stargate.network.* on gate entrance +- Warp player outside of gate on access denied + #### \[Version 0.4.3] - - Made some errors more user-friendly - - Properly take into account portal-closed material + +- Made some errors more user-friendly +- Properly take into account portal-closed material + #### \[Version 0.4.2] - - Gates can't be created on existing gate blocks + +- Gates can't be created on existing gate blocks + #### \[Version 0.4.1] - - Sign option permissions - - Per-gate iconomy target - - /sg reload command - - Other misc fixes + +- Sign option permissions +- Per-gate iconomy target +- /sg reload command +- Other misc fixes + #### \[Version 0.4.0] - - Carts with no player can now go through gates. - - You can set gates to send their cost to their owner. - - Per-gate layout option for "toOwner". - - Cleaned up the iConomy code a bit, messages should only be shown on actual deduction now. - - Created separate 'stargate.free.{use/create/destroy}' permissions. + +- Carts with no player can now go through gates. +- You can set gates to send their cost to their owner. +- Per-gate layout option for "toOwner". +- Cleaned up the iConomy code a bit, messages should only be shown on actual deduction now. +- Created separate 'stargate.free.{use/create/destroy}' permissions. + #### \[Version 0.3.5] - - Added 'stargate.world.*' permissions - - Added 'stargate.network.*' permissions - - Added 'networkfilter' config option - - Added 'worldfilter' config option + +- Added 'stargate.world.*' permissions +- Added 'stargate.network.*' permissions +- Added 'networkfilter' config option +- Added 'worldfilter' config option + #### \[Version 0.3.4] - - Added 'stargate.free' permission - - Added iConomy cost into .gate files + +- Added 'stargate.free' permission +- Added iConomy cost into .gate files + #### \[Version 0.3.3] - - Moved sign update into a schedule event, should fix signs + +- Moved sign update into a schedule event, should fix signs + #### \[Version 0.3.2] - - Updated to latest RB - - Implemented proper vehicle handling - - Added iConomy to vehicle handling - - Can now set cost to go to creator on use + +- Updated to latest RB +- Implemented proper vehicle handling +- Added iConomy to vehicle handling +- Can now set cost to go to creator on use + #### \[Version 0.3.1] - - Changed version numbering. - - Changed how plugins are hooked into. + +- Changed version numbering. +- Changed how plugins are hooked into. + #### \[Version 0.30] - - Fixed a bug in iConomy checking. + +- Fixed a bug in iConomy checking. + #### \[Version 0.29] - - Added iConomy support. Currently only works with iConomy 4.4 until Niji fixes 4.5 - - Thanks @Jonbas for the base iConomy implementation + +- Added iConomy support. Currently only works with iConomy 4.4 until Niji fixes 4.5 +- Thanks @Jonbas for the base iConomy implementation + #### \[Version 0.28] - - Fixed an issue with removing stargates during load + +- Fixed an issue with removing stargates during load + #### \[Version 0.27] - - Fixed portal count on load + +- Fixed portal count on load + #### \[Version 0.26] - - Added stargate.create.personal for personal stargate networks - - Fixed a bug with destroying stargates by removing sign/button + +- Added stargate.create.personal for personal stargate networks +- Fixed a bug with destroying stargates by removing sign/button + #### \[Version 0.25] - - Fixed a bug with worlds in subfolders - - Fixed gates being destroyed with explosions - - Added stargate.destroy.owner + +- Fixed a bug with worlds in subfolders +- Fixed gates being destroyed with explosions +- Added stargate.destroy.owner + #### \[Version 0.24] - - Fixed a loading bug in which invalid gates caused file truncation + +- Fixed a loading bug in which invalid gates caused file truncation + #### \[Version 0.23] - - Added a check to make sure "nethergate.gate" exists, otherwise create it + +- Added a check to make sure "nethergate.gate" exists, otherwise create it + #### \[Version 0.22] - - Fixed multi-world stargates causing an NPE + +- Fixed multi-world stargates causing an NPE + #### \[Version 0.21] - - Code cleanup - - Added a few more errors when a gate can't be loaded - - Hopefully fixed path issue on some Linux installs + +- Code cleanup +- Added a few more errors when a gate can't be loaded +- Hopefully fixed path issue on some Linux installs + #### \[Version 0.20] - - Fixed the bug SIGN_CHANGE exception when using plugins such as Lockette + +- Fixed the bug SIGN_CHANGE exception when using plugins such as Lockette + #### \[Version 0.19] - - Set button facing on new gates, fixes weirdass button glitch - - Beginning of very buggy multi-world support + +- Set button facing on new gates, fixes weirdass button glitch +- Beginning of very buggy multi-world support + #### \[Version 0.18] - - Small permissions handling update. + +- Small permissions handling update. + #### \[Version 0.17] - - Core GM support removed, depends on FakePermissions if you use GM. + +- Core GM support removed, depends on FakePermissions if you use GM. + #### \[Version 0.16] - - Fixed Permissions, will work with GroupManager, Permissions 2.0, or Permissions 2.1 - - Left-clicking to activate a stargate works again + +- Fixed Permissions, will work with GroupManager, Permissions 2.0, or Permissions 2.1 +- Left-clicking to activate a stargate works again + #### \[Version 0.15] - - Built against b424jnks -- As such nothing lower is supported at the moment. - - Moved gate destruction code to onBlockBreak since onBlockDamage no longer handles breaking blocks. - - Removed long constructor. + +- Built against b424jnks -- As such nothing lower is supported at the moment. +- Moved gate destruction code to onBlockBreak since onBlockDamage no longer handles breaking blocks. +- Removed long constructor. + #### \[Version 0.14] - - Fixed infinite loop in fixed gates. - - Fixed gate destination will not open when dialed into. + +- Fixed infinite loop in fixed gates. +- Fixed gate destination will not open when dialed into. + #### \[Version 0.13] - - Fixed gates no longer show in destination list. + +- Fixed gates no longer show in destination list. + #### \[Version 0.12] - - Implemented fixed destination block using * in .gate file. This is the recommended method of doing an exit point for custom gates, as the automatic method doesn't work in a lot of cases. - - Split networks up in memory, can now use same name in different networks. As a result, fixed gates must now specify a network. - - Added the ability to have a private gate, which only you can activate. Use the 'P' option to create. - - Fixed but not AlwaysOn gates now open the destination gate. - - Fixed gates now show their network. Existing fixed gates are added to the default network (Sorry! It had to be done) + +- Implemented fixed destination block using * in .gate file. This is the recommended method of doing an exit point for + custom gates, as the automatic method doesn't work in a lot of cases. +- Split networks up in memory, can now use same name in different networks. As a result, fixed gates must now specify a + network. +- Added the ability to have a private gate, which only you can activate. Use the 'P' option to create. +- Fixed but not AlwaysOn gates now open the destination gate. +- Fixed gates now show their network. Existing fixed gates are added to the default network (Sorry! It had to be done) + #### \[Version 0.11] - - Fuuuu- Some code got undid and broke everything. Fixed. + +- Fuuuu- Some code got undid and broke everything. Fixed. + #### \[Version 0.10] - - Hopefully fixed the "No position found" bug. - - If dest > origin, any blocks past origin.size will drop you at dest[0] - - Switched to scheduler instead of our own thread for closing gates and deactivating signs - - No longer depend on Permissions, use it as an option. isOp() used as defaults. + +- Hopefully fixed the "No position found" bug. +- If dest > origin, any blocks past origin.size will drop you at dest[0] +- Switched to scheduler instead of our own thread for closing gates and deactivating signs +- No longer depend on Permissions, use it as an option. isOp() used as defaults. + #### \[Version 0.09] - - Gates can now be any shape + +- Gates can now be any shape + #### \[Version 0.08] - - Gates can now consist of any material. - - You can left or right click the button to open a gate - - Gates are now initialized on sign placement, not more right clicking! + +- Gates can now consist of any material. +- You can left or right click the button to open a gate +- Gates are now initialized on sign placement, not more right clicking! + #### \[Version 0.07] - - Fixed where the default gate is saved to. + +- Fixed where the default gate is saved to. + #### \[Version 0.06] - - Forgot to make gates load from new location, oops + +- Forgot to make gates load from new location, oops + #### \[Version 0.05] - - Moved Stargate files into the plugins/Stargate/ folder - - Added migration code so old gates/portals are ported to new folder structure - - Create default config.yml if it doesn't exist - - Fixed removing a gate, it is now completely removed + +- Moved Stargate files into the plugins/Stargate/ folder +- Added migration code so old gates/portals are ported to new folder structure +- Create default config.yml if it doesn't exist +- Fixed removing a gate, it is now completely removed + #### \[Version 0.04] - - Updated to multi-world Bukkit + +- Updated to multi-world Bukkit + #### \[Version 0.03] - - Changed package to net.TheDgtl.* - - Everything now uses Blox instead of Block objects - - Started on vehicle code, but it's still buggy \ No newline at end of file + +- Changed package to net.TheDgtl.* +- Everything now uses Blox instead of Block objects +- Started on vehicle code, but it's still buggy \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9cdaa33..285e6f9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,9 +1,10 @@ - - 4.0.0 + + 4.0.0 - net.knarcraft - Stargate - 0.9.0.0 + net.knarcraft + Stargate + 0.9.0.0 @@ -12,34 +13,34 @@ - - UTF-8 + + UTF-8 16 16 - + - - - spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ - - - vault-repo - http://nexus.hc.to/content/repositories/pub_releases - - + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + vault-repo + http://nexus.hc.to/content/repositories/pub_releases + + - - - org.spigotmc - spigot-api - 1.17.1-R0.1-SNAPSHOT - - - net.milkbowl.vault - VaultAPI - 1.7 - + + + org.spigotmc + spigot-api + 1.17.1-R0.1-SNAPSHOT + + + net.milkbowl.vault + VaultAPI + 1.7 + org.junit.jupiter junit-jupiter-api @@ -58,26 +59,26 @@ 19.0.0 compile - - junit - junit - 4.13.1 - test - - + + junit + junit + 4.13.1 + test + + - - src/main/java - - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.1 - - 1.8 - 1.8 - - - - + + src/main/java + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 605386f..ebaef5b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -38,17 +38,17 @@ gates: maxGatesEachNetwork: 0 defaultGateNetwork: central cosmetic: - rememberDestination: false - sortNetworkDestinations: false - signColor: BLACK + rememberDestination: false + sortNetworkDestinations: false + signColor: BLACK integrity: - destroyedByExplosion: false - verifyPortals: false - protectEntrance: false - ignoreEntrance: false + destroyedByExplosion: false + verifyPortals: false + protectEntrance: false + ignoreEntrance: false functionality: - enableBungee: false - handleVehicles: true + enableBungee: false + handleVehicles: true economy: useEconomy: false createCost: 0 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0d3bb20..c52e5a1 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,10 +3,10 @@ main: net.knarcraft.stargate.Stargate version: 0.9.0.0 description: Stargate mod for Bukkit author: EpicKnarvik97 -authors: [Drakia, PseudoKnight, EpicKnarvik97] +authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] website: https://knarcraft.net api-version: 1.16 -softdepend: [Vault] +softdepend: [ Vault ] commands: stargate: aliases: diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 7e767c9..f1a24cd 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -1,21 +1,20 @@ package net.knarcraft.stargate.portal; +import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.WorldMock; -import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.RelativeBlockVector; import org.bukkit.Material; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import be.seeseemelk.mockbukkit.MockBukkit; - import java.util.ArrayList; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class GateLayoutTest { private static GateLayout layout; From f681db629f71d9d56ac43537f847ed2f281f7745 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 13:56:30 +0200 Subject: [PATCH 097/378] Refactors a lot of code, and extracts permission-related functions to the PermissionHelper class --- .../java/net/knarcraft/stargate/Stargate.java | 389 +++++------------- .../command/StarGateTabCompleter.java | 9 +- .../stargate/container/BlockLocation.java | 4 +- .../stargate/listener/BlockEventListener.java | 7 +- .../listener/EntityEventListener.java | 2 +- .../listener/PlayerEventListener.java | 12 +- .../listener/PluginEventListener.java | 3 +- .../listener/VehicleEventListener.java | 2 +- .../stargate/listener/WorldEventListener.java | 2 +- .../net/knarcraft/stargate/portal/Gate.java | 2 +- .../stargate/portal/GateHandler.java | 46 ++- .../knarcraft/stargate/portal/GateLayout.java | 20 +- .../net/knarcraft/stargate/portal/Portal.java | 9 +- .../stargate/portal/PortalDirection.java | 1 - .../stargate/portal/PortalHandler.java | 23 +- .../stargate/thread/BlockChangeThread.java | 6 +- .../stargate/thread/StarGateThread.java | 2 +- .../stargate/utility/BungeeHelper.java | 2 +- .../stargate/utility/DirectionHelper.java | 12 +- .../stargate/utility/EconomyHandler.java | 27 +- .../stargate/utility/EconomyHelper.java | 2 +- .../stargate/utility/PermissionHelper.java | 272 ++++++++++++ .../stargate/utility/SignHelper.java | 24 +- 23 files changed, 497 insertions(+), 381 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 6cb4d43..7962c7d 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -15,10 +15,10 @@ import net.knarcraft.stargate.listener.WorldEventListener; import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalOption; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.EconomyHandler; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; @@ -28,7 +28,6 @@ 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; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -192,7 +191,7 @@ public class Stargate extends JavaPlugin { } // Check if the player can use the private gate - if (portal.isPrivate() && !Stargate.canPrivate(player, portal)) { + if (portal.isPrivate() && !PermissionHelper.canPrivate(player, portal)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); return; } @@ -207,109 +206,14 @@ public class Stargate extends JavaPlugin { portal.open(player, false); } - /* - * Check whether the player has the given permissions. - */ - /** - * Checks whether a player has the given permission - * - *

This is the same as player.hasPermission(), but this function allows for printing permission debugging info.

- * - * @param player

The player to check

- * @param perm

The permission to check

- * @return

True if the player has the permission

- */ - public static boolean hasPermission(Player player, String perm) { - if (permissionDebuggingEnabled) { - Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); - } - return player.hasPermission(perm); - } - - /** - * Check a deep permission, this will check to see if the permissions is defined for this use - * - *

If using Permissions it will return the same as hasPerm. If using SuperPerms will return true if the node - * isn't defined, or the value of the node if it is

- * - * @param player

The player to check

- * @param permission

The permission to check

- * @return

True if the player has the permission or it is not set

- */ - public static boolean hasPermDeep(Player player, String permission) { - if (!player.isPermissionSet(permission)) { - if (permissionDebuggingEnabled) { - Stargate.debug("hasPermDeep::SuperPerm", permission + " => true"); - } - return true; - } - if (permissionDebuggingEnabled) { - Stargate.debug("hasPermDeep::SuperPerms", permission + " => " + player.hasPermission(permission)); - } - return player.hasPermission(permission); - } - - /* - * Check whether player can teleport to dest world - */ - public static boolean cannotAccessWorld(Player player, String world) { - // Can use all stargate player features or access all worlds - if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.world")) { - // Do a deep check to see if the player lacks this specific world node - return !hasPermDeep(player, "stargate.world." + world); - } - // Can access dest world - return !hasPermission(player, "stargate.world." + world); - } - - /** - * Checks whether a player can access the given network - * @param player

The player to check

- * @param network

The network to check

- * @return

True if the player is denied from accessing the network

- */ - public static boolean cannotAccessNetwork(Player player, String network) { - // Can user all stargate player features, or access all networks - if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.network")) { - // Do a deep check to see if the player lacks this specific network node - return !hasPermDeep(player, "stargate.network." + network); - } - //Check if the player can access this network - if (hasPermission(player, "stargate.network." + network)) { - return false; - } - // Is able to create personal gates (Assumption is made they can also access them) - String playerName = player.getName(); - if (playerName.length() > 11) playerName = playerName.substring(0, 11); - return !network.equals(playerName) || !hasPermission(player, "stargate.create.personal"); - } - - /* - * Check whether the player can access this server - */ - public static boolean canAccessServer(Player player, String server) { - // Can user all stargate player features, or access all servers - if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.servers")) { - // Do a deep check to see if the player lacks this specific server node - return hasPermDeep(player, "stargate.server." + server); - } - // Can access this server - return hasPermission(player, "stargate.server." + server); - } - - /* - * Call the StargateAccessPortal event, used for other plugins to bypass Permissions checks - */ - - /** - * Creates a stargate access event and gives the result + * Creates a StargateAccessPortal and gives the result * *

The event is used for other plugins to bypass the permission checks

* * @param player

The player trying to use the portal

* @param portal

The portal the player is trying to use

- * @param deny

Whether the player's access has already been denied by a check

+ * @param deny

Whether the player's access has already been denied by a check

* @return

False if the player should be allowed through the portal

*/ public static boolean cannotAccessPortal(Player player, Portal portal, boolean deny) { @@ -329,138 +233,19 @@ public class Stargate extends JavaPlugin { public static boolean cannotAccessPortal(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())) { + if (entrancePortal.isBungee() && !PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; - } else if (Stargate.cannotAccessNetwork(player, entrancePortal.getNetwork())) { + } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (!entrancePortal.isBungee() && Stargate.cannotAccessWorld(player, destination.getWorld().getName())) { + } else if (!entrancePortal.isBungee() && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } return Stargate.cannotAccessPortal(player, entrancePortal, deny); } - /* - * Return true if the portal is free for the player - */ - public static boolean isFree(Player player, Portal src, Portal dest) { - // This gate is free - if (src.isFree()) return true; - // Player gets free use - if (hasPermission(player, "stargate.free") || Stargate.hasPermission(player, "stargate.free.use")) return true; - // Don't charge for free destination gates - return dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree(); - } - - /* - * Check whether the player can see this gate (Hidden property check) - */ - - /** - * Checks whether the player can see this gate (Hidden property check) - * - *

This decides if the player can see the gate on the network selection screen

- * - * @param player

The player to check

- * @param portal

The portal to check

- * @return

True if the given player can see the given portal

- */ - public static boolean canSee(Player player, Portal portal) { - // The gate is not hidden - if (!portal.isHidden()) { - return true; - } - // The player is an admin with the ability to see hidden gates - if (hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.hidden")) { - return true; - } - // The player is the owner of the gate - return portal.isOwner(player); - } - - /* - * Check if the player can use this private gate - */ - public static boolean canPrivate(Player player, Portal portal) { - // Check if the player is the owner of the gate - if (portal.isOwner(player)) return true; - // The player is an admin with the ability to use private gates - return hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.private"); - } - - /* - * Check if the player has access to {option} - */ - public static boolean canOption(Player player, PortalOption option) { - // Check if the player can use all options - if (hasPermission(player, "stargate.option") || option == PortalOption.BUNGEE) { - return true; - } - // Check if they can use this specific option - return hasPermission(player, option.getPermissionString()); - } - - /* - * Check if the player can create gates on {network} - */ - public static boolean canCreate(Player player, String network) { - // Check for general create - if (hasPermission(player, "stargate.create")) return true; - // Check for all network create permission - if (hasPermission(player, "stargate.create.network")) { - // Do a deep check to see if the player lacks this specific network node - return hasPermDeep(player, "stargate.create.network." + network); - } - // Check for this specific network - return hasPermission(player, "stargate.create.network." + network); - - } - - /* - * Check if the player can create a personal gate - */ - public static boolean canCreatePersonal(Player player) { - // Check for general create - if (hasPermission(player, "stargate.create")) return true; - // Check for personal - return hasPermission(player, "stargate.create.personal"); - } - - /* - * Check if the player can create this gate layout - */ - public static boolean canCreateGate(Player player, String gate) { - // Check for general create - if (hasPermission(player, "stargate.create")) return true; - // Check for all gate create permissions - if (hasPermission(player, "stargate.create.gate")) { - // Do a deep check to see if the player lacks this specific gate node - return hasPermDeep(player, "stargate.create.gate." + gate); - } - // Check for this specific gate - return hasPermission(player, "stargate.create.gate." + gate); - } - - /* - * Check if the player can destroy this gate - */ - public static boolean canDestroy(Player player, Portal portal) { - String network = portal.getNetwork(); - // Check for general destroy - if (hasPermission(player, "stargate.destroy")) return true; - // Check for all network destroy permission - if (hasPermission(player, "stargate.destroy.network")) { - // Do a deep check to see if the player lacks permission for this network node - return hasPermDeep(player, "stargate.destroy.network." + network); - } - // Check for this specific network - if (hasPermission(player, "stargate.destroy.network." + network)) return true; - // Check for personal gate - return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); - } - /** * Replaces a list of variables in a string in the order they are given * @@ -518,7 +303,37 @@ public class Stargate extends JavaPlugin { log.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); - // Register events before loading gates to stop weird things happening. + //Register events before loading gates to stop weird things happening. + registerEventListeners(); + + this.loadConfig(); + + //Enable the required channels for Bungee support + if (enableBungee) { + startStopBungeeListener(true); + } + + // It is important to load languages here, as they are used during reloadGates() + languageLoader = new LanguageLoader(languageFolder, Stargate.languageName); + + this.createMissingFolders(); + this.loadGates(); + this.loadAllPortals(); + + // Check to see if Economy is loaded yet. + setupVaultEconomy(); + + //Run necessary threads + getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); + getServer().getScheduler().runTaskTimer(this, new BlockChangeThread(), 0L, 1L); + + this.registerCommands(); + } + + /** + * Registers all event listeners + */ + private void registerEventListeners() { pluginManager.registerEvents(new PlayerEventListener(), this); pluginManager.registerEvents(new BlockEventListener(), this); @@ -527,30 +342,11 @@ public class Stargate extends JavaPlugin { pluginManager.registerEvents(new PortalEventListener(), this); pluginManager.registerEvents(new WorldEventListener(), this); pluginManager.registerEvents(new PluginEventListener(this), this); - - this.loadConfig(); - - // Enable the required channels for Bungee support - if (enableBungee) { - startStopBungeeListener(true); - } - - // It is important to load languages here, as they are used during reloadGates() - languageLoader = new LanguageLoader(languageFolder, Stargate.languageName); - - this.migrate(); - this.loadGates(); - this.loadAllPortals(); - - // Check to see if Economy is loaded yet. - setupVaultEconomy(); - - getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); - getServer().getScheduler().runTaskTimer(this, new BlockChangeThread(), 0L, 1L); - - this.registerCommands(); } + /** + * Registers a command for this plugin + */ private void registerCommands() { PluginCommand stargateCommand = this.getCommand("stargate"); if (stargateCommand != null) { @@ -559,34 +355,63 @@ public class Stargate extends JavaPlugin { } } + /** + * Loads all config values + */ public void loadConfig() { - reloadConfig(); + this.reloadConfig(); newConfig = this.getConfig(); // Copy default values if required newConfig.options().copyDefaults(true); - // Load values into variables + //Language + languageName = newConfig.getString("language"); + + //Folders portalFolder = newConfig.getString("folders.portalFolder"); gateFolder = newConfig.getString("folders.gateFolder"); - String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); - defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; - destroyExplosion = newConfig.getBoolean("gates.destroyedByExplosion"); - maxGates = newConfig.getInt("gates.maxGatesEachNetwork"); - languageName = newConfig.getString("language"); - rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); - ignoreEntrance = newConfig.getBoolean("gates.integrity.ignoreEntrance"); - handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); - sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); - protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); - enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); - verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); - // Sign color - loadSignColor(newConfig.getString("gates.cosmetic.signColor")); - // Debug + //Debug debuggingEnabled = newConfig.getBoolean("debugging.debug"); permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug"); - // Economy + + //Gates + loadGateConfig(); + + //Economy + loadEconomyConfig(); + + this.saveConfig(); + } + + /** + * Loads all config values related to gates + */ + private void loadGateConfig() { + String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); + defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; + maxGates = newConfig.getInt("gates.maxGatesEachNetwork"); + + //Functionality + handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); + enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); + + //Integrity + protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); + verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); + ignoreEntrance = newConfig.getBoolean("gates.integrity.ignoreEntrance"); + destroyExplosion = newConfig.getBoolean("gates.integrity.destroyedByExplosion"); + + //Cosmetic + sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); + rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); + loadSignColor(newConfig.getString("gates.cosmetic.signColor")); + } + + /** + * Loads all config values related to economy + */ + private void loadEconomyConfig() { EconomyHandler.economyEnabled = newConfig.getBoolean("economy.useEconomy"); EconomyHandler.setCreateCost(newConfig.getInt("economy.createCost")); EconomyHandler.setDestroyCost(newConfig.getInt("economy.destroyCost")); @@ -594,12 +419,11 @@ public class Stargate extends JavaPlugin { EconomyHandler.toOwner = newConfig.getBoolean("economy.toOwner"); EconomyHandler.chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination"); EconomyHandler.freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen"); - - this.saveConfig(); } /** * Loads the correct sign color given a sign color string + * * @param signColor

A string representing a sign color

*/ private void loadSignColor(String signColor) { @@ -614,18 +438,27 @@ public class Stargate extends JavaPlugin { Stargate.signColor = ChatColor.BLACK; } + /** + * Forces all open portals to close + */ public void closeAllPortals() { // Close all gates prior to reloading - for (Portal p : openList) { - p.close(true); + for (Portal openPortal : openList) { + openPortal.close(true); } } + /** + * Loads all available gates + */ public void loadGates() { GateHandler.loadGates(gateFolder); log.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); } + /** + * Loads all portals in all un-managed worlds + */ public void loadAllPortals() { for (World world : getServer().getWorlds()) { if (!managedWorlds.contains(world.getName())) { @@ -635,8 +468,10 @@ public class Stargate extends JavaPlugin { } } - private void migrate() { - // Only migrate if new file doesn't exist. + /** + * Creates missing folders + */ + private void createMissingFolders() { File newPortalDir = new File(portalFolder); if (!newPortalDir.exists()) { if (!newPortalDir.mkdirs()) { @@ -651,22 +486,6 @@ public class Stargate extends JavaPlugin { } } - /* - * Check if a plugin is loaded/enabled already. Returns the plugin if so, null otherwise - */ - private Plugin checkPlugin(String p) { - Plugin plugin = pluginManager.getPlugin(p); - return checkPlugin(plugin); - } - - private Plugin checkPlugin(Plugin plugin) { - if (plugin != null && plugin.isEnabled()) { - log.info(Stargate.getString("prefix") + "Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")"); - return plugin; - } - return null; - } - /** * Reloads all portals and files * diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index 2675e80..0242b4a 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -16,11 +16,16 @@ public class StarGateTabCompleter implements TabCompleter { @Override public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, - @NotNull String s, @NotNull String[] strings) { + @NotNull String s, @NotNull String[] args) { List commands = new ArrayList<>(); commands.add("about"); commands.add("reload"); - return commands; + + if (args.length == 1) { + return commands; + } else { + return new ArrayList<>(); + } } } diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index e5ea6b6..7ea37e1 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -70,7 +70,7 @@ public class BlockLocation extends Location { * @param x

The x position relative to this block's position

* @param y

The y position relative to this block's position

* @param z

The z position relative to this block's position

- * @param yaw

The yaw of the location

+ * @param yaw

The yaw of the location

* @param rotY

The y rotation of the location

* @return

A new location

*/ @@ -105,7 +105,7 @@ public class BlockLocation extends Location { * @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 yaw

The yaw of the location

+ * @param yaw

The yaw of the location

* @param rotY

Unused

* @param modX

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

* @param modY

Unused

diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index cc5eb9e..ae9f314 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -1,12 +1,13 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.portal.Portal; -import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateDestroyEvent; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -84,7 +85,7 @@ public class BlockEventListener implements Listener { String denyMsg = ""; //Decide if the user can destroy the portal - if (!Stargate.canDestroy(player, portal)) { + if (!PermissionHelper.canDestroyPortal(player, portal)) { denyMsg = Stargate.getString("denyMsg"); deny = true; Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 43f5fcb..3c32226 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.block.Block; import org.bukkit.entity.Entity; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index f7ac066..028fe60 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -1,13 +1,14 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.block.Block; @@ -127,10 +128,11 @@ public class PlayerEventListener implements Listener { /** * Checks whether a player move event is relevant for this plugin - * @param event

The player move event to check

- * @param player

The player which moved

+ * + * @param event

The player move event to check

+ * @param player

The player which moved

* @param fromLocation

The location the player is moving from

- * @param toLocation

The location the player is moving to

+ * @param toLocation

The location the player is moving to

* @return

True if the event is relevant

*/ private boolean isRelevantMoveEvent(PlayerMoveEvent event, Player player, BlockLocation fromLocation, BlockLocation toLocation) { @@ -232,7 +234,7 @@ public class PlayerEventListener implements Listener { * @return

True if the player should be denied

*/ private boolean cannotAccessPortal(Player player, Portal portal) { - boolean deny = Stargate.cannotAccessNetwork(player, portal.getNetwork()); + boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); if (Stargate.cannotAccessPortal(player, portal, deny)) { Stargate.sendMessage(player, Stargate.getString("denyMsg")); diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index fbe34be..a65b4e2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; @@ -28,6 +28,7 @@ public class PluginEventListener implements Listener { * This event listens for and announces that the vault plugin was detected and enabled * *

Each time this event is called, the economy handler will try to enable vault

+ * * @param ignored

The actual event called. This is currently not used

*/ @EventHandler diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index eba8466..55a7986 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 08c248b..64cb5fa 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.PortalHandler; import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 55673fc..5f56701 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.portal; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Material; diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 1a90965..0aac91b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -1,10 +1,11 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; import org.bukkit.block.Block; + import java.io.File; import java.io.InputStream; import java.util.ArrayList; @@ -109,9 +110,9 @@ public class GateHandler { /** * Loads a gate * - * @param fileName

The name of the file containing the gate layout

+ * @param fileName

The name of the file containing the gate layout

* @param parentFolder

The parent folder of the layout file

- * @param scanner

The scanner to use for reading the gate layout

+ * @param scanner

The scanner to use for reading the gate layout

* @return

The loaded gate or null if unable to load the gate

*/ private static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { @@ -145,10 +146,10 @@ public class GateHandler { /** * Creates a new gate * - * @param config

The config map to get configuration values from

+ * @param config

The config map to get configuration values from

* @param fileName

The name of the saved gate config file

- * @param layout

The layout matrix of the new gate

- * @param types

The mapping for used gate material types

+ * @param layout

The layout matrix of the new gate

+ * @param types

The mapping for used gate material types

* @return

A new gate or null if the config is invalid

*/ private static Gate createGate(Map config, String fileName, Character[][] layout, @@ -173,7 +174,7 @@ public class GateHandler { /** * Validate that a gate is valid * - * @param gate

The gate to validate

+ * @param gate

The gate to validate

* @param fileName

The filename of the loaded gate file

* @return

True if the gate is valid. False otherwise

*/ @@ -196,7 +197,7 @@ public class GateHandler { * Generates a matrix storing the gate layout * * @param design

The design of the gate layout

- * @param cols

The largest amount of columns in the design

+ * @param cols

The largest amount of columns in the design

* @return

A matrix containing the gate's layout

*/ private static Character[][] generateLayoutMatrix(List> design, int cols) { @@ -222,12 +223,12 @@ public class GateHandler { /** * Reads the gate file * - * @param scanner

The scanner to read from

- * @param types

The map of characters to store valid symbols in

- * @param fileName

The filename of the loaded gate config file

- * @param design

The list to store the loaded design to

+ * @param scanner

The scanner to read from

+ * @param types

The map of characters to store valid symbols in

+ * @param fileName

The filename of the loaded gate config file

+ * @param design

The list to store the loaded design to

* @param frameTypes

The set of gate frame types to store to

- * @param config

The map of config values to store to

+ * @param config

The map of config values to store to

* @return

The column count/width of the loaded gate

*/ private static int readGateFile(Scanner scanner, Map types, String fileName, @@ -265,11 +266,11 @@ public class GateHandler { /** * Reads one design line of the gate layout file * - * @param line

The line to read

- * @param cols

The current max columns value of the design

- * @param types

The map of characters to check for valid symbols

+ * @param line

The line to read

+ * @param cols

The current max columns value of the design

+ * @param types

The map of characters to check for valid symbols

* @param fileName

The filename of the loaded gate config file

- * @param design

The list to store the loaded design to

+ * @param design

The list to store the loaded design to

* @return

The new max columns value of the design

*/ private static int readGateDesignLine(String line, int cols, Map types, String fileName, @@ -295,10 +296,10 @@ public class GateHandler { /** * Reads one config value from the gate layout file * - * @param line

The line to read

- * @param types

The map of characters to materials to store to

+ * @param line

The line to read

+ * @param types

The map of characters to materials to store to

* @param frameTypes

The set of gate frame types to store to

- * @param config

The map of config values to store to

+ * @param config

The map of config values to store to

* @throws Exception

If an invalid material is encountered

*/ private static void readGateConfigValue(String line, Map types, Set frameTypes, @@ -322,9 +323,10 @@ public class GateHandler { /** * Reads an integer configuration key - * @param config

The configuration to read

+ * + * @param config

The configuration to read

* @param fileName

The filename of the config file

- * @param key

The config key to read

+ * @param key

The config key to read

* @return

The read value, or -1 if it cannot be read

*/ private static int readConfig(Map config, String fileName, String key) { diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 402946f..2b734ff 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -16,7 +16,7 @@ import java.util.List; */ public class GateLayout { - private final Character [][] layout; + private final Character[][] layout; private final List exits = new ArrayList<>(); private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; private RelativeBlockVector[] border = new RelativeBlockVector[0]; @@ -39,7 +39,7 @@ public class GateLayout { * @return

Two of the gate's corners

*/ public RelativeBlockVector[] getCorners() { - return new RelativeBlockVector[] { + return new RelativeBlockVector[]{ new RelativeBlockVector(0, 0, 0), new RelativeBlockVector(layout[0].length - 1, layout.length - 1, 1) }; @@ -157,9 +157,9 @@ public class GateLayout { /** * Reads the given layout matrix, filling in the given lists of relative block vectors * - * @param controlList

The list of control blocks to save to

+ * @param controlList

The list of control blocks to save to

* @param entranceList

The list of entrances to save to

- * @param borderList

The list of border blocks to save to

+ * @param borderList

The list of border blocks to save to

* @return

A list of depths of possible extra exits

*/ private int[] readLayout(List controlList, List entranceList, @@ -181,13 +181,13 @@ public class GateLayout { /** * Parses one character of the layout * - * @param key

The character read

- * @param rowIndex

The row of the read character

- * @param lineIndex

The line of the read character

- * @param exitDepths

The list of exit depths to save to

- * @param controlList

The list of control blocks to save to

+ * @param key

The character read

+ * @param rowIndex

The row of the read character

+ * @param lineIndex

The line of the read character

+ * @param exitDepths

The list of exit depths to save to

+ * @param controlList

The list of control blocks to save to

* @param entranceList

The list of entrances to save to

- * @param borderList

The list of border blocks to save to

+ * @param borderList

The list of border blocks to save to

*/ private void parseLayoutCharacter(Character key, int rowIndex, int lineIndex, int[] exitDepths, List controlList, List entranceList, diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 001634c..b4f33f2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -1,9 +1,9 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.container.BlockChangeRequest; -import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockChangeRequest; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; @@ -86,7 +86,7 @@ public class Portal { * @param topLeft

The top-left block of the portal. This is used to decide the positions of the rest of the portal

* @param modX

* @param modZ

- * @param yaw

+ * @param yaw

* @param id

The location of the portal's id block, which is the sign which activated the portal

* @param button

The location of the portal's open button

* @param destination

The destination defined on the sign's destination line

@@ -921,6 +921,7 @@ public class Portal { /** * Loads one chunk + * * @param chunk

The chunk to load

*/ private void loadOneChunk(Chunk chunk) { diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java b/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java index f509e21..d6bbb4a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java @@ -3,5 +3,4 @@ package net.knarcraft.stargate.portal; public class PortalDirection { - } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index ac7f41d..afd1e43 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -1,13 +1,14 @@ package net.knarcraft.stargate.portal; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; @@ -90,12 +91,12 @@ public class PortalHandler { continue; } // Check if this player can access the dest world - if (Stargate.cannotAccessWorld(player, portal.getWorld().getName())) { + if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { Stargate.log.info("cannot access world"); continue; } // Visible to this player. - if (Stargate.canSee(player, portal)) { + if (PermissionHelper.canSeePortal(player, portal)) { destinations.add(portal.getName()); } } @@ -314,7 +315,7 @@ public class PortalHandler { //If the player is trying to create a Bungee gate without permissions, drop out here if (options.indexOf(PortalOption.BUNGEE.getCharacterRepresentation()) != -1) { - if (!Stargate.hasPermission(player, "stargate.admin.bungee")) { + if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); return null; } @@ -344,9 +345,9 @@ public class PortalHandler { String denyMsg = ""; // Check if the player can create gates on this network - if (!portalOptions.get(PortalOption.BUNGEE) && !Stargate.canCreate(player, network)) { + if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); - if (Stargate.canCreatePersonal(player)) { + if (PermissionHelper.canCreatePersonalGate(player)) { network = player.getName(); if (network.length() > 11) network = network.substring(0, 11); Stargate.debug("createPortal", "Creating personal portal"); @@ -362,7 +363,7 @@ public class PortalHandler { // Check if the player can create this gate layout String gateName = gate.getFilename(); gateName = gateName.substring(0, gateName.indexOf('.')); - if (!deny && !Stargate.canCreateGate(player, gateName)) { + if (!deny && !PermissionHelper.canCreateGate(player, gateName)) { Stargate.debug("createPortal", "Player does not have access to gate layout"); deny = true; denyMsg = Stargate.getString("createGateDeny"); @@ -373,8 +374,8 @@ public class PortalHandler { Portal p = getByName(destinationName, network); if (p != null) { String world = p.getWorld().getName(); - if (Stargate.cannotAccessWorld(player, world)) { - Stargate.debug("canCreate", "Player does not have access to destination world"); + if (PermissionHelper.cannotAccessWorld(player, world)) { + Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); deny = true; denyMsg = Stargate.getString("createWorldDeny"); } @@ -506,7 +507,7 @@ public class PortalHandler { Map portalOptions = new HashMap<>(); for (PortalOption option : PortalOption.values()) { portalOptions.put(option, options.indexOf(option.getCharacterRepresentation()) != -1 && - Stargate.canOption(player, option)); + PermissionHelper.canUseOption(player, option)); } // Can not create a non-fixed always-on gate. @@ -583,7 +584,7 @@ public class PortalHandler { * Gets a portal given a location adjacent to its entrance * * @param location

A location adjacent to the portal's entrance

- * @param range

The range to scan for portals

+ * @param range

The range to scan for portals

* @return

The portal adjacent to the given location

*/ public static Portal getByAdjacentEntrance(Location location, int range) { diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index 3a5bfdd..985ba5a 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.thread; -import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockChangeRequest; import org.bukkit.Axis; import org.bukkit.Material; import org.bukkit.World; @@ -44,6 +44,7 @@ public class BlockChangeThread implements Runnable { /** * Prevents end gateway portal from behaving strangely + * * @param block

The block to fix

*/ private void fixEndGatewayGate(Block block) { @@ -55,8 +56,9 @@ public class BlockChangeThread implements Runnable { /** * Sets the orientation axis of the placed block + * * @param block

The block to orient

- * @param axis

The axis to use for orienting the block

+ * @param axis

The axis to use for orienting the block

*/ private void orientBlock(Block block, Axis axis) { Orientable orientable = (Orientable) block.getBlockData(); diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 4b03cc0..65984b5 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.thread; -import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; import java.util.Iterator; diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index b51cf4e..64e1a4b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.utility; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; import java.io.ByteArrayInputStream; diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 6db573d..9f747fc 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -41,6 +41,7 @@ public final class DirectionHelper { /** * Gets a block face given a yaw + * * @param yaw

The yaw to use

* @return

The block face the yaw corresponds to

*/ @@ -63,6 +64,7 @@ public final class DirectionHelper { /** * Gets a direction vector given a yaw + * * @param yaw

The yaw to use

* @return

The direction vector of the yaw

*/ @@ -95,12 +97,13 @@ public final class DirectionHelper { /** * Adds a relative block vector to a location, accounting for direction + * * @param location

The location to adjust

- * @param right

The amount of blocks to the right to adjust

- * @param depth

The amount of blocks upward to adjust

+ * @param right

The amount of blocks to the right to adjust

+ * @param depth

The amount of blocks upward to adjust

* @param distance

The distance outward to adjust

- * @param modX

The x modifier to use

- * @param modZ

The z modifier to use

+ * @param modX

The x modifier to use

+ * @param modZ

The z modifier to use

* @return

The altered location

*/ public static Location adjustLocation(Location location, double right, double depth, double distance, int modX, @@ -110,6 +113,7 @@ public final class DirectionHelper { /** * Normalizes a yaw to make it positive and no larger than 360 degrees + * * @param yaw

The yaw to normalize

* @return

The normalized yaw

*/ diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 27908aa..bb5150f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -90,8 +90,9 @@ public final class EconomyHandler { /** * Charges the player for an action, if required + * * @param player

The player to take money from

- * @param cost

The cost of the transaction

+ * @param cost

The cost of the transaction

* @return

True if the player was charged successfully

*/ public static boolean chargePlayerIfNecessary(Player player, int cost) { @@ -104,9 +105,10 @@ public final class EconomyHandler { /** * Charges the player for an action, if required + * * @param player

The player to take money from

* @param target

The target to pay

- * @param cost

The cost of the transaction

+ * @param cost

The cost of the transaction

* @return

True if the player was charged successfully

*/ public static boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { @@ -170,6 +172,7 @@ public final class EconomyHandler { /** * Checks whether a payment transaction should be skipped + * * @param cost

The cost of the transaction

* @return

True if the transaction should be skipped

*/ @@ -180,8 +183,8 @@ public final class EconomyHandler { /** * Determines the cost of using a gate * - * @param player

The player trying to use the gate

- * @param source

The source/entry portal

+ * @param player

The player trying to use the gate

+ * @param source

The source/entry portal

* @param destination

The destination portal

* @return

The cost of using the portal

*/ @@ -199,7 +202,8 @@ public final class EconomyHandler { return 0; } //Player gets free gate use - if (Stargate.hasPermission(player, "stargate.free") || Stargate.hasPermission(player, "stargate.free.use")) { + if (PermissionHelper.hasPermission(player, "stargate.free") || + PermissionHelper.hasPermission(player, "stargate.free.use")) { return 0; } @@ -208,8 +212,9 @@ public final class EconomyHandler { /** * Gets the cost of creating the given gate + * * @param player

The player creating the gate

- * @param gate

The gate type used

+ * @param gate

The gate type used

* @return

The cost of creating the gate

*/ public static int getCreateCost(Player player, Gate gate) { @@ -222,8 +227,9 @@ public final class EconomyHandler { /** * Gets the cost of destroying the given gate + * * @param player

The player creating the gate

- * @param gate

The gate type used

+ * @param gate

The gate type used

* @return

The cost of destroying the gate

*/ public static int getDestroyCost(Player player, Gate gate) { @@ -236,13 +242,14 @@ public final class EconomyHandler { /** * Determines if a player can do a gate action for free - * @param player

The player to check

+ * + * @param player

The player to check

* @param permissionNode

The free.permissionNode necessary to allow free gate {action}

* @return

*/ private static boolean isFree(Player player, String permissionNode) { - return !EconomyHandler.useEconomy() || Stargate.hasPermission(player, "stargate.free") || - Stargate.hasPermission(player, "stargate.free." + permissionNode); + return !EconomyHandler.useEconomy() || PermissionHelper.hasPermission(player, "stargate.free") || + PermissionHelper.hasPermission(player, "stargate.free." + permissionNode); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 25db29f..54ec4a0 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.utility; -import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; /** diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java new file mode 100644 index 0000000..37965b2 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -0,0 +1,272 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalOption; +import org.bukkit.entity.Player; + +/** + * Helper class for deciding which actions a player is allowed to perform + */ +public final class PermissionHelper { + + private PermissionHelper() { + + } + + /** + * Checks whether a player has the given permission + * + *

This is the same as player.hasPermission(), but this function allows for printing permission debugging info.

+ * + * @param player

The player to check

+ * @param perm

The permission to check

+ * @return

True if the player has the permission

+ */ + public static boolean hasPermission(Player player, String perm) { + if (Stargate.permissionDebuggingEnabled) { + Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); + } + return player.hasPermission(perm); + } + + /** + * Check a deep permission, this will check to see if the permissions is defined for this use + * + *

If using Permissions it will return the same as hasPerm. If using SuperPerms will return true if the node + * isn't defined, or the value of the node if it is

+ * + * @param player

The player to check

+ * @param permission

The permission to check

+ * @return

True if the player has the permission or it is not set

+ */ + public static boolean hasPermDeep(Player player, String permission) { + if (!player.isPermissionSet(permission)) { + if (Stargate.permissionDebuggingEnabled) { + Stargate.debug("hasPermDeep::SuperPerm", permission + " => true"); + } + return true; + } + if (Stargate.permissionDebuggingEnabled) { + Stargate.debug("hasPermDeep::SuperPerms", permission + " => " + player.hasPermission(permission)); + } + return player.hasPermission(permission); + } + + /** + * Checks whether a player can access the given world + * @param player

The player trying to access the world

+ * @param world

The world the player is trying to access

+ * @return

False if the player should be allowed to access the world

+ */ + public static boolean cannotAccessWorld(Player player, String world) { + // Can use all stargate player features or access all worlds + if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.world")) { + // Do a deep check to see if the player lacks this specific world node + return !hasPermDeep(player, "stargate.world." + world); + } + // Can access dest world + return !hasPermission(player, "stargate.world." + world); + } + + /** + * Checks whether a player can access the given network + * + * @param player

The player to check

+ * @param network

The network to check

+ * @return

True if the player is denied from accessing the network

+ */ + public static boolean cannotAccessNetwork(Player player, String network) { + // Can user all stargate player features, or access all networks + if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.network")) { + // Do a deep check to see if the player lacks this specific network node + return !hasPermDeep(player, "stargate.network." + network); + } + //Check if the player can access this network + if (hasPermission(player, "stargate.network." + network)) { + return false; + } + //Is able to create personal gates (Assumption is made they can also access them) + String playerName = player.getName(); + if (playerName.length() > 11) { + playerName = playerName.substring(0, 11); + } + return !network.equals(playerName) || !hasPermission(player, "stargate.create.personal"); + } + + /** + * Checks whether a player can access the given bungee server + * @param player

The player trying to teleport

+ * @param server

The server the player is trying to connect to

+ * @return

True if the player is allowed to access the given server

+ */ + public static boolean canAccessServer(Player player, String server) { + //Can user all stargate player features, or access all servers + if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.servers")) { + //Do a deep check to see if the player lacks this specific server node + return hasPermDeep(player, "stargate.server." + server); + } + //Can access this server + return hasPermission(player, "stargate.server." + server); + } + + /** + * Checks whether the given player can teleport the given stretch for free + * + * @param player

The player trying to teleport

+ * @param src

The portal the player is entering

+ * @param dest

The portal the player wants to teleport to

+ * @return

True if the player can travel for free

+ */ + public static boolean isFree(Player player, Portal src, Portal dest) { + // This gate is free + if (src.isFree()) { + return true; + } + // Player gets free use + if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.use")) { + return true; + } + // Don't charge for free destination gates + return dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree(); + } + + /** + * Checks whether the player can see this gate (Hidden property check) + * + *

This decides if the player can see the gate on the network selection screen

+ * + * @param player

The player to check

+ * @param portal

The portal to check

+ * @return

True if the given player can see the given portal

+ */ + public static boolean canSeePortal(Player player, Portal portal) { + // The gate is not hidden + if (!portal.isHidden()) { + return true; + } + // The player is an admin with the ability to see hidden gates + if (hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.hidden")) { + return true; + } + // The player is the owner of the gate + return portal.isOwner(player); + } + + /** + * Checks if the given player is allowed to use the given private portal + * + * @param player

The player trying to use the portal

+ * @param portal

The private portal used

+ * @return

True if the player is allowed to use the portal

+ */ + public static boolean canPrivate(Player player, Portal portal) { + //Check if the player is the owner of the gate + if (portal.isOwner(player)) { + return true; + } + //The player is an admin with the ability to use private gates + return hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.private"); + } + + /** + * Checks if the given player has access to the given portal option + * + * @param player

The player trying to use the option

+ * @param option

The option the player is trying to use

+ * @return

True if the player is allowed to create a portal with the given option

+ */ + public static boolean canUseOption(Player player, PortalOption option) { + //Check if the player can use all options + if (hasPermission(player, "stargate.option") || option == PortalOption.BUNGEE) { + return true; + } + //Check if they can use this specific option + return hasPermission(player, option.getPermissionString()); + } + + /** + * Checks if the given player is allowed to create gates on the given network + * + * @param player

The player trying to create a new gate

+ * @param network

The network the player is trying to create a gate on

+ * @return

True if the player is allowed to create the new gate

+ */ + public static boolean canCreateNetworkGate(Player player, String network) { + //Check for general create + if (hasPermission(player, "stargate.create")) { + return true; + } + //Check for all network create permission + if (hasPermission(player, "stargate.create.network")) { + // Do a deep check to see if the player lacks this specific network node + return hasPermDeep(player, "stargate.create.network." + network); + } + //Check for this specific network + return hasPermission(player, "stargate.create.network." + network); + + } + + /** + * Checks whether the given player is allowed to create a personal gate + * + * @param player

The player trying to create the new gate

+ * @return

True if the player is allowed

+ */ + public static boolean canCreatePersonalGate(Player player) { + //Check for general create + if (hasPermission(player, "stargate.create")) { + return true; + } + //Check for personal + return hasPermission(player, "stargate.create.personal"); + } + + /** + * Checks if the given player can create a portal with the given gate layout + * + * @param player

The player trying to create a portal

+ * @param gate

The gate type of the new portal

+ * @return

True if the player is allowed to create a portal with the given gate layout

+ */ + public static boolean canCreateGate(Player player, String gate) { + //Check for general create + if (hasPermission(player, "stargate.create")) { + return true; + } + //Check for all gate create permissions + if (hasPermission(player, "stargate.create.gate")) { + // Do a deep check to see if the player lacks this specific gate node + return hasPermDeep(player, "stargate.create.gate." + gate); + } + //Check for this specific gate + return hasPermission(player, "stargate.create.gate." + gate); + } + + /** + * Checks if the given player can destroy the given portal + * + * @param player

The player trying to destroy the portal

+ * @param portal

The portal to destroy

+ * @return

True if the player is allowed to destroy the portal

+ */ + public static boolean canDestroyPortal(Player player, Portal portal) { + String network = portal.getNetwork(); + //Check for general destroy + if (hasPermission(player, "stargate.destroy")) { + return true; + } + //Check for all network destroy permission + if (hasPermission(player, "stargate.destroy.network")) { + //Do a deep check to see if the player lacks permission for this network node + return hasPermDeep(player, "stargate.destroy.network." + network); + } + //Check for this specific network + if (hasPermission(player, "stargate.destroy.network." + network)) { + return true; + } + //Check for personal gate + return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index e902770..891c209 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -7,7 +7,7 @@ import org.bukkit.ChatColor; import org.bukkit.block.Sign; /** - * This class helps drawing the sign on a portal as it's a bit too complicated to be contained within the portal class + * This class helps to draw the sign on a portal as it's a bit too complicated to be contained within the portal class */ public final class SignHelper { @@ -41,7 +41,7 @@ public final class SignHelper { } /** - * Draws a sign with chooseable network locations + * Draws a sign with choose-able network locations * * @param sign

The sign to draw on

*/ @@ -51,7 +51,7 @@ public final class SignHelper { int destinationIndex = portal.getDestinations().indexOf(portal.getDestinationName()); boolean freeGatesGreen = EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen; - //Last entry, and not only entry. Draw the entry two previously + //Last, and not only entry. Draw the entry two back if ((destinationIndex == maxIndex) && (maxIndex > 1)) { drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2, portal); } @@ -62,8 +62,8 @@ public final class SignHelper { //Draw the chosen entry (line 2 or 3) drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex, portal); //Has another entry and space on the sign - if ((maxIndex >= destinationIndex + 1) && (++signLineIndex <= 3)) { - drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 1, portal); + if ((maxIndex >= destinationIndex + 1)) { + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex + 1, portal); } //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { @@ -75,13 +75,13 @@ public final class SignHelper { * Draws the chosen destination on one sign line * * @param freeGatesGreen

Whether to display free gates in a green color

- * @param sign

The sign to draw on

- * @param signLineIndex

The line to draw on

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

*/ private static void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex, Portal portal) { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); - boolean green = Stargate.isFree(portal.getActivePlayer(), portal, destination); + boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + portal.getDestinationName() + "<"); } else { Stargate.setLine(sign, signLineIndex, " >" + portal.getDestinationName() + "< "); @@ -91,16 +91,16 @@ public final class SignHelper { /** * Draws one network destination on one sign line * - * @param freeGatesGreen

Whether to display free gates in a green color

- * @param sign

The sign to draw on

- * @param signLineIndex

The line to draw on

+ * @param freeGatesGreen

Whether to display free gates in a green color

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

* @param destinationIndex

The index of the destination to draw

*/ private static void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex, Portal portal) { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinations().get(destinationIndex), portal.getNetwork()); - boolean green = Stargate.isFree(portal.getActivePlayer(), portal, destination); + boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + portal.getDestinations().get(destinationIndex)); } else { Stargate.setLine(sign, signLineIndex, portal.getDestinations().get(destinationIndex)); From d24f35375a02d14684d35562163ad76b59aae38f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 18:21:26 +0200 Subject: [PATCH 098/378] Changes the default folders to prevent problems on Unix systems --- src/main/resources/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ebaef5b..22dd8a1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -32,8 +32,8 @@ language: en folders: - portalFolder: plugins/stargate/portals/ - gateFolder: plugins/stargate/gates/ + portalFolder: plugins/Stargate/portals/ + gateFolder: plugins/Stargate/gates/ gates: maxGatesEachNetwork: 0 defaultGateNetwork: central From 1e29db58b9470fce33318a01d5c0f56ea0c9f45e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 18:22:20 +0200 Subject: [PATCH 099/378] Improves some variable names and adds some comments --- .../knarcraft/stargate/LanguageLoader.java | 12 +- .../java/net/knarcraft/stargate/Stargate.java | 257 +++++++++--------- .../stargate/command/CommandReload.java | 2 +- .../stargate/listener/BlockEventListener.java | 8 +- .../listener/PlayerEventListener.java | 18 +- .../listener/VehicleEventListener.java | 15 +- .../net/knarcraft/stargate/portal/Gate.java | 2 +- .../stargate/portal/GateHandler.java | 14 +- .../net/knarcraft/stargate/portal/Portal.java | 24 +- .../stargate/portal/PortalHandler.java | 43 +-- .../stargate/thread/StarGateThread.java | 4 +- .../stargate/utility/BungeeHelper.java | 8 +- .../stargate/utility/EconomyHandler.java | 4 +- .../stargate/utility/EconomyHelper.java | 8 +- .../stargate/utility/PermissionHelper.java | 101 ++++++- 15 files changed, 310 insertions(+), 210 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index 9b6ab3f..4367eae 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -42,7 +42,7 @@ public class LanguageLoader { File tmp = new File(languageFolder, chosenLanguage + ".txt"); if (!tmp.exists()) { if (tmp.getParentFile().mkdirs() && Stargate.debuggingEnabled) { - Stargate.log.info("[stargate] Created language folder"); + Stargate.logger.info("[stargate] Created language folder"); } } updateLanguage(chosenLanguage); @@ -54,7 +54,7 @@ public class LanguageLoader { loadedBackupStrings = load("en", inputStream); } else { loadedBackupStrings = null; - Stargate.log.severe("[stargate] Error loading backup language. There may be missing text in-game"); + Stargate.logger.severe("[stargate] Error loading backup language. There may be missing text in-game"); } } @@ -110,10 +110,10 @@ public class LanguageLoader { InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); if (inputStream == null) { - Stargate.log.info("[stargate] The language " + language + " is not available. Falling back to " + + Stargate.logger.info("[stargate] The language " + language + " is not available. Falling back to " + "english, You can add a custom language by creating a new text file in the lang directory."); if (Stargate.debuggingEnabled) { - Stargate.log.info("[stargate] Unable to load /lang/" + language + ".txt"); + Stargate.logger.info("[stargate] Unable to load /lang/" + language + ".txt"); } return; } @@ -157,7 +157,7 @@ public class LanguageLoader { } } if (updated) { - Stargate.log.info("[stargate] Your language file (" + language + ".txt) has been updated"); + Stargate.logger.info("[stargate] Your language file (" + language + ".txt) has been updated"); } } @@ -243,7 +243,7 @@ public class LanguageLoader { readLanguageFile(inputStreamReader, strings); } catch (Exception e) { if (Stargate.debuggingEnabled) { - Stargate.log.info("Unable to load chosen language"); + Stargate.logger.info("Unable to load chosen language"); } return null; } finally { diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 7962c7d..12cc3dc 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -3,7 +3,6 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.container.BlockChangeRequest; -import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; @@ -18,7 +17,6 @@ import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.EconomyHandler; -import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; @@ -27,7 +25,6 @@ import org.bukkit.block.Sign; 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.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -47,47 +44,51 @@ import java.util.logging.Logger; @SuppressWarnings("unused") public class Stargate extends JavaPlugin { - public static final ConcurrentLinkedQueue openList = new ConcurrentLinkedQueue<>(); + //Used for changing gate open/closed material. + public static final Queue blockChangeRequestQueue = new LinkedList<>(); + public static final ConcurrentLinkedQueue openPortalsQueue = new ConcurrentLinkedQueue<>(); + public static final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); + + //Amount of seconds before deactivating/closing portals private static final int activeTime = 10; private static final int openTime = 10; - public static Logger log; + + public static Logger logger; public static Server server; public static Stargate stargate; public static LanguageLoader languageLoader; - public static int maxGates = 0; + + public static int maxGatesEachNetwork = 0; public static boolean rememberDestination = false; public static boolean handleVehicles = true; public static boolean sortNetworkDestinations = false; public static boolean protectEntrance = false; public static boolean enableBungee = true; public static boolean verifyPortals = true; - public static ChatColor signColor; - // Temp workaround for snowmen, don't check gate entrance + private static boolean destroyExplosion = false; + //Temp workaround for snowmen, don't check gate entrance public static boolean ignoreEntrance = false; + + public static ChatColor signColor; // Used for debug public static boolean debuggingEnabled = false; public static boolean permissionDebuggingEnabled = false; - public static final ConcurrentLinkedQueue activeList = new ConcurrentLinkedQueue<>(); - // Used for populating gate open/closed material. - public static final Queue blockChangeRequestQueue = new LinkedList<>(); + // HashMap of player names for Bungee support public static final Map bungeeQueue = new HashMap<>(); //World names that contain stargates public static final HashSet managedWorlds = new HashSet<>(); + private static String pluginVersion; private static String portalFolder; private static String gateFolder; + private static String defaultGateNetwork = "central"; - private static boolean destroyExplosion = false; private static String languageName = "en"; + private FileConfiguration newConfig; private PluginManager pluginManager; - public Stargate() { - super(); - - } - /** * Special constructor used for MockBukkit * @@ -100,152 +101,148 @@ public class Stargate extends JavaPlugin { super(loader, descriptionFile, dataFolder, file); } + /** + * Gets the version of this plugin + * + * @return

This plugin's version

+ */ public static String getPluginVersion() { return pluginVersion; } + /** + * Gets whether portals should be destroyed by explosions + * + * @return

True if portals should be destroyed

+ */ public static boolean destroyedByExplosion() { return destroyExplosion; } + /** + * Gets the amount of seconds a portal should be open before automatically closing + * + * @return

The open time of a gate

+ */ public static int getOpenTime() { return openTime; } + /** + * Gets the amount of seconds a portal should be active before automatically deactivating + * + * @return

The active time of a gate

+ */ public static int getActiveTime() { return activeTime; } - public static void debug(String rout, String msg) { + /** + * Sends a debug message + * + * @param route

The class name/route where something happened

+ * @param message

A message describing what happened

+ */ + public static void debug(String route, String message) { if (Stargate.debuggingEnabled) { - log.info("[stargate::" + rout + "] " + msg); + logger.info("[stargate::" + route + "] " + message); } else { - log.log(Level.FINEST, "[stargate::" + rout + "] " + msg); + logger.log(Level.FINEST, "[stargate::" + route + "] " + message); } } - public static void sendMessage(CommandSender player, String message) { + /** + * Sends an error message to a player + * + * @param player

The player to send the message to

+ * @param message

The message to send

+ */ + public static void sendErrorMessage(CommandSender player, String message) { sendMessage(player, message, true); } - public static void sendMessage(CommandSender player, String message, boolean error) { - if (message.isEmpty()) return; - message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); - if (error) - player.sendMessage(ChatColor.RED + Stargate.getString("prefix") + ChatColor.WHITE + message); - else - player.sendMessage(ChatColor.GREEN + Stargate.getString("prefix") + ChatColor.WHITE + message); + /** + * Sends a success message to a player + * + * @param player

The player to send the message to

+ * @param message

The message to send

+ */ + public static void sendSuccessMessage(CommandSender player, String message) { + sendMessage(player, message, false); } + /** + * Sends a message to a player + * + * @param player

The player to send the message to

+ * @param message

The message to send

+ * @param error

Whether the message sent is an error

+ */ + private static void sendMessage(CommandSender player, String message, boolean error) { + if (message.isEmpty()) return; + //Replace color codes with green? What's the deal with the dollar sign? + message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); + if (error) { + player.sendMessage(ChatColor.RED + Stargate.getString("prefix") + ChatColor.WHITE + message); + } else { + player.sendMessage(ChatColor.GREEN + Stargate.getString("prefix") + ChatColor.WHITE + message); + } + } + + /** + * Sets a line on a sign, adding the chosen sign color + * + * @param sign

The sign to update

+ * @param index

The index of the sign line to change

+ * @param text

The new text on the sign

+ */ public static void setLine(Sign sign, int index, String text) { sign.setLine(index, Stargate.signColor + text); } + /** + * Gets the folder for saving created portals + * + *

The returned String path is the full path to the folder

+ * + * @return

The folder for storing the portal database

+ */ public static String getSaveLocation() { return portalFolder; } + /** + * Gets the folder storing gate files + * + *

The returned String path is the full path to the folder

+ * + * @return

The folder storing gate files

+ */ public static String getGateFolder() { return gateFolder; } + /** + * Gets the default network for gates where a network is not specified + * + * @return

The default network

+ */ public static String getDefaultNetwork() { return defaultGateNetwork; } + /** + * Gets a translated string given its string key + * + *

The name/key is the string before the equals sign in the language files

+ * + * @param name

The name/key of the string to get

+ * @return

The full translated string

+ */ public static String getString(String name) { return languageLoader.getString(name); } - public static void openPortal(Player player, Portal portal) { - Portal destination = portal.getDestination(); - - // Always-open gate -- Do nothing - if (portal.isAlwaysOn()) { - return; - } - - // Random gate -- Do nothing - if (portal.isRandom()) - return; - - // Invalid destination - if ((destination == null) || (destination == portal)) { - Stargate.sendMessage(player, Stargate.getString("invalidMsg")); - return; - } - - // Gate is already open - if (portal.isOpen()) { - // Close if this player opened the gate - if (portal.getActivePlayer() == player) { - portal.close(false); - } - return; - } - - // Gate that someone else is using -- Deny access - if ((!portal.isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - // Check if the player can use the private gate - if (portal.isPrivate() && !PermissionHelper.canPrivate(player, portal)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); - return; - } - - // Destination blocked - if ((destination.isOpen()) && (!destination.isAlwaysOn())) { - Stargate.sendMessage(player, Stargate.getString("blockMsg")); - return; - } - - // Open gate - portal.open(player, false); - } - - /** - * Creates a StargateAccessPortal and gives the result - * - *

The event is used for other plugins to bypass the permission checks

- * - * @param player

The player trying to use the portal

- * @param portal

The portal the player is trying to use

- * @param deny

Whether the player's access has already been denied by a check

- * @return

False if the player should be allowed through the portal

- */ - public static boolean cannotAccessPortal(Player player, Portal portal, boolean deny) { - StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); - Stargate.server.getPluginManager().callEvent(event); - return event.getDeny(); - } - - /** - * Checks whether a given user cannot 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

False if the user is allowed to access the portal

- */ - public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { - boolean deny = false; - // Check if player has access to this server for Bungee gates - if (entrancePortal.isBungee() && !PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { - Stargate.debug("cannotAccessPortal", "Cannot access server"); - deny = true; - } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { - Stargate.debug("cannotAccessPortal", "Cannot access network"); - deny = true; - } else if (!entrancePortal.isBungee() && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { - Stargate.debug("cannotAccessPortal", "Cannot access world"); - deny = true; - } - return Stargate.cannotAccessPortal(player, entrancePortal, deny); - } - /** * Replaces a list of variables in a string in the order they are given * @@ -289,7 +286,7 @@ public class Stargate extends JavaPlugin { PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); newConfig = this.getConfig(); - log = Logger.getLogger("Minecraft"); + logger = Logger.getLogger("Minecraft"); Stargate.server = getServer(); Stargate.stargate = this; @@ -301,7 +298,7 @@ public class Stargate extends JavaPlugin { pluginVersion = pluginDescriptionFile.getVersion(); - log.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); + logger.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); //Register events before loading gates to stop weird things happening. registerEventListeners(); @@ -390,7 +387,7 @@ public class Stargate extends JavaPlugin { private void loadGateConfig() { String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; - maxGates = newConfig.getInt("gates.maxGatesEachNetwork"); + maxGatesEachNetwork = newConfig.getInt("gates.maxGatesEachNetwork"); //Functionality handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); @@ -434,7 +431,7 @@ public class Stargate extends JavaPlugin { } catch (IllegalArgumentException | NullPointerException ignored) { } } - log.warning(getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); + logger.warning(getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); Stargate.signColor = ChatColor.BLACK; } @@ -443,7 +440,7 @@ public class Stargate extends JavaPlugin { */ public void closeAllPortals() { // Close all gates prior to reloading - for (Portal openPortal : openList) { + for (Portal openPortal : openPortalsQueue) { openPortal.close(true); } } @@ -453,7 +450,7 @@ public class Stargate extends JavaPlugin { */ public void loadGates() { GateHandler.loadGates(gateFolder); - log.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); + logger.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); } /** @@ -475,13 +472,13 @@ public class Stargate extends JavaPlugin { File newPortalDir = new File(portalFolder); if (!newPortalDir.exists()) { if (!newPortalDir.mkdirs()) { - log.severe("Unable to create portal directory"); + logger.severe("Unable to create portal directory"); } } File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); if (!newFile.exists() && !newFile.getParentFile().exists()) { if (!newFile.getParentFile().mkdirs()) { - log.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); + logger.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); } } } @@ -493,14 +490,14 @@ public class Stargate extends JavaPlugin { */ public void reload(CommandSender sender) { // Deactivate portals - for (Portal activePortal : activeList) { + for (Portal activePortal : activePortalsQueue) { activePortal.deactivate(); } // Close portals closeAllPortals(); // Clear all lists - activeList.clear(); - openList.clear(); + activePortalsQueue.clear(); + openPortalsQueue.clear(); managedWorlds.clear(); PortalHandler.clearGates(); GateHandler.clearGates(); @@ -522,7 +519,7 @@ public class Stargate extends JavaPlugin { startStopBungeeListener(enableBungee); } - sendMessage(sender, "stargate reloaded"); + sendErrorMessage(sender, "stargate reloaded"); } /** @@ -543,7 +540,7 @@ public class Stargate extends JavaPlugin { private void setupVaultEconomy() { if (EconomyHandler.setupEconomy(pluginManager) && EconomyHandler.economy != null) { String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); - log.info(Stargate.getString("prefix") + Stargate.replaceVars( + logger.info(Stargate.getString("prefix") + Stargate.replaceVars( Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index dfd3d74..79ba7fe 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -29,7 +29,7 @@ public class CommandReload implements CommandExecutor { if (commandSender instanceof Player) { Player player = (Player) commandSender; if (!player.hasPermission("stargate.reload")) { - Stargate.sendMessage(commandSender, "Permission Denied"); + Stargate.sendErrorMessage(commandSender, "Permission Denied"); return true; } } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index ae9f314..63fa088 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -54,7 +54,7 @@ public class BlockEventListener implements Listener { return; } - Stargate.sendMessage(player, Stargate.getString("createMsg"), false); + Stargate.sendSuccessMessage(player, Stargate.getString("createMsg")); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); } @@ -88,7 +88,7 @@ public class BlockEventListener implements Listener { if (!PermissionHelper.canDestroyPortal(player, portal)) { denyMsg = Stargate.getString("denyMsg"); deny = true; - Stargate.log.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); + Stargate.logger.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); } int cost = EconomyHandler.getDestroyCost(player, portal.getGate()); @@ -103,7 +103,7 @@ public class BlockEventListener implements Listener { //Destroy denied if (destroyEvent.getDeny()) { - Stargate.sendMessage(player, destroyEvent.getDenyReason()); + Stargate.sendErrorMessage(player, destroyEvent.getDenyReason()); event.setCancelled(true); return; } @@ -114,7 +114,7 @@ public class BlockEventListener implements Listener { } PortalHandler.unregisterPortal(portal, true); - Stargate.sendMessage(player, Stargate.getString("destroyMsg"), false); + Stargate.sendSuccessMessage(player, Stargate.getString("destroyMsg")); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 028fe60..bea32d7 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -122,7 +122,7 @@ public class PlayerEventListener implements Listener { } else { destination.teleport(player, entrancePortal, event); } - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); entrancePortal.close(false); } @@ -157,7 +157,7 @@ public class PlayerEventListener implements Listener { //Decide if the user should be teleported to another bungee server if (entrancePortal.isBungee()) { if (bungeeTeleport(player, entrancePortal, event)) { - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); } return false; } @@ -236,8 +236,8 @@ public class PlayerEventListener implements Listener { private boolean cannotAccessPortal(Player player, Portal portal) { boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); - if (Stargate.cannotAccessPortal(player, portal, deny)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); + if (PermissionHelper.cannotAccessPortal(player, portal, deny)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return true; } return false; @@ -277,7 +277,7 @@ public class PlayerEventListener implements Listener { return; } - Stargate.openPortal(player, portal); + PermissionHelper.openPortal(player, portal); if (portal.isOpenFor(player)) { event.setUseInteractedBlock(Event.Result.ALLOW); } @@ -319,7 +319,7 @@ public class PlayerEventListener implements Listener { private boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { //Check if bungee is actually enabled if (!Stargate.enableBungee) { - player.sendMessage(Stargate.getString("bungeeDisabled")); + Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); entrancePortal.close(false); return false; } @@ -362,7 +362,7 @@ public class PlayerEventListener implements Listener { // Not open for this player if (!entrancePortal.isOpenFor(player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); entrancePortal.teleport(player, entrancePortal, event); return false; } @@ -373,8 +373,8 @@ public class PlayerEventListener implements Listener { } //Player cannot access portal - if (Stargate.cannotAccessPortal(player, entrancePortal, destination)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); entrancePortal.teleport(player, entrancePortal, event); entrancePortal.close(false); return false; diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 55a7986..ec87539 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -6,6 +6,7 @@ import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; @@ -59,13 +60,13 @@ public class VehicleEventListener implements Listener { */ private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - Stargate.log.info(Stargate.getString("prefox") + "Found passenger vehicle"); + Stargate.logger.info(Stargate.getString("prefox") + "Found passenger vehicle"); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Stargate.log.info(Stargate.getString("prefox") + "Found empty vehicle"); + Stargate.logger.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"); + Stargate.logger.warning(Stargate.getString("prefox") + "Unable to find portal destination"); return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getId()); @@ -83,7 +84,7 @@ public class VehicleEventListener implements Listener { private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { Player player = (Player) passengers.get(0); if (!entrancePortal.isOpenFor(player)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } @@ -93,8 +94,8 @@ public class VehicleEventListener implements Listener { } //Make sure the user can access the portal - if (Stargate.cannotAccessPortal(player, entrancePortal, destinationPortal)) { - Stargate.sendMessage(player, Stargate.getString("denyMsg")); + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); entrancePortal.close(false); return; } @@ -107,7 +108,7 @@ public class VehicleEventListener implements Listener { } } - Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); + Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); destinationPortal.teleport(vehicle, entrancePortal); entrancePortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 5f56701..51ae9d2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -302,7 +302,7 @@ public class Gate { bufferedWriter.close(); } catch (IOException ex) { - Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); + Stargate.logger.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 0aac91b..3b5d700 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -102,7 +102,7 @@ public class GateHandler { try (Scanner scanner = new Scanner(file)) { return loadGate(file.getName(), file.getParent(), scanner); } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); return null; } } @@ -180,13 +180,13 @@ public class GateHandler { */ private static boolean validateGate(Gate gate, String fileName) { if (gate.getLayout().getControls().length != 2) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); return false; } if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); return false; } @@ -253,7 +253,7 @@ public class GateHandler { } } } catch (Exception ex) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); return -1; } finally { if (scanner != null) { @@ -283,7 +283,7 @@ public class GateHandler { for (Character symbol : line.toCharArray()) { if ((symbol.equals('?')) || (!types.containsKey(symbol))) { - Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); return -1; } row.add(symbol); @@ -334,7 +334,7 @@ public class GateHandler { try { return Integer.parseInt(config.get(key)); } catch (NumberFormatException ex) { - Stargate.log.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); + Stargate.logger.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); } } @@ -356,7 +356,7 @@ public class GateHandler { if (material != null) { return material; } else { - Stargate.log.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, key)); + Stargate.logger.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, key)); } } return defaultMaterial; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index b4f33f2..6245300 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -511,8 +511,8 @@ public class Portal { //Update the open state of this portal isOpen = true; openTime = System.currentTimeMillis() / 1000; - Stargate.openList.add(this); - Stargate.activeList.remove(this); + Stargate.openPortalsQueue.add(this); + Stargate.activePortalsQueue.remove(this); //Open remote portal if (!isAlwaysOn()) { @@ -561,8 +561,8 @@ public class Portal { //Update the closed state of this portal player = null; isOpen = false; - Stargate.openList.remove(this); - Stargate.activeList.remove(this); + Stargate.openPortalsQueue.remove(this); + Stargate.activePortalsQueue.remove(this); //Close remote portal if (!isAlwaysOn()) { @@ -714,7 +714,7 @@ public class Portal { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { - Stargate.log.warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); + Stargate.logger.warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); return; } putPassengersInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); @@ -803,7 +803,7 @@ public class Portal { } } } else { - Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); } return adjustExitLocation(traveller, exitLocation); @@ -895,7 +895,7 @@ public class Portal { exitLocation.setPitch(traveller.getPitch()); return exitLocation; } else { - Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Unable to generate exit location"); + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + "Unable to generate exit location"); } return traveller; } @@ -1026,7 +1026,7 @@ public class Portal { private boolean activate(Player player) { destinations.clear(); destination = ""; - Stargate.activeList.add(this); + Stargate.activePortalsQueue.add(this); activePlayer = player; String network = getNetwork(); destinations = PortalHandler.getDestinations(this, player, network); @@ -1040,7 +1040,7 @@ public class Portal { StargateActivateEvent event = new StargateActivateEvent(this, player, destinations, destination); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { - Stargate.activeList.remove(this); + Stargate.activePortalsQueue.remove(this); return false; } destination = event.getDestination(); @@ -1059,7 +1059,7 @@ public class Portal { return; } - Stargate.activeList.remove(this); + Stargate.activePortalsQueue.remove(this); if (isFixed()) { return; } @@ -1110,7 +1110,7 @@ public class Portal { } if (destinations.size() == 0) { - Stargate.sendMessage(player, Stargate.getString("destEmpty")); + Stargate.sendErrorMessage(player, Stargate.getString("destEmpty")); return; } @@ -1147,7 +1147,7 @@ public class Portal { public final void drawSign() { BlockState state = id.getBlock().getState(); if (!(state instanceof Sign)) { - Stargate.log.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); + Stargate.logger.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); Stargate.debug("Portal::drawSign", "Block: " + id.getBlock().getType() + " @ " + id.getBlock().getLocation()); return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index afd1e43..8996cca 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -34,6 +34,9 @@ import java.util.Scanner; import java.util.UUID; import java.util.logging.Level; +/** + * Keeps track of all loaded portals, and handles portal creation + */ public class PortalHandler { // Static variables used to store portal lists private static final Map lookupBlocks = new HashMap<>(); @@ -92,7 +95,7 @@ public class PortalHandler { } // Check if this player can access the dest world if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { - Stargate.log.info("cannot access world"); + Stargate.logger.info("cannot access world"); continue; } // Visible to this player. @@ -316,16 +319,16 @@ public class PortalHandler { //If the player is trying to create a Bungee gate without permissions, drop out here if (options.indexOf(PortalOption.BUNGEE.getCharacterRepresentation()) != -1) { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { - Stargate.sendMessage(player, Stargate.getString("bungeeDeny")); + Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); return null; } } if (portalOptions.get(PortalOption.BUNGEE)) { if (!Stargate.enableBungee) { - Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); + Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); return null; } else if (destinationName.isEmpty() || network.isEmpty()) { - Stargate.sendMessage(player, Stargate.getString("bungeeEmpty")); + Stargate.sendErrorMessage(player, Stargate.getString("bungeeEmpty")); return null; } } @@ -351,7 +354,7 @@ public class PortalHandler { network = player.getName(); if (network.length() > 11) network = network.substring(0, 11); Stargate.debug("createPortal", "Creating personal portal"); - Stargate.sendMessage(player, Stargate.getString("createPersonal")); + Stargate.sendErrorMessage(player, Stargate.getString("createPersonal")); } else { Stargate.debug("createPortal", "Player does not have access to network"); deny = true; @@ -387,7 +390,7 @@ public class PortalHandler { 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")); + Stargate.sendErrorMessage(player, Stargate.getString("createConflict")); return null; } } @@ -406,7 +409,7 @@ public class PortalHandler { return null; } if (cEvent.getDeny()) { - Stargate.sendMessage(player, cEvent.getDenyReason()); + Stargate.sendErrorMessage(player, cEvent.getDenyReason()); return null; } @@ -415,7 +418,7 @@ public class PortalHandler { // Name & Network can be changed in the event, so do these checks here. if (portal.getName().length() < 1 || portal.getName().length() > 11) { Stargate.debug("createPortal", "Name length error"); - Stargate.sendMessage(player, Stargate.getString("createNameLength")); + Stargate.sendErrorMessage(player, Stargate.getString("createNameLength")); return null; } @@ -423,20 +426,20 @@ public class PortalHandler { if (portal.isBungee()) { if (bungeePortals.get(portal.getName().toLowerCase()) != null) { Stargate.debug("createPortal::Bungee", "Gate Exists"); - Stargate.sendMessage(player, Stargate.getString("createExists")); + Stargate.sendErrorMessage(player, Stargate.getString("createExists")); return null; } } else { if (getByName(portal.getName(), portal.getNetwork()) != null) { Stargate.debug("createPortal", "Name Error"); - Stargate.sendMessage(player, Stargate.getString("createExists")); + Stargate.sendErrorMessage(player, Stargate.getString("createExists")); return null; } // Check if there are too many gates in this network List netList = allPortalNetworks.get(portal.getNetwork().toLowerCase()); - if (Stargate.maxGates > 0 && netList != null && netList.size() >= Stargate.maxGates) { - Stargate.sendMessage(player, Stargate.getString("createFull")); + if (Stargate.maxGatesEachNetwork > 0 && netList != null && netList.size() >= Stargate.maxGatesEachNetwork) { + Stargate.sendErrorMessage(player, Stargate.getString("createFull")); return null; } } @@ -715,7 +718,7 @@ public class PortalHandler { bw.close(); } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); + Stargate.logger.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); } } @@ -783,7 +786,7 @@ public class PortalHandler { if (database.exists()) { return loadGates(world, database); } else { - Stargate.log.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); + Stargate.logger.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); } return false; } @@ -811,7 +814,7 @@ public class PortalHandler { //Check if the min. required portal data is present String[] portalData = line.split(":"); if (portalData.length < 8) { - Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); + Stargate.logger.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); continue; } @@ -822,12 +825,12 @@ public class PortalHandler { // Open any always-on gates. Do this here as it should be more efficient than in the loop. TwoTuple portalCounts = openAlwaysOpenGates(); - Stargate.log.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", + Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), portalCounts.getFirstValue())); return true; } catch (Exception e) { - Stargate.log.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + lineIndex); + Stargate.logger.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + lineIndex); e.printStackTrace(); } return false; @@ -851,7 +854,7 @@ public class PortalHandler { BlockLocation topLeft = new BlockLocation(world, portalData[6]); Gate gate = GateHandler.getGateByName(portalData[7]); if (gate == null) { - Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + + Stargate.logger.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + " does not exist [" + portalData[7] + "]"); return; } @@ -949,14 +952,14 @@ public class PortalHandler { } } PortalHandler.unregisterPortal(portal, false); - Stargate.log.info(Stargate.getString("prefix") + "Destroying stargate at " + portal); + Stargate.logger.info(Stargate.getString("prefix") + "Destroying stargate at " + portal); } /** * Closes all star gate portals */ public static void closeAllGates() { - Stargate.log.info("Closing all stargates."); + Stargate.logger.info("Closing all stargates."); for (Portal portal : allPortals) { if (portal != null) { portal.close(true); diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 65984b5..4b202df 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -14,7 +14,7 @@ public class StarGateThread implements Runnable { public void run() { long time = System.currentTimeMillis() / 1000; // Close open portals - for (Iterator iterator = Stargate.openList.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = Stargate.openPortalsQueue.iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); // Skip always open and non-open gates if (portal.isAlwaysOn() || !portal.isOpen()) { @@ -26,7 +26,7 @@ public class StarGateThread implements Runnable { } } // Deactivate active portals - for (Iterator iterator = Stargate.activeList.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = Stargate.activePortalsQueue.iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); if (!portal.isActive()) { continue; diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 64e1a4b..2939bae 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -48,7 +48,7 @@ public final class BungeeHelper { dataOutputStream.writeBytes(message); player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); + Stargate.logger.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); ex.printStackTrace(); return false; } @@ -72,7 +72,7 @@ public final class BungeeHelper { player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); byteArrayOutputStream.reset(); } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); + Stargate.logger.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); ex.printStackTrace(); return false; } @@ -99,7 +99,7 @@ public final class BungeeHelper { data = new byte[dataLength]; dataInputStream.readFully(data); } catch (IOException ex) { - Stargate.log.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); + Stargate.logger.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); ex.printStackTrace(); return null; } @@ -127,7 +127,7 @@ public final class BungeeHelper { Portal destinationPortal = PortalHandler.getBungeeGate(destination); // Specified an invalid gate. For now we'll just let them connect at their current location if (destinationPortal == null) { - Stargate.log.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); + Stargate.logger.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); return; } destinationPortal.teleport(player, destinationPortal, null); diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index bb5150f..616e347 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -152,10 +152,10 @@ public final class EconomyHandler { EconomyHandler.vault = vault; return true; } else { - Stargate.log.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); + Stargate.logger.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); } } else { - Stargate.log.info(Stargate.getString("prefix") + Stargate.getString("vaultLoadError")); + Stargate.logger.info(Stargate.getString("prefix") + Stargate.getString("vaultLoadError")); } economyEnabled = false; return false; diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 54ec4a0..31519ef 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -68,7 +68,7 @@ public final class EconomyHelper { public static void sendObtainMessage(String portalName, Player portalOwner, int earnings) { String obtainedMsg = Stargate.getString("ecoObtain"); obtainedMsg = replaceVars(obtainedMsg, portalName, earnings); - Stargate.sendMessage(portalOwner, obtainedMsg, false); + Stargate.sendSuccessMessage(portalOwner, obtainedMsg); } /** @@ -81,7 +81,7 @@ public final class EconomyHelper { public static void sendDeductMessage(String portalName, Player player, int cost) { String deductMsg = Stargate.getString("ecoDeduct"); deductMsg = replaceVars(deductMsg, portalName, cost); - Stargate.sendMessage(player, deductMsg, false); + Stargate.sendSuccessMessage(player, deductMsg); } /** @@ -94,7 +94,7 @@ public final class EconomyHelper { public static void sendInsufficientFundsMessage(String portalName, Player player, int cost) { String inFundMsg = Stargate.getString("ecoInFunds"); inFundMsg = replaceVars(inFundMsg, portalName, cost); - Stargate.sendMessage(player, inFundMsg); + Stargate.sendErrorMessage(player, inFundMsg); } /** @@ -107,7 +107,7 @@ public final class EconomyHelper { public static void sendRefundMessage(String portalName, Player player, int cost) { String refundMsg = Stargate.getString("ecoRefund"); refundMsg = replaceVars(refundMsg, portalName, -cost); - Stargate.sendMessage(player, refundMsg, false); + Stargate.sendSuccessMessage(player, refundMsg); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 37965b2..9c6eacb 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalOption; import org.bukkit.entity.Player; @@ -14,6 +15,102 @@ public final class PermissionHelper { } + /** + * Opens a portal if the given player is allowed to, and if the portal is not already open + * + * @param player

The player opening the portal

+ * @param portal

The portal to open

+ */ + public static void openPortal(Player player, Portal portal) { + Portal destination = portal.getDestination(); + + //Always-open gate -- Do nothing + if (portal.isAlwaysOn()) { + return; + } + + //Random gate -- Do nothing + if (portal.isRandom()) { + return; + } + + //Invalid destination + if ((destination == null) || (destination == portal)) { + Stargate.sendErrorMessage(player, Stargate.getString("invalidMsg")); + return; + } + + //Gate is already open + if (portal.isOpen()) { + // Close if this player opened the gate + if (portal.getActivePlayer() == player) { + portal.close(false); + } + return; + } + + //Gate that someone else is using -- Deny access + if ((!portal.isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + return; + } + + //Check if the player can use the private gate + if (portal.isPrivate() && !PermissionHelper.canPrivate(player, portal)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + return; + } + + //Destination blocked + if ((destination.isOpen()) && (!destination.isAlwaysOn())) { + Stargate.sendErrorMessage(player, Stargate.getString("blockMsg")); + return; + } + + //Open gate + portal.open(player, false); + } + + /** + * Creates a StargateAccessPortal and gives the result + * + *

The event is used for other plugins to bypass the permission checks

+ * + * @param player

The player trying to use the portal

+ * @param portal

The portal the player is trying to use

+ * @param deny

Whether the player's access has already been denied by a check

+ * @return

False if the player should be allowed through the portal

+ */ + public static boolean cannotAccessPortal(Player player, Portal portal, boolean deny) { + StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); + Stargate.server.getPluginManager().callEvent(event); + return event.getDeny(); + } + + /** + * Checks whether a given user cannot 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

False if the user is allowed to access the portal

+ */ + public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { + boolean deny = false; + // Check if player has access to this server for Bungee gates + if (entrancePortal.isBungee() && !PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { + Stargate.debug("cannotAccessPortal", "Cannot access server"); + deny = true; + } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { + Stargate.debug("cannotAccessPortal", "Cannot access network"); + deny = true; + } else if (!entrancePortal.isBungee() && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { + Stargate.debug("cannotAccessPortal", "Cannot access world"); + deny = true; + } + return cannotAccessPortal(player, entrancePortal, deny); + } + /** * Checks whether a player has the given permission * @@ -55,8 +152,9 @@ public final class PermissionHelper { /** * Checks whether a player can access the given world + * * @param player

The player trying to access the world

- * @param world

The world the player is trying to access

+ * @param world

The world the player is trying to access

* @return

False if the player should be allowed to access the world

*/ public static boolean cannotAccessWorld(Player player, String world) { @@ -96,6 +194,7 @@ public final class PermissionHelper { /** * Checks whether a player can access the given bungee server + * * @param player

The player trying to teleport

* @param server

The server the player is trying to connect to

* @return

True if the player is allowed to access the given server

From f2579c4b12e333c0fad00ec5906ac27220eb9b6c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 18:52:16 +0200 Subject: [PATCH 100/378] Adds back default constructor as removing it caused it to no longer load --- src/main/java/net/knarcraft/stargate/Stargate.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 12cc3dc..2a07a44 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -89,6 +89,13 @@ public class Stargate extends JavaPlugin { private FileConfiguration newConfig; private PluginManager pluginManager; + /** + * Empty constructor necessary for Spigot + */ + public Stargate() { + super(); + } + /** * Special constructor used for MockBukkit * From 24af26324ade435bcf79cff09b1cf123daf71c5f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 20 Sep 2021 19:23:57 +0200 Subject: [PATCH 101/378] Renames some methods to prevent confusion --- .../java/net/knarcraft/stargate/portal/PortalHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 8996cca..f12cf3d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -784,7 +784,7 @@ public class PortalHandler { File database = new File(location, world.getName() + ".db"); if (database.exists()) { - return loadGates(world, database); + return loadStarGates(world, database); } else { Stargate.logger.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); } @@ -798,7 +798,7 @@ public class PortalHandler { * @param database

The database file containing the gates

* @return

True if the gates were loaded successfully

*/ - private static boolean loadGates(World world, File database) { + private static boolean loadStarGates(World world, File database) { int lineIndex = 0; try { Scanner scanner = new Scanner(database); @@ -818,7 +818,7 @@ public class PortalHandler { continue; } - loadGate(portalData, world, lineIndex); + loadStarGate(portalData, world, lineIndex); } scanner.close(); @@ -843,7 +843,7 @@ public class PortalHandler { * @param world

The world to create the portal in

* @param lineIndex

The line index to report in case the user needs to fix an error

*/ - private static void loadGate(String[] portalData, World world, int lineIndex) { + private static void loadStarGate(String[] portalData, World world, int lineIndex) { //Load min. required portal data String name = portalData[0]; BlockLocation sign = new BlockLocation(world, portalData[1]); From b7c7252fadc5b85f6d0e738be21b5925775597ef Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 21 Sep 2021 18:28:18 +0200 Subject: [PATCH 102/378] Improves the differentiation between portals (stargates) and gates --- .../java/net/knarcraft/stargate/Stargate.java | 8 +- .../listener/PlayerEventListener.java | 2 +- .../stargate/listener/WorldEventListener.java | 4 +- .../stargate/portal/PortalHandler.java | 197 ++++++++---------- .../stargate/utility/BungeeHelper.java | 2 +- 5 files changed, 97 insertions(+), 116 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2a07a44..cfccea8 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -282,8 +282,8 @@ public class Stargate extends JavaPlugin { @Override public void onDisable() { - PortalHandler.closeAllGates(); - PortalHandler.clearGates(); + PortalHandler.closeAllPortals(); + PortalHandler.clearPortals(); managedWorlds.clear(); getServer().getScheduler().cancelTasks(this); } @@ -466,7 +466,7 @@ public class Stargate extends JavaPlugin { public void loadAllPortals() { for (World world : getServer().getWorlds()) { if (!managedWorlds.contains(world.getName())) { - PortalHandler.loadAllGates(world); + PortalHandler.loadAllPortals(world); managedWorlds.add(world.getName()); } } @@ -506,7 +506,7 @@ public class Stargate extends JavaPlugin { activePortalsQueue.clear(); openPortalsQueue.clear(); managedWorlds.clear(); - PortalHandler.clearGates(); + PortalHandler.clearPortals(); GateHandler.clearGates(); // Store the old Bungee enabled value diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index bea32d7..8416b9f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -56,7 +56,7 @@ public class PlayerEventListener implements Listener { return; } - Portal portal = PortalHandler.getBungeeGate(destination); + Portal portal = PortalHandler.getBungeePortal(destination); if (portal == null) { Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); return; diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 64cb5fa..f729fda 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -22,7 +22,7 @@ public class WorldEventListener implements Listener { @EventHandler public void onWorldLoad(WorldLoadEvent event) { if (!Stargate.managedWorlds.contains(event.getWorld().getName()) && - PortalHandler.loadAllGates(event.getWorld())) { + PortalHandler.loadAllPortals(event.getWorld())) { Stargate.managedWorlds.add(event.getWorld().getName()); } } @@ -38,7 +38,7 @@ public class WorldEventListener implements Listener { World world = event.getWorld(); if (Stargate.managedWorlds.contains(world.getName())) { Stargate.managedWorlds.remove(world.getName()); - PortalHandler.clearGates(world); + PortalHandler.clearPortals(world); } } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index f12cf3d..8eac971 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -72,33 +72,33 @@ public class PortalHandler { if (portal == null) { continue; } - // Check if destination is a random gate + //Check if destination is a random portal if (portal.isRandom()) { continue; } - // Check if destination is always open (Don't show if so) + //Check if destination is always open (Don't show if so) if (portal.isAlwaysOn() && !portal.isShown()) { continue; } - // Check if destination is this portal + //Check if destination is this portal if (destination.equalsIgnoreCase(entrancePortal.getName())) { continue; } - // Check if destination is a fixed gate not pointing to this gate + //Check if destination is a fixed portal not pointing to this portal if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(entrancePortal.getName())) { continue; } - // Allow random use by non-players (Minecarts) + //Allow random use by non-players (Minecarts) if (player == null) { destinations.add(portal.getName()); continue; } - // Check if this player can access the dest world + //Check if this player can access the dest world if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { Stargate.logger.info("cannot access world"); continue; } - // Visible to this player. + //Visible to this player. if (PermissionHelper.canSeePortal(player, portal)) { destinations.add(portal.getName()); } @@ -177,7 +177,7 @@ public class PortalHandler { sign.update(); } - saveAllGates(portal.getWorld()); + saveAllPortals(portal.getWorld()); } /** @@ -191,7 +191,7 @@ public class PortalHandler { String portalName = portal.getName().toLowerCase(); String networkName = portal.getNetwork().toLowerCase(); - // Bungee gates are stored in their own list + //Bungee portals are stored in their own list if (portal.isBungee()) { bungeePortals.put(portalName, portal); } else { @@ -250,7 +250,7 @@ public class PortalHandler { } if (getByBlock(idParent) != null) { - Stargate.debug("createPortal", "idParent belongs to existing gate"); + Stargate.debug("createPortal", "idParent belongs to existing stargate"); return null; } @@ -316,7 +316,7 @@ public class PortalHandler { return null; } - //If the player is trying to create a Bungee gate without permissions, drop out here + //If the player is trying to create a Bungee portal without permissions, drop out here if (options.indexOf(PortalOption.BUNGEE.getCharacterRepresentation()) != -1) { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); @@ -347,7 +347,7 @@ public class PortalHandler { boolean deny = false; String denyMsg = ""; - // Check if the player can create gates on this network + // Check if the player can create portals on this network if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); if (PermissionHelper.canCreatePersonalGate(player)) { @@ -372,11 +372,11 @@ public class PortalHandler { denyMsg = Stargate.getString("createGateDeny"); } - // Check if the user can create gates to this world. + //Check if the user can create portals to this world. if (!portalOptions.get(PortalOption.BUNGEE) && !deny && destinationName.length() > 0) { - Portal p = getByName(destinationName, network); - if (p != null) { - String world = p.getWorld().getName(); + Portal portal = getByName(destinationName, network); + if (portal != null) { + String world = portal.getWorld().getName(); if (PermissionHelper.cannotAccessWorld(player, world)) { Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); deny = true; @@ -386,9 +386,9 @@ public class PortalHandler { } // Bleh, gotta check to make sure none of this gate belongs to another gate. Boo slow. - for (RelativeBlockVector v : gate.getLayout().getBorder()) { - BlockLocation b = topLeft.modRelative(v.getRight(), v.getDepth(), v.getDistance(), modX, 1, modZ); - if (getByBlock(b.getBlock()) != null) { + for (RelativeBlockVector vector : gate.getLayout().getBorder()) { + BlockLocation blockLocation = topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); + if (getByBlock(blockLocation.getBlock()) != null) { Stargate.debug("createPortal", "Gate conflicts with existing gate"); Stargate.sendErrorMessage(player, Stargate.getString("createConflict")); return null; @@ -422,7 +422,7 @@ public class PortalHandler { return null; } - // Don't do network checks for bungee gates + //Don't do network checks for bungee portals if (portal.isBungee()) { if (bungeePortals.get(portal.getName().toLowerCase()) != null) { Stargate.debug("createPortal::Bungee", "Gate Exists"); @@ -436,7 +436,7 @@ public class PortalHandler { return null; } - // Check if there are too many gates in this network + //Check if there are too many gates in this network List netList = allPortalNetworks.get(portal.getNetwork().toLowerCase()); if (Stargate.maxGatesEachNetwork > 0 && netList != null && netList.size() >= Stargate.maxGatesEachNetwork) { Stargate.sendErrorMessage(player, Stargate.getString("createFull")); @@ -453,7 +453,7 @@ public class PortalHandler { EconomyHelper.sendDeductMessage(name, player, cost); } - // No button on an always-open gate. + //No button on an always-open portal. if (!portalOptions.get(PortalOption.ALWAYS_ON)) { button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); Directional buttonData = (Directional) Bukkit.createBlockData(gate.getPortalButton()); @@ -464,7 +464,7 @@ public class PortalHandler { registerPortal(portal); portal.drawSign(); - // Open always on gate + //Open an always on portal if (portal.isRandom() || portal.isBungee()) { portal.open(true); } else if (portal.isAlwaysOn()) { @@ -480,9 +480,9 @@ public class PortalHandler { } } - // Don't do network stuff for bungee gates + //Don't do network stuff for bungee portals if (!portal.isBungee()) { - // Open any always on gate pointing at this gate + //Open any always on portal pointing at this portal for (String originName : allPortalNetworks.get(portal.getNetwork().toLowerCase())) { Portal origin = getByName(originName, portal.getNetwork()); if (origin == null) continue; @@ -493,13 +493,13 @@ public class PortalHandler { } } - saveAllGates(portal.getWorld()); + saveAllPortals(portal.getWorld()); return portal; } /** - * Gets all portal options to be applied to a new gate + * Gets all portal options to be applied to a new portal * * @param player

The player creating the portal

* @param destinationName

The destination of the portal

@@ -513,23 +513,23 @@ public class PortalHandler { PermissionHelper.canUseOption(player, option)); } - // Can not create a non-fixed always-on gate. + //Can not create a non-fixed always-on portal if (portalOptions.get(PortalOption.ALWAYS_ON) && destinationName.length() == 0) { portalOptions.put(PortalOption.ALWAYS_ON, false); } - // Show isn't useful if always on is false + //Show isn't useful if always on is false if (portalOptions.get(PortalOption.SHOW) && !portalOptions.get(PortalOption.ALWAYS_ON)) { portalOptions.put(PortalOption.SHOW, false); } - // Random gates are always on and can't be shown + //Random portals are always on and can't be shown if (portalOptions.get(PortalOption.RANDOM)) { portalOptions.put(PortalOption.ALWAYS_ON, true); portalOptions.put(PortalOption.SHOW, false); } - // Bungee gates are always on and don't support Random + //Bungee portals are always on and don't support Random if (portalOptions.get(PortalOption.BUNGEE)) { portalOptions.put(PortalOption.ALWAYS_ON, true); portalOptions.put(PortalOption.RANDOM, false); @@ -621,7 +621,7 @@ public class PortalHandler { * Gets a portal given its control block (the block type used for the sign and button) * * @param block

The portal's control block

- * @return

The gate with the given control block

+ * @return

The portal with the given control block

*/ public static Portal getByControl(Block block) { return lookupControls.get(new BlockLocation(block)); @@ -638,21 +638,21 @@ public class PortalHandler { } /** - * Gets a bungee gate given its name + * Gets a bungee portal given its name * - * @param name

The name of the bungee gate to get

- * @return

A bungee gate

+ * @param name

The name of the bungee portal to get

+ * @return

A bungee portal

*/ - public static Portal getBungeeGate(String name) { + public static Portal getBungeePortal(String name) { return bungeePortals.get(name.toLowerCase()); } /** - * Saves all gates for the given world + * Saves all portals for the given world * - * @param world

The world to save gates for

+ * @param world

The world to save portals for

*/ - public static void saveAllGates(World world) { + public static void saveAllPortals(World world) { Stargate.managedWorlds.add(world.getName()); String loc = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; @@ -665,26 +665,16 @@ public class PortalHandler { StringBuilder builder = new StringBuilder(); BlockLocation button = portal.getButton(); - builder.append(portal.getName()); - builder.append(':'); - builder.append(portal.getId().toString()); - builder.append(':'); - builder.append((button != null) ? button.toString() : ""); - builder.append(':'); - builder.append(portal.getModX()); - builder.append(':'); - builder.append(portal.getModZ()); - builder.append(':'); - builder.append(portal.getYaw()); - builder.append(':'); - builder.append(portal.getTopLeft().toString()); - builder.append(':'); - builder.append(portal.getGate().getFilename()); - builder.append(':'); - builder.append(portal.isFixed() ? portal.getDestinationName() : ""); - builder.append(':'); - builder.append(portal.getNetwork()); - builder.append(':'); + builder.append(portal.getName()).append(':'); + builder.append(portal.getId().toString()).append(':'); + builder.append((button != null) ? button.toString() : "").append(':'); + builder.append(portal.getModX()).append(':'); + builder.append(portal.getModZ()).append(':'); + builder.append(portal.getYaw()).append(':'); + builder.append(portal.getTopLeft().toString()).append(':'); + builder.append(portal.getGate().getFilename()).append(':'); + builder.append(portal.isFixed() ? portal.getDestinationName() : "").append(':'); + builder.append(portal.getNetwork()).append(':'); UUID owner = portal.getOwnerUUID(); if (owner != null) { builder.append(portal.getOwnerUUID().toString()); @@ -692,24 +682,15 @@ public class PortalHandler { builder.append(portal.getOwnerName()); } builder.append(':'); - builder.append(portal.isHidden()); - builder.append(':'); - builder.append(portal.isAlwaysOn()); - builder.append(':'); - builder.append(portal.isPrivate()); - builder.append(':'); - builder.append(portal.getWorld().getName()); - builder.append(':'); - builder.append(portal.isFree()); - builder.append(':'); - builder.append(portal.isBackwards()); - builder.append(':'); - builder.append(portal.isShown()); - builder.append(':'); - builder.append(portal.isNoNetwork()); - builder.append(':'); - builder.append(portal.isRandom()); - builder.append(':'); + builder.append(portal.isHidden()).append(':'); + builder.append(portal.isAlwaysOn()).append(':'); + builder.append(portal.isPrivate()).append(':'); + builder.append(portal.getWorld().getName()).append(':'); + builder.append(portal.isFree()).append(':'); + builder.append(portal.isBackwards()).append(':'); + builder.append(portal.isShown()).append(':'); + builder.append(portal.isNoNetwork()).append(':'); + builder.append(portal.isRandom()).append(':'); builder.append(portal.isBungee()); bw.append(builder.toString()); @@ -723,9 +704,9 @@ public class PortalHandler { } /** - * Clears all loaded gates and gate data from all worlds + * Clears all loaded portals and portal data from all worlds */ - public static void clearGates() { + public static void clearPortals() { lookupBlocks.clear(); portalLookupByNetwork.clear(); lookupEntrances.clear(); @@ -735,11 +716,11 @@ public class PortalHandler { } /** - * Clears all gates loaded in a given world + * Clears all portals loaded in a given world * * @param world

The world containing the portals to clear

*/ - public static void clearGates(World world) { + public static void clearPortals(World world) { //This is necessary List portalsToRemove = new ArrayList<>(); allPortals.forEach((portal) -> { @@ -748,7 +729,7 @@ public class PortalHandler { } }); - clearGates(portalsToRemove); + clearPortals(portalsToRemove); } /** @@ -756,7 +737,7 @@ public class PortalHandler { * * @param portalsToRemove

A list of portals to remove

*/ - private static void clearGates(List portalsToRemove) { + private static void clearPortals(List portalsToRemove) { List portalNames = new ArrayList<>(); portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); @@ -773,18 +754,18 @@ public class PortalHandler { } /** - * Loads all gates for the given world + * Loads all portals for the given world * - * @param world

The world to load gates for

- * @return

True if gates could be loaded

+ * @param world

The world to load portals for

+ * @return

True if portals could be loaded

*/ - public static boolean loadAllGates(World world) { + public static boolean loadAllPortals(World world) { String location = Stargate.getSaveLocation(); File database = new File(location, world.getName() + ".db"); if (database.exists()) { - return loadStarGates(world, database); + return loadPortals(world, database); } else { Stargate.logger.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); } @@ -792,13 +773,13 @@ public class PortalHandler { } /** - * Loads all the given gates + * Loads all the given portals * - * @param world

The world to load gates for

- * @param database

The database file containing the gates

- * @return

True if the gates were loaded successfully

+ * @param world

The world to load portals for

+ * @param database

The database file containing the portals

+ * @return

True if the portals were loaded successfully

*/ - private static boolean loadStarGates(World world, File database) { + private static boolean loadPortals(World world, File database) { int lineIndex = 0; try { Scanner scanner = new Scanner(database); @@ -818,12 +799,12 @@ public class PortalHandler { continue; } - loadStarGate(portalData, world, lineIndex); + loadPortal(portalData, world, lineIndex); } scanner.close(); // Open any always-on gates. Do this here as it should be more efficient than in the loop. - TwoTuple portalCounts = openAlwaysOpenGates(); + TwoTuple portalCounts = openAlwaysOpenPortals(); Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), @@ -837,13 +818,13 @@ public class PortalHandler { } /** - * Loads one gate from a data array + * Loads one portal from a data array * * @param portalData

The array describing the portal

* @param world

The world to create the portal in

* @param lineIndex

The line index to report in case the user needs to fix an error

*/ - private static void loadStarGate(String[] portalData, World world, int lineIndex) { + private static void loadPortal(String[] portalData, World world, int lineIndex) { //Load min. required portal data String name = portalData[0]; BlockLocation sign = new BlockLocation(world, portalData[1]); @@ -878,7 +859,7 @@ public class PortalHandler { } catch (IllegalArgumentException ex) { // neither name nor UUID, so keep it as-is ownerName = ownerString; - Stargate.debug("loadAllGates", "Invalid stargate owner string: " + ownerString); + Stargate.debug("loadAllPortals", "Invalid stargate owner string: " + ownerString); } } else { ownerName = ownerString; @@ -908,11 +889,11 @@ public class PortalHandler { } /** - * Opens all always open gates + * Opens all always open portals * - * @return

A TwoTuple where the first value is the number of always open gates and the second value is the total number of gates

+ * @return

A TwoTuple where the first value is the number of always open portals and the second value is the total number of portals

*/ - private static TwoTuple openAlwaysOpenGates() { + private static TwoTuple openAlwaysOpenPortals() { int portalCount = 0; int openCount = 0; for (Iterator iterator = allPortals.iterator(); iterator.hasNext(); ) { @@ -923,7 +904,7 @@ public class PortalHandler { // Verify portal integrity/register portal if (!portal.wasVerified() && (!portal.isVerified() || !portal.checkIntegrity())) { - destroyInvalidStarGate(portal); + destroyInvalidPortal(portal); iterator.remove(); continue; } @@ -940,15 +921,15 @@ public class PortalHandler { } /** - * Destroys a star gate which has failed its integrity test + * Destroys a portal which has failed its integrity test * - * @param portal

The portal of the star gate

+ * @param portal

The portal of the star portal

*/ - private static void destroyInvalidStarGate(Portal portal) { + private static void destroyInvalidPortal(Portal portal) { // DEBUG for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { - Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); + Stargate.debug("loadAllPortals", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); } } PortalHandler.unregisterPortal(portal, false); @@ -956,9 +937,9 @@ public class PortalHandler { } /** - * Closes all star gate portals + * Closes all portals */ - public static void closeAllGates() { + public static void closeAllPortals() { Stargate.logger.info("Closing all stargates."); for (Portal portal : allPortals) { if (portal != null) { diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 2939bae..a894503 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -124,7 +124,7 @@ public final class BungeeHelper { if (player == null) { Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); } else { - Portal destinationPortal = PortalHandler.getBungeeGate(destination); + Portal destinationPortal = PortalHandler.getBungeePortal(destination); // Specified an invalid gate. For now we'll just let them connect at their current location if (destinationPortal == null) { Stargate.logger.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); From dd7176fa12b338a2eef99a1534fc687183f1d23d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 22 Sep 2021 13:42:21 +0200 Subject: [PATCH 103/378] Adds config migration to reduce annoyance and improve backwards compatibility --- .../java/net/knarcraft/stargate/Stargate.java | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index cfccea8..75be795 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.container.BlockChangeRequest; +import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; @@ -32,9 +33,12 @@ import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.messaging.Messenger; import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -68,6 +72,7 @@ public class Stargate extends JavaPlugin { private static boolean destroyExplosion = false; //Temp workaround for snowmen, don't check gate entrance public static boolean ignoreEntrance = false; + private String dataFolderPath; public static ChatColor signColor; // Used for debug @@ -298,7 +303,7 @@ public class Stargate extends JavaPlugin { Stargate.stargate = this; // Set portalFile and gateFolder to the plugin folder as defaults. - String dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); + dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); portalFolder = dataFolderPath + "/portals/"; gateFolder = dataFolderPath + "/gates/"; String languageFolder = dataFolderPath + "/lang/"; @@ -365,6 +370,11 @@ public class Stargate extends JavaPlugin { public void loadConfig() { this.reloadConfig(); newConfig = this.getConfig(); + + if (newConfig.getString("lang") != null) { + migrateConfig(newConfig); + } + // Copy default values if required newConfig.options().copyDefaults(true); @@ -388,6 +398,53 @@ public class Stargate extends JavaPlugin { this.saveConfig(); } + /** + * Changes all configuration values from the old name to the new name + * @param newConfig

The config to read from and write to

+ */ + private void migrateConfig(FileConfiguration newConfig) { + try { + newConfig.save(dataFolderPath + "/config.old"); + } catch (IOException e) { + Stargate.debug("Stargate::migrateConfig", "Unable to save old backup and do migration"); + e.printStackTrace(); + return; + } + + List> migrationFields = new ArrayList<>(); + migrationFields.add(new TwoTuple<>("lang", "language")); + migrationFields.add(new TwoTuple<>("portal-folder", "folders.portalFolder")); + migrationFields.add(new TwoTuple<>("gate-folder", "folders.gateFolder")); + migrationFields.add(new TwoTuple<>("default-gate-network", "gates.defaultGateNetwork")); + migrationFields.add(new TwoTuple<>("destroyexplosion", "gates.integrity.destroyedByExplosion")); + migrationFields.add(new TwoTuple<>("maxgates", "gates.maxGatesEachNetwork")); + migrationFields.add(new TwoTuple<>("destMemory", "gates.cosmetic.rememberDestination")); + migrationFields.add(new TwoTuple<>("ignoreEntrance", "gates.integrity.ignoreEntrance")); + migrationFields.add(new TwoTuple<>("handleVehicles", "gates.functionality.handleVehicles")); + migrationFields.add(new TwoTuple<>("sortLists", "gates.cosmetic.sortNetworkDestinations")); + migrationFields.add(new TwoTuple<>("protectEntrance", "gates.integrity.protectEntrance")); + migrationFields.add(new TwoTuple<>("enableBungee", "gates.functionality.enableBungee")); + migrationFields.add(new TwoTuple<>("verifyPortals", "gates.integrity.verifyPortals")); + migrationFields.add(new TwoTuple<>("signColor", "gates.cosmetic.signColor")); + migrationFields.add(new TwoTuple<>("debug", "debugging.debug")); + migrationFields.add(new TwoTuple<>("permdebug", "debugging.permissionDebug")); + migrationFields.add(new TwoTuple<>("useeconomy", "economy.useEconomy")); + migrationFields.add(new TwoTuple<>("createcost", "economy.createCost")); + migrationFields.add(new TwoTuple<>("destroycost", "economy.destroyCost")); + migrationFields.add(new TwoTuple<>("usecost", "economy.useCost")); + migrationFields.add(new TwoTuple<>("toowner", "economy.toOwner")); + migrationFields.add(new TwoTuple<>("chargefreedestination", "economy.chargeFreeDestination")); + migrationFields.add(new TwoTuple<>("freegatesgreen", "economy.freeGatesGreen")); + + for (TwoTuple migration : migrationFields) { + if (newConfig.contains(migration.getFirstValue())) { + Object oldValue = newConfig.get(migration.getFirstValue()); + newConfig.set(migration.getSecondValue(), oldValue); + newConfig.set(migration.getFirstValue(), null); + } + } + } + /** * Loads all config values related to gates */ From 461202503e0e02ebd49c000295538f72d17ee3c7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 22 Sep 2021 13:52:22 +0200 Subject: [PATCH 104/378] Adds migration for useiconomy and CheckUpdates which were found in old config files --- src/main/java/net/knarcraft/stargate/Stargate.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 75be795..d0c67c3 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -428,6 +428,7 @@ public class Stargate extends JavaPlugin { migrationFields.add(new TwoTuple<>("signColor", "gates.cosmetic.signColor")); migrationFields.add(new TwoTuple<>("debug", "debugging.debug")); migrationFields.add(new TwoTuple<>("permdebug", "debugging.permissionDebug")); + migrationFields.add(new TwoTuple<>("useiconomy", "economy.useEconomy")); migrationFields.add(new TwoTuple<>("useeconomy", "economy.useEconomy")); migrationFields.add(new TwoTuple<>("createcost", "economy.createCost")); migrationFields.add(new TwoTuple<>("destroycost", "economy.destroyCost")); @@ -435,12 +436,17 @@ public class Stargate extends JavaPlugin { migrationFields.add(new TwoTuple<>("toowner", "economy.toOwner")); migrationFields.add(new TwoTuple<>("chargefreedestination", "economy.chargeFreeDestination")); migrationFields.add(new TwoTuple<>("freegatesgreen", "economy.freeGatesGreen")); + migrationFields.add(new TwoTuple<>("CheckUpdates", "")); for (TwoTuple migration : migrationFields) { - if (newConfig.contains(migration.getFirstValue())) { - Object oldValue = newConfig.get(migration.getFirstValue()); - newConfig.set(migration.getSecondValue(), oldValue); - newConfig.set(migration.getFirstValue(), null); + String oldPath = migration.getFirstValue(); + if (newConfig.contains(oldPath)) { + String newPath = migration.getSecondValue(); + Object oldValue = newConfig.get(oldPath); + if (!newPath.trim().isEmpty()) { + newConfig.set(newPath, oldValue); + } + newConfig.set(oldPath, null); } } } From 650a26402a34eb889c41cffb59ea68ef911f07d9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 23 Sep 2021 17:50:43 +0200 Subject: [PATCH 105/378] Moves all config migration mappings to its own file --- .../knarcraft/stargate/LanguageLoader.java | 214 ++++++------------ .../java/net/knarcraft/stargate/Stargate.java | 52 ++--- .../stargate/utility/FileHelper.java | 125 ++++++++++ src/main/resources/config-migrations.txt | 25 ++ 4 files changed, 234 insertions(+), 182 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/FileHelper.java create mode 100644 src/main/resources/config-migrations.txt diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index 4367eae..e64bb99 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -1,20 +1,13 @@ package net.knarcraft.stargate; -import org.bukkit.ChatColor; +import net.knarcraft.stargate.utility.FileHelper; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; @@ -48,8 +41,8 @@ public class LanguageLoader { updateLanguage(chosenLanguage); loadedStringTranslations = load(chosenLanguage); - // We have a default hashMap used for when new text is added. - InputStream inputStream = getClass().getResourceAsStream("/lang/en.txt"); + //Load english as backup language in case the chosen language is missing newly added text strings + InputStream inputStream = FileHelper.getInputStreamForInternalFile("/lang/en.txt"); if (inputStream != null) { loadedBackupStrings = load("en", inputStream); } else { @@ -103,8 +96,6 @@ public class LanguageLoader { */ private void updateLanguage(String language) { // Load the current language file - List keyList = new ArrayList<>(); - List valueList = new ArrayList<>(); Map currentLanguageValues = load(language); @@ -118,46 +109,10 @@ public class LanguageLoader { return; } - boolean updated = false; - FileOutputStream fileOutputStream = null; try { - if (readChangedLanguageStrings(inputStream, keyList, valueList, currentLanguageValues)) { - updated = true; - } - - // Save file - fileOutputStream = new FileOutputStream(languageFolder + language + ".txt"); - OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8); - BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter); - - // Output normal Language data - for (int i = 0; i < keyList.size(); i++) { - bufferedWriter.write(keyList.get(i) + valueList.get(i)); - bufferedWriter.newLine(); - } - bufferedWriter.newLine(); - // Output any custom language strings the user had - if (currentLanguageValues != null) { - for (String key : currentLanguageValues.keySet()) { - bufferedWriter.write(key + "=" + currentLanguageValues.get(key)); - bufferedWriter.newLine(); - } - } - - bufferedWriter.close(); + readChangedLanguageStrings(inputStream, language, currentLanguageValues); } catch (IOException ex) { ex.printStackTrace(); - } finally { - if (fileOutputStream != null) { - try { - fileOutputStream.close(); - } catch (Exception e) { - //Ignored - } - } - } - if (updated) { - Stargate.logger.info("[stargate] Your language file (" + language + ".txt) has been updated"); } } @@ -165,51 +120,70 @@ public class LanguageLoader { * Reads language strings * * @param inputStream

The input stream to read from

- * @param keyList

The key list to add keys to

- * @param valueList

The value list to add values to

+ * @param language

The selected language

* @param currentLanguageValues

The current values of the loaded/processed language

- * @return

True if at least one line was updated

* @throws IOException

if unable to read a language file

*/ - private boolean readChangedLanguageStrings(InputStream inputStream, List keyList, List valueList, - Map currentLanguageValues) throws IOException { - boolean updated = false; - // Input stuff - InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + private void readChangedLanguageStrings(InputStream inputStream, String language, Map currentLanguageValues) throws IOException { - String line = bufferedReader.readLine(); - boolean firstLine = true; - while (line != null) { - // Strip UTF BOM - if (firstLine) { - line = removeUTF8BOM(line); - firstLine = false; - } - // Split at first "=" - int equalSignIndex = line.indexOf('='); - if (equalSignIndex == -1) { - keyList.add(""); - valueList.add(""); - line = bufferedReader.readLine(); - continue; - } - String key = line.substring(0, equalSignIndex); - String value = line.substring(equalSignIndex); + //Get language values + BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); + Map internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader); - if (currentLanguageValues == null || currentLanguageValues.get(key) == null) { - keyList.add(key); - valueList.add(value); - updated = true; - } else { - keyList.add(key); - valueList.add("=" + currentLanguageValues.get(key).replace('\u00A7', '&')); - currentLanguageValues.remove(key); - } - line = bufferedReader.readLine(); + //If currentLanguageValues is null; the chosen language is invalid, use the internal strings instead + if (currentLanguageValues == null) { + return; } - bufferedReader.close(); - return updated; + + //If a key is not found in the language file, add the one in the internal file. Must update the external file + if (!internalLanguageValues.keySet().equals(currentLanguageValues.keySet())) { + Map newLanguageValues = new HashMap<>(); + boolean updateNecessary = false; + for (String key : internalLanguageValues.keySet()) { + if (currentLanguageValues.get(key) == null) { + newLanguageValues.put(key, internalLanguageValues.get(key)); + //Found at least one value in the internal file not in the external file. Need to update + updateNecessary = true; + } else { + newLanguageValues.put(key, currentLanguageValues.get(key)); + currentLanguageValues.remove(key); + } + } + //Update the file itself + if (updateNecessary) { + updateLanguageFile(language, newLanguageValues, currentLanguageValues); + Stargate.logger.info("[stargate] Your language file (" + language + ".txt) has been updated"); + } + } + } + + /** + * Updates the language file for a given language + * + * @param language

The language to update

+ * @param languageStrings

The updated language strings

+ * @param customLanguageStrings

Any custom language strings not recognized

+ * @throws IOException

If unable to write to the language file

+ */ + private void updateLanguageFile(String language, Map languageStrings, + Map customLanguageStrings) throws IOException { + BufferedWriter bufferedWriter = FileHelper.getBufferedWriterFromString(languageFolder + language + ".txt"); + + //Output normal Language data + for (String key : languageStrings.keySet()) { + bufferedWriter.write(key + "=" + languageStrings.get(key)); + bufferedWriter.newLine(); + } + bufferedWriter.newLine(); + //Output any custom language strings the user had + if (customLanguageStrings != null) { + for (String key : customLanguageStrings.keySet()) { + bufferedWriter.write(key + "=" + customLanguageStrings.get(key)); + bufferedWriter.newLine(); + } + } + bufferedWriter.close(); } /** @@ -230,64 +204,24 @@ public class LanguageLoader { * @return

A mapping between loaded string indexes and the strings to display

*/ private Map load(String lang, InputStream inputStream) { - Map strings = new HashMap<>(); - FileInputStream fileInputStream = null; - InputStreamReader inputStreamReader; + Map strings; + BufferedReader bufferedReader; try { if (inputStream == null) { - fileInputStream = new FileInputStream(languageFolder + lang + ".txt"); - inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8); + bufferedReader = FileHelper.getBufferedReaderFromString(languageFolder + lang + ".txt"); } else { - inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); } - readLanguageFile(inputStreamReader, strings); + strings = FileHelper.readKeyValuePairs(bufferedReader); } catch (Exception e) { if (Stargate.debuggingEnabled) { Stargate.logger.info("Unable to load chosen language"); } return null; - } finally { - if (fileInputStream != null) { - try { - fileInputStream.close(); - } catch (IOException e) { - //Ignored - } - } } return strings; } - /** - * Reads a language file given its input stream - * - * @param inputStreamReader

The input stream reader to read from

- * @param strings

The loaded string pairs

- * @throws IOException

If unable to read the file

- */ - private void readLanguageFile(InputStreamReader inputStreamReader, Map strings) throws IOException { - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - String line = bufferedReader.readLine(); - boolean firstLine = true; - while (line != null) { - // Strip UTF BOM - if (firstLine) { - line = removeUTF8BOM(line); - firstLine = false; - } - // Split at first "=" - int equalSignIndex = line.indexOf('='); - if (equalSignIndex == -1) { - line = bufferedReader.readLine(); - continue; - } - String key = line.substring(0, equalSignIndex); - String val = ChatColor.translateAlternateColorCodes('&', line.substring(equalSignIndex + 1)); - strings.put(key, val); - line = bufferedReader.readLine(); - } - } - /** * Prints debug output to the console for checking of loading language strings/translations */ @@ -303,18 +237,4 @@ public class LanguageLoader { } } - /** - * Removes the UTF-8 Byte Order Mark if present - * - * @param string

The string to remove the BOM from

- * @return

A string guaranteed without a BOM

- */ - private String removeUTF8BOM(String string) { - String UTF8_BOM = "\uFEFF"; - if (string.startsWith(UTF8_BOM)) { - string = string.substring(1); - } - return string; - } - } diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index d0c67c3..975c97c 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -3,7 +3,6 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.container.BlockChangeRequest; -import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; @@ -18,6 +17,7 @@ import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.EconomyHandler; +import net.knarcraft.stargate.utility.FileHelper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; @@ -34,11 +34,9 @@ import org.bukkit.plugin.messaging.Messenger; import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -400,6 +398,7 @@ public class Stargate extends JavaPlugin { /** * Changes all configuration values from the old name to the new name + * * @param newConfig

The config to read from and write to

*/ private void migrateConfig(FileConfiguration newConfig) { @@ -411,42 +410,25 @@ public class Stargate extends JavaPlugin { return; } - List> migrationFields = new ArrayList<>(); - migrationFields.add(new TwoTuple<>("lang", "language")); - migrationFields.add(new TwoTuple<>("portal-folder", "folders.portalFolder")); - migrationFields.add(new TwoTuple<>("gate-folder", "folders.gateFolder")); - migrationFields.add(new TwoTuple<>("default-gate-network", "gates.defaultGateNetwork")); - migrationFields.add(new TwoTuple<>("destroyexplosion", "gates.integrity.destroyedByExplosion")); - migrationFields.add(new TwoTuple<>("maxgates", "gates.maxGatesEachNetwork")); - migrationFields.add(new TwoTuple<>("destMemory", "gates.cosmetic.rememberDestination")); - migrationFields.add(new TwoTuple<>("ignoreEntrance", "gates.integrity.ignoreEntrance")); - migrationFields.add(new TwoTuple<>("handleVehicles", "gates.functionality.handleVehicles")); - migrationFields.add(new TwoTuple<>("sortLists", "gates.cosmetic.sortNetworkDestinations")); - migrationFields.add(new TwoTuple<>("protectEntrance", "gates.integrity.protectEntrance")); - migrationFields.add(new TwoTuple<>("enableBungee", "gates.functionality.enableBungee")); - migrationFields.add(new TwoTuple<>("verifyPortals", "gates.integrity.verifyPortals")); - migrationFields.add(new TwoTuple<>("signColor", "gates.cosmetic.signColor")); - migrationFields.add(new TwoTuple<>("debug", "debugging.debug")); - migrationFields.add(new TwoTuple<>("permdebug", "debugging.permissionDebug")); - migrationFields.add(new TwoTuple<>("useiconomy", "economy.useEconomy")); - migrationFields.add(new TwoTuple<>("useeconomy", "economy.useEconomy")); - migrationFields.add(new TwoTuple<>("createcost", "economy.createCost")); - migrationFields.add(new TwoTuple<>("destroycost", "economy.destroyCost")); - migrationFields.add(new TwoTuple<>("usecost", "economy.useCost")); - migrationFields.add(new TwoTuple<>("toowner", "economy.toOwner")); - migrationFields.add(new TwoTuple<>("chargefreedestination", "economy.chargeFreeDestination")); - migrationFields.add(new TwoTuple<>("freegatesgreen", "economy.freeGatesGreen")); - migrationFields.add(new TwoTuple<>("CheckUpdates", "")); + Map migrationFields; + try { + migrationFields = FileHelper.readKeyValuePairs(FileHelper.getBufferedReaderFromInputStream( + FileHelper.getInputStreamForInternalFile("/config-migrations.txt"))); + } catch (IOException e) { + Stargate.debug("Stargate::migrateConfig", "Unable to load config migration file"); + e.printStackTrace(); + return; + } - for (TwoTuple migration : migrationFields) { - String oldPath = migration.getFirstValue(); - if (newConfig.contains(oldPath)) { - String newPath = migration.getSecondValue(); - Object oldValue = newConfig.get(oldPath); + //Replace old config names with the new ones + for (String key : migrationFields.keySet()) { + if (newConfig.contains(key)) { + String newPath = migrationFields.get(key); + Object oldValue = newConfig.get(key); if (!newPath.trim().isEmpty()) { newConfig.set(newPath, oldValue); } - newConfig.set(oldPath, null); + newConfig.set(key, null); } } } diff --git a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java new file mode 100644 index 0000000..829b5dc --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java @@ -0,0 +1,125 @@ +package net.knarcraft.stargate.utility; + +import org.bukkit.ChatColor; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +/** + * Helper class for reading files + */ +public final class FileHelper { + + private FileHelper() { + + } + + /** + * Gets a buffered reader from a string pointing to a file + * + * @param file

The file to read

+ * @return

A buffered reader reading the file

+ */ + public static InputStream getInputStreamForInternalFile(String file) { + return FileHelper.class.getResourceAsStream(file); + } + + /** + * Gets a buffered reader from a string pointing to a file + * + * @param file

The file to read

+ * @return

A buffered reader reading the file

+ * @throws FileNotFoundException

If the given file does not exist

+ */ + public static BufferedReader getBufferedReaderFromString(String file) throws FileNotFoundException { + FileInputStream fileInputStream = new FileInputStream(file); + return getBufferedReaderFromInputStream(fileInputStream); + } + + /** + * Gets a buffered reader from an input stream + * + * @param inputStream

The input stream to read

+ * @return

A buffered reader reading the stream

+ */ + public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) { + InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + return new BufferedReader(inputStreamReader); + } + + /** + * Gets a buffered writer from a string pointing to a file + * + * @param file

The file to write to

+ * @return

A buffered writer writing to the file

+ * @throws FileNotFoundException

If the file does not exist

+ */ + public static BufferedWriter getBufferedWriterFromString(String file) throws FileNotFoundException { + FileOutputStream fileOutputStream = new FileOutputStream(file); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8); + return new BufferedWriter(outputStreamWriter); + } + + /** + * Reads key value pairs from an input stream + * + * @param bufferedReader

The buffered reader to read

+ * @return

A map containing the read pairs

+ * @throws IOException

If unable to read from the stream

+ */ + public static Map readKeyValuePairs(BufferedReader bufferedReader) throws IOException { + + Map readPairs = new HashMap<>(); + + String line = bufferedReader.readLine(); + boolean firstLine = true; + while (line != null) { + // Strip UTF BOM + if (firstLine) { + line = removeUTF8BOM(line); + firstLine = false; + } + //Split at first "=" + int equalSignIndex = line.indexOf('='); + if (equalSignIndex == -1) { + line = bufferedReader.readLine(); + continue; + } + + //Read the line + String key = line.substring(0, equalSignIndex); + String value = ChatColor.translateAlternateColorCodes('&', line.substring(equalSignIndex + 1)); + readPairs.put(key, value); + + line = bufferedReader.readLine(); + } + bufferedReader.close(); + + return readPairs; + } + + /** + * Removes the UTF-8 Byte Order Mark if present + * + * @param string

The string to remove the BOM from

+ * @return

A string guaranteed without a BOM

+ */ + private static String removeUTF8BOM(String string) { + String UTF8_BOM = "\uFEFF"; + if (string.startsWith(UTF8_BOM)) { + string = string.substring(1); + } + return string; + } + +} diff --git a/src/main/resources/config-migrations.txt b/src/main/resources/config-migrations.txt new file mode 100644 index 0000000..eb53155 --- /dev/null +++ b/src/main/resources/config-migrations.txt @@ -0,0 +1,25 @@ +lang=language +portal-folder=folders.portalFolder +gate-folder=folders.gateFolder +default-gate-network=gates.defaultGateNetwork +destroyexplosion=gates.integrity.destroyedByExplosion +maxgates=gates.maxGatesEachNetwork +destMemory=gates.cosmetic.rememberDestination +ignoreEntrance=gates.integrity.ignoreEntrance +handleVehicles=gates.functionality.handleVehicles +sortLists=gates.cosmetic.sortNetworkDestinations +protectEntrance=gates.integrity.protectEntrance +enableBungee=gates.functionality.enableBungee +verifyPortals=gates.integrity.verifyPortals +signColor=gates.cosmetic.signColor +debug=debugging.debug +permdebug=debugging.permissionDebug +useiconomy=economy.useEconomy +useeconomy=economy.useEconomy +createcost=economy.createCost +destroycost=economy.destroyCost +usecost=economy.useCost +toowner=economy.toOwner +chargefreedestination=economy.chargeFreeDestination +freegatesgreen=economy.freeGatesGreen +CheckUpdates= \ No newline at end of file From 98cee192aa4d655fc43af5198aec31216ee8d60d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 23 Sep 2021 18:12:57 +0200 Subject: [PATCH 106/378] Fixes some behavior when a language is valid, but the language file does not exist --- src/main/java/net/knarcraft/stargate/LanguageLoader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index e64bb99..c9e5f6e 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -126,13 +126,14 @@ public class LanguageLoader { */ private void readChangedLanguageStrings(InputStream inputStream, String language, Map currentLanguageValues) throws IOException { - //Get language values BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); Map internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader); - //If currentLanguageValues is null; the chosen language is invalid, use the internal strings instead + //If currentLanguageValues is null; the chosen language has not been used before if (currentLanguageValues == null) { + updateLanguageFile(language, internalLanguageValues, null); + Stargate.logger.info("[stargate] Language (" + language + ") has been loaded"); return; } From 8ada84ddb3aa3a1abceefef1320daf2e926fa5bf Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 23 Sep 2021 18:21:15 +0200 Subject: [PATCH 107/378] Improves an error message --- src/main/java/net/knarcraft/stargate/LanguageLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index c9e5f6e..1cf4951 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -216,7 +216,7 @@ public class LanguageLoader { strings = FileHelper.readKeyValuePairs(bufferedReader); } catch (Exception e) { if (Stargate.debuggingEnabled) { - Stargate.logger.info("Unable to load chosen language"); + Stargate.logger.info("[stargate] Unable to load language " + lang); } return null; } From 7dcf050d96f84805546c2b13974bab1d7031b6e9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 25 Sep 2021 12:46:59 +0200 Subject: [PATCH 108/378] Removes a function for checking if a control block is powered as it's never used --- .../net/knarcraft/stargate/portal/Portal.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 6245300..a5487de 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -613,25 +613,6 @@ public class Portal { this.fixed = fixed; } - /** - * Gets whether at least one of this portal's control blocks are powered - * - * @return

True if at least one control block is powered

- */ - public boolean isPowered() { - RelativeBlockVector[] controls = gate.getLayout().getControls(); - - for (RelativeBlockVector vector : controls) { - BlockData data = getBlockAt(vector).getBlock().getBlockData(); - - if (data instanceof Powerable && ((Powerable) data).isPowered()) { - return true; - } - } - - return false; - } - /** * Teleports a player to this portal * From e4f71f1b71eb42e5177538997cce314bf3dac245 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 25 Sep 2021 13:22:50 +0200 Subject: [PATCH 109/378] Extracts some portal creation code into separate methods --- .../net/knarcraft/stargate/portal/Portal.java | 6 +- .../stargate/portal/PortalHandler.java | 118 ++++++++++++------ 2 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index a5487de..75824b2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -22,7 +22,6 @@ import org.bukkit.block.Sign; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Orientable; -import org.bukkit.block.data.Powerable; import org.bukkit.block.data.type.Slab; import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Boat; @@ -42,7 +41,7 @@ import java.util.UUID; import java.util.logging.Level; /** - * This class represents a portal in space which points to one or several other portals + * This class represents a portal in space which points to one or several portals */ public class Portal { @@ -569,7 +568,8 @@ public class Portal { Portal end = getDestination(); if (end != null && end.isOpen()) { - end.deactivate(); // Clear it's destination first. + //Clear its destination first + end.deactivate(); end.close(false); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 8eac971..e6f2f72 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -395,25 +395,24 @@ public class PortalHandler { } } - BlockLocation button = null; Portal portal; - portal = new Portal(topLeft, modX, modZ, yaw, id, button, destinationName, name, false, network, + portal = new Portal(topLeft, modX, modZ, yaw, id, null, destinationName, name, false, network, gate, player.getUniqueId(), player.getName(), portalOptions); int cost = EconomyHandler.getCreateCost(player, gate); // Call StargateCreateEvent - StargateCreateEvent cEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); - Stargate.server.getPluginManager().callEvent(cEvent); - if (cEvent.isCancelled()) { + StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); + Stargate.server.getPluginManager().callEvent(stargateCreateEvent); + if (stargateCreateEvent.isCancelled()) { return null; } - if (cEvent.getDeny()) { - Stargate.sendErrorMessage(player, cEvent.getDenyReason()); + if (stargateCreateEvent.getDeny()) { + Stargate.sendErrorMessage(player, stargateCreateEvent.getDenyReason()); return null; } - cost = cEvent.getCost(); + cost = stargateCreateEvent.getCost(); // Name & Network can be changed in the event, so do these checks here. if (portal.getName().length() < 1 || portal.getName().length() > 11) { @@ -455,42 +454,16 @@ public class PortalHandler { //No button on an always-open portal. if (!portalOptions.get(PortalOption.ALWAYS_ON)) { - button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); - Directional buttonData = (Directional) Bukkit.createBlockData(gate.getPortalButton()); - buttonData.setFacing(buttonFacing); - button.getBlock().setBlockData(buttonData); - portal.setButton(button); + generatePortalButton(portal, topLeft, buttonVector, buttonFacing); } + //Register the new portal registerPortal(portal); - portal.drawSign(); - //Open an always on portal - if (portal.isRandom() || portal.isBungee()) { - portal.open(true); - } else if (portal.isAlwaysOn()) { - Portal dest = getByName(destinationName, portal.getNetwork()); - if (dest != null) { - portal.open(true); - dest.drawSign(); - } - // Set the inside of the gate to its closed material - } else { - for (BlockLocation inside : portal.getEntrances()) { - inside.setType(portal.getGate().getPortalClosedBlock()); - } - } + updateNewPortal(portal, destinationName); - //Don't do network stuff for bungee portals + //Update portals pointing at this one if it's not a bungee portal if (!portal.isBungee()) { - //Open any always on portal pointing at this portal - for (String originName : allPortalNetworks.get(portal.getNetwork().toLowerCase())) { - Portal origin = getByName(originName, portal.getNetwork()); - if (origin == null) continue; - if (!origin.getDestinationName().equalsIgnoreCase(portal.getName())) continue; - if (!origin.isVerified()) continue; - if (origin.isFixed()) origin.drawSign(); - if (origin.isAlwaysOn()) origin.open(true); - } + updatePortalsPointingAtNewPortal(portal); } saveAllPortals(portal.getWorld()); @@ -498,6 +471,73 @@ public class PortalHandler { return portal; } + /** + * Generates a button for a portal + * + * @param portal

The portal to generate a button for

+ * @param topLeft

The top-left block of the portal

+ * @param buttonVector

A relative vector pointing at the button

+ * @param buttonFacing

The direction the button should be facing

+ */ + private static void generatePortalButton(Portal portal, BlockLocation topLeft, RelativeBlockVector buttonVector, + BlockFace buttonFacing) { + BlockLocation button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), + buttonVector.getDistance() + 1, portal.getModX(), 1, portal.getModZ()); + Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); + buttonData.setFacing(buttonFacing); + button.getBlock().setBlockData(buttonData); + portal.setButton(button); + } + + /** + * Updates the open state of the newly created portal + * + * @param portal

The portal newly created

+ * @param destinationName

The name of the destination portal

+ */ + private static void updateNewPortal(Portal portal, String destinationName) { + portal.drawSign(); + //Open an always on portal + if (portal.isRandom() || portal.isBungee()) { + portal.open(true); + } else if (portal.isAlwaysOn()) { + Portal destinationPortal = getByName(destinationName, portal.getNetwork()); + if (destinationPortal != null) { + portal.open(true); + destinationPortal.drawSign(); + } + } else { + //Update the block type for the portal's opening to the closed block + for (BlockLocation entrance : portal.getEntrances()) { + entrance.setType(portal.getGate().getPortalClosedBlock()); + } + } + } + + /** + * Updates the sign and open state of portals pointing at the newly created portal + * + * @param portal

The newly created portal

+ */ + private static void updatePortalsPointingAtNewPortal(Portal portal) { + for (String originName : allPortalNetworks.get(portal.getNetwork().toLowerCase())) { + Portal origin = getByName(originName, portal.getNetwork()); + if (origin == null || + !origin.getDestinationName().equalsIgnoreCase(portal.getName()) || + !origin.isVerified()) { + continue; + } + //Update sign of fixed gates pointing at this gate + if (origin.isFixed()) { + origin.drawSign(); + } + //Open any always on portal pointing at this portal + if (origin.isAlwaysOn()) { + origin.open(true); + } + } + } + /** * Gets all portal options to be applied to a new portal * From d86aae87f34adc7edc2ea6c313b59dfb22dfd3eb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 25 Sep 2021 13:52:00 +0200 Subject: [PATCH 110/378] Extracts portal creation validation into its own method --- .../stargate/portal/PortalHandler.java | 93 +++++++++++-------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index e6f2f72..ade3986 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -257,7 +257,7 @@ public class PortalHandler { //Get necessary information from the gate's sign BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); BlockLocation topLeft = null; - String name = filterName(event.getLine(0)); + String portalName = filterName(event.getLine(0)); String destinationName = filterName(event.getLine(1)); String network = filterName(event.getLine(2)); String options = filterName(event.getLine(3)).toLowerCase(); @@ -396,12 +396,12 @@ public class PortalHandler { } Portal portal; - portal = new Portal(topLeft, modX, modZ, yaw, id, null, destinationName, name, false, network, + portal = new Portal(topLeft, modX, modZ, yaw, id, null, destinationName, portalName, false, network, gate, player.getUniqueId(), player.getName(), portalOptions); int cost = EconomyHandler.getCreateCost(player, gate); - // Call StargateCreateEvent + //Call StargateCreateEvent to let other plugins cancel or overwrite denial StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); Stargate.server.getPluginManager().callEvent(stargateCreateEvent); if (stargateCreateEvent.isCancelled()) { @@ -414,44 +414,11 @@ public class PortalHandler { cost = stargateCreateEvent.getCost(); - // Name & Network can be changed in the event, so do these checks here. - if (portal.getName().length() < 1 || portal.getName().length() > 11) { - Stargate.debug("createPortal", "Name length error"); - Stargate.sendErrorMessage(player, Stargate.getString("createNameLength")); + //Check if the new portal is valid + if (!checkIfNewPortalIsValid(portal, player, cost, portalName)) { return null; } - //Don't do network checks for bungee portals - if (portal.isBungee()) { - if (bungeePortals.get(portal.getName().toLowerCase()) != null) { - Stargate.debug("createPortal::Bungee", "Gate Exists"); - Stargate.sendErrorMessage(player, Stargate.getString("createExists")); - return null; - } - } else { - if (getByName(portal.getName(), portal.getNetwork()) != null) { - Stargate.debug("createPortal", "Name Error"); - Stargate.sendErrorMessage(player, Stargate.getString("createExists")); - return null; - } - - //Check if there are too many gates in this network - List netList = allPortalNetworks.get(portal.getNetwork().toLowerCase()); - if (Stargate.maxGatesEachNetwork > 0 && netList != null && netList.size() >= Stargate.maxGatesEachNetwork) { - Stargate.sendErrorMessage(player, Stargate.getString("createFull")); - return null; - } - } - - if (cost > 0) { - if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { - EconomyHelper.sendInsufficientFundsMessage(name, player, cost); - Stargate.debug("createPortal", "Insufficient Funds"); - return null; - } - EconomyHelper.sendDeductMessage(name, player, cost); - } - //No button on an always-open portal. if (!portalOptions.get(PortalOption.ALWAYS_ON)) { generatePortalButton(portal, topLeft, buttonVector, buttonFacing); @@ -471,6 +438,56 @@ public class PortalHandler { return portal; } + /** + * Checks whether the newly created, but unregistered portal is valid + * @param portal

The portal to validate

+ * @param player

The player creating the portal

+ * @param cost

The cost of creating the portal

+ * @param portalName

The name of the newly created portal

+ * @return

True if the portal is completely valid

+ */ + private static boolean checkIfNewPortalIsValid(Portal portal, Player player, int cost, String portalName) { + // Name & Network can be changed in the event, so do these checks here. + if (portal.getName().length() < 1 || portal.getName().length() > 11) { + Stargate.debug("createPortal", "Name length error"); + Stargate.sendErrorMessage(player, Stargate.getString("createNameLength")); + return false; + } + + //Don't do network checks for bungee portals + if (portal.isBungee()) { + if (bungeePortals.get(portal.getName().toLowerCase()) != null) { + Stargate.debug("createPortal::Bungee", "Gate name duplicate"); + Stargate.sendErrorMessage(player, Stargate.getString("createExists")); + return false; + } + } else { + if (getByName(portal.getName(), portal.getNetwork()) != null) { + Stargate.debug("createPortal", "Gate name duplicate"); + Stargate.sendErrorMessage(player, Stargate.getString("createExists")); + return false; + } + + //Check if there are too many gates in this network + List networkList = allPortalNetworks.get(portal.getNetwork().toLowerCase()); + if (Stargate.maxGatesEachNetwork > 0 && networkList != null && networkList.size() >= Stargate.maxGatesEachNetwork) { + Stargate.sendErrorMessage(player, Stargate.getString("createFull")); + return false; + } + } + + if (cost > 0) { + if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { + EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); + Stargate.debug("createPortal", "Insufficient Funds"); + return false; + } else { + EconomyHelper.sendDeductMessage(portalName, player, cost); + } + } + return true; + } + /** * Generates a button for a portal * From 201f7eaf15e864e74fe65cba6193aa4369eb5b57 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 6 Oct 2021 19:45:49 +0200 Subject: [PATCH 111/378] Adds a class for storing a portal's location data --- .../stargate/portal/PortalLocation.java | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalLocation.java diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java b/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java new file mode 100644 index 0000000..7f0eb0b --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java @@ -0,0 +1,159 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; +import org.bukkit.block.BlockFace; + +/** + * Keeps track of location related data for a portal + */ +public class PortalLocation { + + private BlockLocation topLeft; + private int modX; + private int modZ; + private float yaw; + private BlockLocation signLocation; + private RelativeBlockVector buttonVector; + private BlockFace buttonFacing; + + /** + * Gets the top-left block of the portal + * + * @return

The top-left block of the portal

+ */ + public BlockLocation getTopLeft() { + return topLeft; + } + + /** + * Gets the x-modifier for the portal + * + * @return

The x-modifier for the portal

+ */ + public int getModX() { + return modX; + } + + /** + * Gets the z-modifier for the portal + * + * @return

The z-modifier for the portal

+ */ + public int getModZ() { + return modZ; + } + + /** + * Gets the yaw for looking outwards from the portal + * + * @return

The portal's yaw

+ */ + public float getYaw() { + return yaw; + } + + /** + * Gets the location of the portal's sign + * @return

The location of the portal's sign

+ */ + public BlockLocation getSignLocation() { + return signLocation; + } + + /** + * The relative block vector pointing to the portal's button + * @return

The relative location of the portal's button

+ */ + public RelativeBlockVector getButtonVector() { + return buttonVector; + } + + /** + * Gets the block face determining the button's direction + * @return

The button's block face

+ */ + public BlockFace getButtonFacing() { + return buttonFacing; + } + + /** + * Sets the portal's top-left location + * + *

Assuming the portal is a square, the top-left block is the top-left block when looking at the portal at the + * side with the portal's sign.

+ * + * @param topLeft

The new top-left block of the portal's square structure

+ * @return

The portal location Object

+ */ + public PortalLocation setTopLeft(BlockLocation topLeft) { + this.topLeft = topLeft; + return this; + } + + /** + * Sets the portal's x-modifier + * + * @param modX

The portal's new x-modifier

+ * @return

The portal location Object

+ */ + public PortalLocation setModX(int modX) { + this.modX = modX; + return this; + } + + /** + * Sets the portal's z-modifier + * + * @param modZ

The portal's new z-modifier

+ * @return

The portal location Object

+ */ + public PortalLocation setModZ(int modZ) { + this.modZ = modZ; + return this; + } + + /** + * Sets the portal's yaw + * + *

The portal's yaw is the yaw a player would get when looking directly out from the portal

+ * + * @param yaw

The portal's new yaw

+ * @return

The portal location Object

+ */ + public PortalLocation setYaw(float yaw) { + this.yaw = yaw; + return this; + } + + /** + * Sets the location of the portal's sign + * @param signLocation

The new sign location

+ * @return

The portal location Object

+ */ + public PortalLocation setSignLocation(BlockLocation signLocation) { + this.signLocation = signLocation; + return this; + } + + /** + * Sets the relative location of the portal's button + * @param buttonVector

The new relative button location

+ * @return

The portal location Object

+ */ + public PortalLocation setButtonVector(RelativeBlockVector buttonVector) { + this.buttonVector = buttonVector; + return this; + } + + /** + * Sets the block face for the direction the portal button is facing + * @param buttonFacing

The new block face of the portal's button

+ * @return

The portal location Object

+ */ + public PortalLocation setButtonFacing(BlockFace buttonFacing) { + this.buttonFacing = buttonFacing; + return this; + } + +} From 76b2aab057f191ac26a16096ce83be14fa101f98 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 6 Oct 2021 19:46:34 +0200 Subject: [PATCH 112/378] Tries to improve readability of the portal creation code --- .../net/knarcraft/stargate/portal/Portal.java | 18 +- .../stargate/portal/PortalHandler.java | 254 +++++++++++------- 2 files changed, 169 insertions(+), 103 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 75824b2..fe26130 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -82,11 +82,7 @@ public class Portal { /** * Instantiates a new portal * - * @param topLeft

The top-left block of the portal. This is used to decide the positions of the rest of the portal

- * @param modX

- * @param modZ

- * @param yaw

- * @param id

The location of the portal's id block, which is the sign which activated the portal

+ * @param portalLocation

Object containing locations of all relevant blocks

* @param button

The location of the portal's open button

* @param destination

The destination defined on the sign's destination line

* @param name

The name of the portal defined on the sign's first line

@@ -97,15 +93,15 @@ public class Portal { * @param ownerName

The name of the gate's owner

* @param options

A map containing all possible portal options

*/ - Portal(BlockLocation topLeft, int modX, int modZ, float yaw, BlockLocation id, BlockLocation button, + Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, Map options) { - this.topLeft = topLeft; - this.modX = modX; - this.modZ = modZ; - this.yaw = yaw; + this.topLeft = portalLocation.getTopLeft(); + this.modX = portalLocation.getModX(); + this.modZ = portalLocation.getModZ(); + this.yaw = portalLocation.getYaw(); this.rotationAxis = yaw == 0.0F || yaw == 180.0F ? Axis.X : Axis.Z; - this.id = id; + this.id = portalLocation.getSignLocation(); this.destination = destination; this.button = button; this.verified = verified; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index ade3986..2efc3c8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -239,24 +239,21 @@ public class PortalHandler { * @return

The created portal

*/ public static Portal createPortal(SignChangeEvent event, Player player) { - BlockLocation id = new BlockLocation(event.getBlock()); - Block idParent = id.getParent(); - if (idParent == null) { - return null; - } - - if (GateHandler.getGatesByControlBlock(idParent).length == 0) { + BlockLocation signLocation = new BlockLocation(event.getBlock()); + Block idParent = signLocation.getParent(); + + //Return early if the sign is not placed on a block, or the block is not a control block + if (idParent == null || GateHandler.getGatesByControlBlock(idParent).length == 0) { return null; } + //The control block is already part of another portal if (getByBlock(idParent) != null) { Stargate.debug("createPortal", "idParent belongs to existing stargate"); return null; } //Get necessary information from the gate's sign - BlockLocation parent = new BlockLocation(player.getWorld(), idParent.getX(), idParent.getY(), idParent.getZ()); - BlockLocation topLeft = null; String portalName = filterName(event.getLine(0)); String destinationName = filterName(event.getLine(1)); String network = filterName(event.getLine(2)); @@ -266,88 +263,48 @@ public class PortalHandler { Map portalOptions = getPortalOptions(player, destinationName, options); //Get the yaw - float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), id.getLocation()); + float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), signLocation.getLocation()); //Get the direction the button should be facing BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw); //Get the x and z modifiers Vector direction = DirectionHelper.getDirectionVectorFromYaw(yaw); + //TODO: Figure out how modX and modZ really works and simplify it int modX = -direction.getBlockZ(); int modZ = direction.getBlockX(); - //Get all gates with the used type of control blocks - Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent); - Gate gate = null; - RelativeBlockVector buttonVector = null; - RelativeBlockVector signVector = null; + PortalLocation portalLocation = new PortalLocation(); + portalLocation.setButtonFacing(buttonFacing).setYaw(yaw).setModX(modX).setModZ(modZ).setSignLocation(signLocation); - //Try to find a matching gate configuration - for (Gate possibleGate : possibleGates) { - //Get gate controls - RelativeBlockVector[] vectors = possibleGate.getLayout().getControls(); - - for (RelativeBlockVector controlVector : vectors) { - //Assuming the top-left location is pointing to the gate's top-left location, check if it's a match - BlockLocation possibleTopLocation = parent.modRelative(-controlVector.getRight(), - -controlVector.getDepth(), -controlVector.getDistance(), modX, 1, modZ); - if (possibleGate.matches(possibleTopLocation, modX, modZ, true)) { - gate = possibleGate; - topLeft = possibleTopLocation; - signVector = controlVector; - break; - } - } - } - - //Find the button position if a match was found - if (gate != null) { - RelativeBlockVector[] vectors = gate.getLayout().getControls(); - for (RelativeBlockVector controlVector : vectors) { - if (!controlVector.equals(signVector)) { - buttonVector = controlVector; - break; - } - } - } - - if ((gate == null) || (buttonVector == null)) { + //Try and find a gate matching the new portal + Gate gate = findMatchingGate(portalLocation, player); + if ((gate == null) || (portalLocation.getButtonVector() == null)) { Stargate.debug("createPortal", "Could not find matching gate layout"); return null; } - //If the player is trying to create a Bungee portal without permissions, drop out here - if (options.indexOf(PortalOption.BUNGEE.getCharacterRepresentation()) != -1) { - if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); - return null; - } - } - if (portalOptions.get(PortalOption.BUNGEE)) { - if (!Stargate.enableBungee) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); - return null; - } else if (destinationName.isEmpty() || network.isEmpty()) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeEmpty")); - return null; - } + //If the portal is a bungee portal and invalid, abort here + if (!isValidBungeePortal(portalOptions, player, destinationName, network)) { + return null; } - // Debug + //Debug StringBuilder builder = new StringBuilder(); for (PortalOption option : portalOptions.keySet()) { builder.append(option.getCharacterRepresentation()).append(" = ").append(portalOptions.get(option)).append(" "); } Stargate.debug("createPortal", builder.toString()); + //Use default network if a proper alternative is not set if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > 11)) { network = Stargate.getDefaultNetwork(); } boolean deny = false; - String denyMsg = ""; + String denyMessage = ""; - // Check if the player can create portals on this network + //Check if the player can create portals on this network if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); if (PermissionHelper.canCreatePersonalGate(player)) { @@ -358,18 +315,18 @@ public class PortalHandler { } else { Stargate.debug("createPortal", "Player does not have access to network"); deny = true; - denyMsg = Stargate.getString("createNetDeny"); + denyMessage = Stargate.getString("createNetDeny"); //return null; } } - // Check if the player can create this gate layout + //Check if the player can create this gate layout String gateName = gate.getFilename(); gateName = gateName.substring(0, gateName.indexOf('.')); if (!deny && !PermissionHelper.canCreateGate(player, gateName)) { Stargate.debug("createPortal", "Player does not have access to gate layout"); deny = true; - denyMsg = Stargate.getString("createGateDeny"); + denyMessage = Stargate.getString("createGateDeny"); } //Check if the user can create portals to this world. @@ -380,48 +337,159 @@ public class PortalHandler { if (PermissionHelper.cannotAccessWorld(player, world)) { Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); deny = true; - denyMsg = Stargate.getString("createWorldDeny"); + denyMessage = Stargate.getString("createWorldDeny"); } } } - // Bleh, gotta check to make sure none of this gate belongs to another gate. Boo slow. - for (RelativeBlockVector vector : gate.getLayout().getBorder()) { - BlockLocation blockLocation = topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); - if (getByBlock(blockLocation.getBlock()) != null) { - Stargate.debug("createPortal", "Gate conflicts with existing gate"); - Stargate.sendErrorMessage(player, Stargate.getString("createConflict")); - return null; + //Check if a conflict exists + if (conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), modX, modZ, player)) { + return null; + } + + return createAndValidateNewPortal(portalLocation, destinationName, portalName, network, gate, + player, portalOptions, denyMessage, event.getLines(), deny); + } + + /** + * Checks if the new portal is a valid bungee portal + * @param portalOptions

The enabled portal options

+ * @param player

The player trying to create the new portal

+ * @param destinationName

The name of the portal's destination

+ * @param network

The name of the portal's network

+ * @return

False if the portal is an invalid bungee portal. True otherwise

+ */ + private static boolean isValidBungeePortal(Map portalOptions, Player player, + String destinationName, String network) { + if (portalOptions.get(PortalOption.BUNGEE)) { + if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { + Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); + return false; + } else if (!Stargate.enableBungee) { + Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + return false; + } else if (destinationName.isEmpty() || network.isEmpty()) { + Stargate.sendErrorMessage(player, Stargate.getString("bungeeEmpty")); + return false; + } + } + return true; + } + + /** + * Tries to find a gate matching the portal the user is trying to create + * + * @param portalLocation

The location data for the new portal

+ * @param player

The player trying to create the new portal

+ * @return

The matching gate type, or null if no such gate could be found

+ */ + private static Gate findMatchingGate(PortalLocation portalLocation, Player player) { + Block signParent = portalLocation.getSignLocation().getParent(); + BlockLocation parent = new BlockLocation(player.getWorld(), signParent.getX(), signParent.getY(), + signParent.getZ()); + + //Get all gates with the used type of control blocks + Gate[] possibleGates = GateHandler.getGatesByControlBlock(signParent); + int modX = portalLocation.getModX(); + int modZ = portalLocation.getModZ(); + Gate gate = null; + + for (Gate possibleGate : possibleGates) { + //Get gate controls + RelativeBlockVector[] vectors = possibleGate.getLayout().getControls(); + + portalLocation.setButtonVector(null); + for (RelativeBlockVector controlVector : vectors) { + //Assuming the top-left location is pointing to the gate's top-left location, check if it's a match + BlockLocation possibleTopLocation = parent.modRelative(-controlVector.getRight(), + -controlVector.getDepth(), -controlVector.getDistance(), modX, 1, modZ); + if (possibleGate.matches(possibleTopLocation, modX, modZ, true)) { + gate = possibleGate; + portalLocation.setTopLeft(possibleTopLocation); + } else { + portalLocation.setButtonVector(controlVector); + } } } - Portal portal; - portal = new Portal(topLeft, modX, modZ, yaw, id, null, destinationName, portalName, false, network, - gate, player.getUniqueId(), player.getName(), portalOptions); + return gate; + } - int cost = EconomyHandler.getCreateCost(player, gate); + /** + * Checks whether the new portal conflicts with an existing portal + * + * @param gate

The gate type of the new portal

+ * @param topLeft

The top-left block of the new portal

+ * @param modX

The x-modifier for the new portal

+ * @param modZ

The new z-modifier for the new portal

+ * @param player

The player creating the new portal

+ * @return

True if a conflict was found. False otherwise

+ */ + private static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, int modX, int modZ, + Player player) { + //TODO: Make a quicker check. Could just check for control block conflicts if all code is changed to account for + // getting several hits at a single location when checking for the existence of a portal. May make + // everything slower overall? Would make for cooler gates though. + for (RelativeBlockVector borderVector : gate.getLayout().getBorder()) { + BlockLocation borderBlockLocation = topLeft.modRelative(borderVector.getRight(), borderVector.getDepth(), + borderVector.getDistance(), modX, 1, modZ); + if (getByBlock(borderBlockLocation.getBlock()) != null) { + Stargate.debug("createPortal", "Gate conflicts with existing gate"); + Stargate.sendErrorMessage(player, Stargate.getString("createConflict")); + return true; + } + } + return false; + } + + /** + * Creates and validates a new portal + * + * @param destinationName

The name of the portal's destination

+ * @param portalName

The name of the new portal

+ * @param network

The name of the new portal's network

+ * @param gate

The gate type used in the physical construction of the new portal

+ * @param player

The player creating the new portal

+ * @param portalOptions

A map of enabled and disabled portal options

+ * @param denyMessage

The deny message to display if the portal creation was denied

+ * @param lines

All the lines of the sign which initiated the portal creation

+ * @param deny

Whether to deny the creation of the new portal

+ * @return

A new portal, or null if the input cases the creation to be denied

+ */ + private static Portal createAndValidateNewPortal(PortalLocation portalLocation, String destinationName, + String portalName, String network, Gate gate, Player player, + Map portalOptions, String denyMessage, + String[] lines, boolean deny) { + Portal portal = new Portal(portalLocation, null, destinationName, portalName, + false, network, gate, player.getUniqueId(), player.getName(), portalOptions); + + int createCost = EconomyHandler.getCreateCost(player, gate); //Call StargateCreateEvent to let other plugins cancel or overwrite denial - StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, event.getLines(), deny, denyMsg, cost); + StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, lines, deny, + denyMessage, createCost); Stargate.server.getPluginManager().callEvent(stargateCreateEvent); if (stargateCreateEvent.isCancelled()) { return null; } + + //Tell the user why it was denied from creating the portal if (stargateCreateEvent.getDeny()) { Stargate.sendErrorMessage(player, stargateCreateEvent.getDenyReason()); return null; } - cost = stargateCreateEvent.getCost(); + createCost = stargateCreateEvent.getCost(); //Check if the new portal is valid - if (!checkIfNewPortalIsValid(portal, player, cost, portalName)) { + if (!checkIfNewPortalIsValid(portal, player, createCost, portalName)) { return null; } - //No button on an always-open portal. + //Add button if the portal is not always on if (!portalOptions.get(PortalOption.ALWAYS_ON)) { - generatePortalButton(portal, topLeft, buttonVector, buttonFacing); + generatePortalButton(portal, portalLocation.getTopLeft(), portalLocation.getButtonVector(), + portalLocation.getButtonFacing()); } //Register the new portal @@ -440,9 +508,10 @@ public class PortalHandler { /** * Checks whether the newly created, but unregistered portal is valid - * @param portal

The portal to validate

- * @param player

The player creating the portal

- * @param cost

The cost of creating the portal

+ * + * @param portal

The portal to validate

+ * @param player

The player creating the portal

+ * @param cost

The cost of creating the portal

* @param portalName

The name of the newly created portal

* @return

True if the portal is completely valid

*/ @@ -884,12 +953,13 @@ public class PortalHandler { private static void loadPortal(String[] portalData, World world, int lineIndex) { //Load min. required portal data String name = portalData[0]; - BlockLocation sign = new BlockLocation(world, portalData[1]); + PortalLocation portalLocation = new PortalLocation(); + portalLocation.setSignLocation(new BlockLocation(world, portalData[1])); BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; - int modX = Integer.parseInt(portalData[3]); - int modZ = Integer.parseInt(portalData[4]); - float yaw = Float.parseFloat(portalData[5]); - BlockLocation topLeft = new BlockLocation(world, portalData[6]); + portalLocation.setModX(Integer.parseInt(portalData[3])); + portalLocation.setModZ(Integer.parseInt(portalData[4])); + portalLocation.setYaw(Float.parseFloat(portalData[5])); + portalLocation.setTopLeft(new BlockLocation(world, portalData[6])); Gate gate = GateHandler.getGateByName(portalData[7]); if (gate == null) { Stargate.logger.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + @@ -923,7 +993,7 @@ public class PortalHandler { } //Creates the new portal - Portal portal = new Portal(topLeft, modX, modZ, yaw, sign, button, destination, name, false, + Portal portal = new Portal(portalLocation, button, destination, name, false, network, gate, ownerUUID, ownerName, getPortalOptions(portalData)); registerPortal(portal); From 60c543e52a49ca80ca57ce96d11f802937e6ee4b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 01:25:25 +0200 Subject: [PATCH 113/378] Adds a new class for keeping track of portal options --- .../stargate/portal/PortalOptions.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalOptions.java diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java new file mode 100644 index 0000000..d2335e8 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java @@ -0,0 +1,141 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; + +import java.util.Map; + +/** + * Keeps track of all options for a given portal + */ +public class PortalOptions { + + private final Map options; + private boolean isFixed; + + /** + * Instantiates a new portal options object + * + * @param options

All options to keep track of

+ * @param hasDestination

Whether the portal has a fixed destination

+ */ + public PortalOptions(Map options, boolean hasDestination) { + this.options = options; + + isFixed = hasDestination || this.isRandom() || this.isBungee(); + + if (this.isAlwaysOn() && !isFixed) { + this.options.put(PortalOption.ALWAYS_ON, false); + Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); + } + + if (this.isRandom() && !this.isAlwaysOn()) { + this.options.put(PortalOption.ALWAYS_ON, true); + Stargate.debug("Portal", "Gate marked as random, set to always-on"); + } + } + + /** + * Gets whether this portal is fixed + * + *

A fixed portal has only one destination which never changes. A fixed portal has a fixed destination, is a + * random portal or is a bungee portal. A fixed portal is always open.

+ * + * @return

Whether this gate is fixed

+ */ + public boolean isFixed() { + return this.isFixed; + } + + /** + * Sets whether this portal is fixed + * + * @param fixed

Whether this gate should be fixed

+ */ + public void setFixed(boolean fixed) { + this.isFixed = fixed; + } + + /** + * Gets whether this portal is always on + * + * @return

Whether this portal is always on

+ */ + public boolean isAlwaysOn() { + return this.options.get(PortalOption.ALWAYS_ON); + } + + /** + * Gets whether this portal is hidden + * + * @return

Whether this portal is hidden

+ */ + public boolean isHidden() { + return this.options.get(PortalOption.HIDDEN); + } + + /** + * Gets whether this portal is private + * + * @return

Whether this portal is private

+ */ + public boolean isPrivate() { + return this.options.get(PortalOption.PRIVATE); + } + + /** + * Gets whether this portal is free + * + * @return

Whether this portal is free

+ */ + public boolean isFree() { + return this.options.get(PortalOption.FREE); + } + + /** + * Gets whether this portal is backwards + * + *

A backwards portal is one where players exit through the back.

+ * + * @return

Whether this portal is backwards

+ */ + public boolean isBackwards() { + return this.options.get(PortalOption.BACKWARDS); + } + + /** + * Gets whether this portal is shown on the network even if it's always on + * + * @return

Whether portal gate is shown

+ */ + public boolean isShown() { + return this.options.get(PortalOption.SHOW); + } + + /** + * Gets whether this portal shows no network + * + * @return

Whether this portal shows no network/p> + */ + public boolean isNoNetwork() { + return this.options.get(PortalOption.NO_NETWORK); + } + + /** + * Gets whether this portal goes to a random location on the network + * + * @return

Whether this portal goes to a random location

+ */ + public boolean isRandom() { + return this.options.get(PortalOption.RANDOM); + } + + /** + * Gets whether this portal is a bungee portal + * + * @return

Whether this portal is a bungee portal

+ */ + public boolean isBungee() { + return this.options.get(PortalOption.BUNGEE); + } + +} From e7fc1daafe4e163053f06f1a485128c47d4e51de Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 01:26:12 +0200 Subject: [PATCH 114/378] Moves functionality to the PortalOptions and PortalLocation classes --- .../listener/PlayerEventListener.java | 4 +- .../listener/VehicleEventListener.java | 4 +- .../net/knarcraft/stargate/portal/Portal.java | 234 +++++------------- .../stargate/portal/PortalHandler.java | 65 ++--- .../stargate/portal/PortalLocation.java | 27 ++ .../stargate/thread/StarGateThread.java | 2 +- .../stargate/utility/EconomyHandler.java | 4 +- .../stargate/utility/PermissionHelper.java | 18 +- .../stargate/utility/SignHelper.java | 10 +- 9 files changed, 142 insertions(+), 226 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 8416b9f..9dcb908 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -155,7 +155,7 @@ public class PlayerEventListener implements Listener { } //Decide if the user should be teleported to another bungee server - if (entrancePortal.isBungee()) { + if (entrancePortal.getOptions().isBungee()) { if (bungeeTeleport(player, entrancePortal, event)) { Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); } @@ -368,7 +368,7 @@ public class PlayerEventListener implements Listener { } //No destination - if (!entrancePortal.isBungee() && destination == null) { + if (!entrancePortal.getOptions().isBungee() && destination == null) { return false; } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index ec87539..4a69c13 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -44,7 +44,7 @@ public class VehicleEventListener implements Listener { } //Return if the portal cannot be teleported through - if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) { + if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.getOptions().isBungee()) { return; } @@ -69,7 +69,7 @@ public class VehicleEventListener implements Listener { Stargate.logger.warning(Stargate.getString("prefox") + "Unable to find portal destination"); return; } - Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getId()); + Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); destinationPortal.teleport(vehicle, entrancePortal); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index fe26130..bb47e36 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -46,17 +46,10 @@ import java.util.logging.Level; public class Portal { // Gate location block info - private final BlockLocation topLeft; - private final int modX; - private final int modZ; - private final float yaw; - //The rotation axis is the axis along which the gate is placed. It's the cross axis of the button's axis - private final Axis rotationAxis; + private final PortalLocation location; // Block references - private final BlockLocation id; private final Gate gate; - private final World world; private BlockLocation button; private BlockLocation[] frame; private BlockLocation[] entrances; @@ -69,8 +62,7 @@ public class Portal { private final String ownerName; private UUID ownerUUID; private boolean verified; - private boolean fixed; - private final Map options; + private final PortalOptions options; // In-use information private Player player; @@ -83,25 +75,20 @@ public class Portal { * Instantiates a new portal * * @param portalLocation

Object containing locations of all relevant blocks

- * @param button

The location of the portal's open button

- * @param destination

The destination defined on the sign's destination line

- * @param name

The name of the portal defined on the sign's first line

- * @param verified

Whether the portal's gate has been verified to match its template

- * @param network

The network the portal belongs to, defined on the sign's network line

- * @param gate

The gate template this portal uses

- * @param ownerUUID

The UUID of the gate's owner

- * @param ownerName

The name of the gate's owner

- * @param options

A map containing all possible portal options

+ * @param button

The location of the portal's open button

+ * @param destination

The destination defined on the sign's destination line

+ * @param name

The name of the portal defined on the sign's first line

+ * @param verified

Whether the portal's gate has been verified to match its template

+ * @param network

The network the portal belongs to, defined on the sign's network line

+ * @param gate

The gate template this portal uses

+ * @param ownerUUID

The UUID of the gate's owner

+ * @param ownerName

The name of the gate's owner

+ * @param options

A map containing all possible portal options

*/ Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, boolean verified, String network, Gate gate, UUID ownerUUID, String ownerName, Map options) { - this.topLeft = portalLocation.getTopLeft(); - this.modX = portalLocation.getModX(); - this.modZ = portalLocation.getModZ(); - this.yaw = portalLocation.getYaw(); - this.rotationAxis = yaw == 0.0F || yaw == 180.0F ? Axis.X : Axis.Z; - this.id = portalLocation.getSignLocation(); + this.location = portalLocation; this.destination = destination; this.button = button; this.verified = verified; @@ -110,124 +97,29 @@ public class Portal { this.gate = gate; this.ownerUUID = ownerUUID; this.ownerName = ownerName; - this.options = options; - this.world = topLeft.getWorld(); - this.fixed = destination.length() > 0 || this.isRandom() || this.isBungee(); - - if (this.isAlwaysOn() && !this.isFixed()) { - this.options.put(PortalOption.ALWAYS_ON, false); - Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); - } - - if (this.isRandom() && !this.isAlwaysOn()) { - this.options.put(PortalOption.ALWAYS_ON, true); - Stargate.debug("Portal", "Gate marked as random, set to always-on"); - } + this.options = new PortalOptions(options, destination.length() > 0); if (verified) { this.drawSign(); } } + /** + * Gets the portal options for this portal + * + * @return

This portal's portal options

+ */ + public PortalOptions getOptions() { + return this.options; + } + /** * Gets whether this portal is currently open * * @return

Whether this portal is open

*/ public boolean isOpen() { - return isOpen || isAlwaysOn(); - } - - /** - * Gets whether this portal is always on - * - * @return

Whether this portal is always on

- */ - public boolean isAlwaysOn() { - return this.options.get(PortalOption.ALWAYS_ON); - } - - /** - * Gets whether this portal is hidden - * - * @return

Whether this portal is hidden

- */ - public boolean isHidden() { - return this.options.get(PortalOption.HIDDEN); - } - - /** - * Gets whether this portal is private - * - * @return

Whether this portal is private

- */ - public boolean isPrivate() { - return this.options.get(PortalOption.PRIVATE); - } - - /** - * Gets whether this portal is free - * - * @return

Whether this portal is free

- */ - public boolean isFree() { - return this.options.get(PortalOption.FREE); - } - - /** - * Gets whether this portal is backwards - * - *

A backwards portal is one where players exit through the back.

- * - * @return

Whether this portal is backwards

- */ - public boolean isBackwards() { - return this.options.get(PortalOption.BACKWARDS); - } - - /** - * Gets whether this portal is shown on the network even if it's always on - * - * @return

Whether portal gate is shown

- */ - public boolean isShown() { - return this.options.get(PortalOption.SHOW); - } - - /** - * Gets whether this portal shows no network - * - * @return

Whether this portal shows no network/p> - */ - public boolean isNoNetwork() { - return this.options.get(PortalOption.NO_NETWORK); - } - - /** - * Gets whether this portal goes to a random location on the network - * - * @return

Whether this portal goes to a random location

- */ - public boolean isRandom() { - return this.options.get(PortalOption.RANDOM); - } - - /** - * Gets whether this portal is a bungee portal - * - * @return

Whether this portal is a bungee portal

- */ - public boolean isBungee() { - return this.options.get(PortalOption.BUNGEE); - } - - /** - * Gets the rotation of the portal in degrees - * - * @return

The rotation of the portal

- */ - public float getRotation() { - return yaw; + return isOpen || options.isAlwaysOn(); } /** @@ -301,7 +193,7 @@ public class Portal { * @return

The destination portal the player should teleport to

*/ public Portal getDestination(Player player) { - if (isRandom()) { + if (options.isRandom()) { destinations = PortalHandler.getDestinations(this, player, getNetwork()); if (destinations.size() == 0) { return null; @@ -426,22 +318,13 @@ public class Portal { return frame; } - /** - * Gets the location of this portal's sign - * - * @return

The location of this portal's sign

- */ - public BlockLocation getSign() { - return id; - } - /** * Gets the world this portal belongs to * * @return

The world this portal belongs to

*/ public World getWorld() { - return world; + return location.getWorld(); } /** @@ -488,7 +371,7 @@ public class Portal { //Change the opening blocks to the correct type Material openType = gate.getPortalOpenBlock(); - Axis axis = (openType.createBlockData() instanceof Orientable) ? rotationAxis : null; + Axis axis = (openType.createBlockData() instanceof Orientable) ? location.getRotationAxis() : null; for (BlockLocation inside : getEntrances()) { Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, openType, axis)); } @@ -510,12 +393,12 @@ public class Portal { Stargate.activePortalsQueue.remove(this); //Open remote portal - if (!isAlwaysOn()) { + if (!options.isAlwaysOn()) { player = openFor; Portal destination = getDestination(); // Only open destination if it's not-fixed or points at this portal - if (!isRandom() && destination != null && (!destination.isFixed() || + if (!options.isRandom() && destination != null && (!destination.isFixed() || destination.getDestinationName().equalsIgnoreCase(getName())) && !destination.isOpen()) { destination.open(openFor, false); destination.setDestination(this); @@ -537,7 +420,7 @@ public class Portal { if (event.isCancelled()) return; force = event.getForce(); - if (isAlwaysOn() && !force) return; // Only close always-open if forced + if (options.isAlwaysOn() && !force) return; // Only close always-open if forced // Close this gate, then the dest gate. Material closedType = gate.getPortalClosedBlock(); @@ -560,7 +443,7 @@ public class Portal { Stargate.activePortalsQueue.remove(this); //Close remote portal - if (!isAlwaysOn()) { + if (!options.isAlwaysOn()) { Portal end = getDestination(); if (end != null && end.isOpen()) { @@ -581,7 +464,7 @@ public class Portal { if (!isOpen) { return false; } - if (isAlwaysOn() || this.player == null) { + if (options.isAlwaysOn() || this.player == null) { return true; } return player != null && player.getName().equalsIgnoreCase(this.player.getName()); @@ -595,7 +478,7 @@ public class Portal { * @return

True if this portal points to a fixed exit portal

*/ public boolean isFixed() { - return fixed; + return options.isFixed(); } /** @@ -606,7 +489,7 @@ public class Portal { * @param fixed

True if this portal points to a fixed exit portal

*/ public void setFixed(boolean fixed) { - this.fixed = fixed; + options.setFixed(fixed); } /** @@ -655,10 +538,10 @@ public class Portal { */ private void adjustRotation(Location exit, Portal origin) { int adjust = 0; - if (isBackwards() != origin.isBackwards()) { + if (options.isBackwards() != origin.options.isBackwards()) { adjust = 180; } - float newYaw = (this.getRotation() + adjust) % 360; + float newYaw = (this.getYaw() + adjust) % 360; Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); exit.setYaw(newYaw); } @@ -679,7 +562,7 @@ public class Portal { vehicle.setVelocity(new Vector()); //Get new velocity - Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(this.getRotation()); + Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(this.getYaw()); Vector newVelocity = newVelocityDirection.multiply(velocity); adjustRotation(exit, origin); @@ -769,9 +652,9 @@ public class Portal { RelativeBlockVector relativeExit = gate.getLayout().getExit(); if (relativeExit != null) { BlockLocation exit = getBlockAt(relativeExit); - int back = (isBackwards()) ? -1 : 1; + int back = (options.isBackwards()) ? -1 : 1; exitLocation = exit.modRelativeLoc(0D, 0D, 1, traveller.getYaw(), - traveller.getPitch(), modX * back, 1, modZ * back); + traveller.getPitch(), getModX() * back, 1, getModZ() * back); if (entity != null) { double entitySize = EntityHelper.getEntityMaxSize(entity); @@ -810,20 +693,22 @@ public class Portal { if (openingWidth > 1) { newOffset -= 0.5; } - exitLocation = DirectionHelper.adjustLocation(exitLocation, newOffset, 0, 0, modX, modZ); + exitLocation = DirectionHelper.adjustLocation(exitLocation, newOffset, 0, 0, getModX(), getModZ()); //Move large entities further from the portal, especially if this portal will teleport them at once double entitySize = EntityHelper.getEntityMaxSize(entity); int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); if (entitySize > 1) { - if (isAlwaysOn()) { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entityBoxSize / 2D), modX, modZ); + if (options.isAlwaysOn()) { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entityBoxSize / 2D), + getModX(), getModZ()); } else { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D) - 1, modX, modZ); + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, + (entitySize / 2D) - 1, getModX(), getModZ()); } } if (entity instanceof AbstractHorse) { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, 1, modX, modZ); + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, 1, getModX(), getModZ()); } return exitLocation; @@ -886,8 +771,9 @@ public class Portal { //Get the chunk in front of the gate corner Location cornerLocation = getBlockAt(vector).getLocation(); - int blockOffset = this.isBackwards() ? -5 : 5; - Location fiveBlocksForward = DirectionHelper.adjustLocation(cornerLocation, 0, 0, blockOffset, modX, modZ); + int blockOffset = options.isBackwards() ? -5 : 5; + Location fiveBlocksForward = DirectionHelper.adjustLocation(cornerLocation, 0, 0, blockOffset, + getModX(), getModZ()); Chunk forwardChunk = fiveBlocksForward.getChunk(); //Load the chunks @@ -914,8 +800,8 @@ public class Portal { * * @return

The identity location of the portal

*/ - public BlockLocation getId() { - return this.id; + public BlockLocation getSignLocation() { + return this.location.getSignLocation(); } /** @@ -924,7 +810,7 @@ public class Portal { * @return

The x modifier used by this portal

*/ public int getModX() { - return this.modX; + return this.location.getModX(); } /** @@ -933,7 +819,7 @@ public class Portal { * @return

The z modifier used by this portal

*/ public int getModZ() { - return this.modZ; + return this.location.getModZ(); } /** @@ -942,7 +828,7 @@ public class Portal { * @return

The rotation of this portal

*/ public float getYaw() { - return this.yaw; + return this.location.getYaw(); } /** @@ -951,7 +837,7 @@ public class Portal { * @return

The location of the top-left portal block

*/ public BlockLocation getTopLeft() { - return this.topLeft; + return this.location.getTopLeft(); } /** @@ -991,7 +877,7 @@ public class Portal { if (!Stargate.verifyPortals) { return true; } - return gate.matches(topLeft, modX, modZ); + return gate.matches(getTopLeft(), getModX(), getModZ()); } /** @@ -1122,10 +1008,11 @@ public class Portal { * Draws the sign on this portal */ public final void drawSign() { - BlockState state = id.getBlock().getState(); + BlockState state = getSignLocation().getBlock().getState(); if (!(state instanceof Sign)) { Stargate.logger.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); - Stargate.debug("Portal::drawSign", "Block: " + id.getBlock().getType() + " @ " + id.getBlock().getLocation()); + Stargate.debug("Portal::drawSign", "Block: " + getSignLocation().getBlock().getType() + " @ " + + getSignLocation().getBlock().getLocation()); return; } @@ -1140,7 +1027,7 @@ public class Portal { * @return

The block at the given relative position

*/ public BlockLocation getBlockAt(RelativeBlockVector vector) { - return DirectionHelper.getBlockAt(topLeft, vector, modX, modZ); + return DirectionHelper.getBlockAt(getTopLeft(), vector, getModX(), getModZ()); } /** @@ -1174,7 +1061,8 @@ public class Portal { @Override public String toString() { - return String.format("Portal [id=%s, network=%s name=%s, type=%s]", id, network, name, gate.getFilename()); + return String.format("Portal [id=%s, network=%s name=%s, type=%s]", getSignLocation(), network, name, + gate.getFilename()); } @Override diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 2efc3c8..067f12b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -73,11 +73,11 @@ public class PortalHandler { continue; } //Check if destination is a random portal - if (portal.isRandom()) { + if (portal.getOptions().isRandom()) { continue; } //Check if destination is always open (Don't show if so) - if (portal.isAlwaysOn() && !portal.isShown()) { + if (portal.getOptions().isAlwaysOn() && !portal.getOptions().isShown()) { continue; } //Check if destination is this portal @@ -125,8 +125,8 @@ public class PortalHandler { } //Remove registered info about the lookup controls and blocks - lookupBlocks.remove(portal.getId()); - lookupControls.remove(portal.getId()); + lookupBlocks.remove(portal.getSignLocation()); + lookupControls.remove(portal.getSignLocation()); if (portal.getButton() != null) { lookupBlocks.remove(portal.getButton()); lookupControls.remove(portal.getButton()); @@ -142,7 +142,7 @@ public class PortalHandler { allPortals.remove(portal); } - if (portal.isBungee()) { + if (portal.getOptions().isBungee()) { //Remove the bungee listing bungeePortals.remove(portalName); } else { @@ -161,15 +161,15 @@ public class PortalHandler { origin.drawSign(); } //Close portal without destination - if (origin.isAlwaysOn()) { + if (origin.getOptions().isAlwaysOn()) { origin.close(true); } } } //Clear sign data - if (portal.getId().getBlock().getBlockData() instanceof WallSign) { - Sign sign = (Sign) portal.getId().getBlock().getState(); + if (portal.getSignLocation().getBlock().getBlockData() instanceof WallSign) { + Sign sign = (Sign) portal.getSignLocation().getBlock().getState(); sign.setLine(0, portal.getName()); sign.setLine(1, ""); sign.setLine(2, ""); @@ -186,13 +186,13 @@ public class PortalHandler { * @param portal

The portal to register

*/ private static void registerPortal(Portal portal) { - portal.setFixed(portal.getDestinationName().length() > 0 || portal.isRandom() || portal.isBungee()); + portal.setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || portal.getOptions().isBungee()); String portalName = portal.getName().toLowerCase(); String networkName = portal.getNetwork().toLowerCase(); //Bungee portals are stored in their own list - if (portal.isBungee()) { + if (portal.getOptions().isBungee()) { bungeePortals.put(portalName, portal); } else { //Check if network exists in the lookup list. If not, register the new network @@ -216,8 +216,8 @@ public class PortalHandler { lookupBlocks.put(block, portal); } //Register the sign and button to the lookup lists - lookupBlocks.put(portal.getId(), portal); - lookupControls.put(portal.getId(), portal); + lookupBlocks.put(portal.getSignLocation(), portal); + lookupControls.put(portal.getSignLocation(), portal); if (portal.getButton() != null) { lookupBlocks.put(portal.getButton(), portal); lookupControls.put(portal.getButton(), portal); @@ -353,10 +353,11 @@ public class PortalHandler { /** * Checks if the new portal is a valid bungee portal - * @param portalOptions

The enabled portal options

- * @param player

The player trying to create the new portal

+ * + * @param portalOptions

The enabled portal options

+ * @param player

The player trying to create the new portal

* @param destinationName

The name of the portal's destination

- * @param network

The name of the portal's network

+ * @param network

The name of the portal's network

* @return

False if the portal is an invalid bungee portal. True otherwise

*/ private static boolean isValidBungeePortal(Map portalOptions, Player player, @@ -497,7 +498,7 @@ public class PortalHandler { updateNewPortal(portal, destinationName); //Update portals pointing at this one if it's not a bungee portal - if (!portal.isBungee()) { + if (!portal.getOptions().isBungee()) { updatePortalsPointingAtNewPortal(portal); } @@ -524,7 +525,7 @@ public class PortalHandler { } //Don't do network checks for bungee portals - if (portal.isBungee()) { + if (portal.getOptions().isBungee()) { if (bungeePortals.get(portal.getName().toLowerCase()) != null) { Stargate.debug("createPortal::Bungee", "Gate name duplicate"); Stargate.sendErrorMessage(player, Stargate.getString("createExists")); @@ -584,9 +585,9 @@ public class PortalHandler { private static void updateNewPortal(Portal portal, String destinationName) { portal.drawSign(); //Open an always on portal - if (portal.isRandom() || portal.isBungee()) { + if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { portal.open(true); - } else if (portal.isAlwaysOn()) { + } else if (portal.getOptions().isAlwaysOn()) { Portal destinationPortal = getByName(destinationName, portal.getNetwork()); if (destinationPortal != null) { portal.open(true); @@ -618,7 +619,7 @@ public class PortalHandler { origin.drawSign(); } //Open any always on portal pointing at this portal - if (origin.isAlwaysOn()) { + if (origin.getOptions().isAlwaysOn()) { origin.open(true); } } @@ -792,7 +793,7 @@ public class PortalHandler { BlockLocation button = portal.getButton(); builder.append(portal.getName()).append(':'); - builder.append(portal.getId().toString()).append(':'); + builder.append(portal.getSignLocation().toString()).append(':'); builder.append((button != null) ? button.toString() : "").append(':'); builder.append(portal.getModX()).append(':'); builder.append(portal.getModZ()).append(':'); @@ -808,16 +809,16 @@ public class PortalHandler { builder.append(portal.getOwnerName()); } builder.append(':'); - builder.append(portal.isHidden()).append(':'); - builder.append(portal.isAlwaysOn()).append(':'); - builder.append(portal.isPrivate()).append(':'); + builder.append(portal.getOptions().isHidden()).append(':'); + builder.append(portal.getOptions().isAlwaysOn()).append(':'); + builder.append(portal.getOptions().isPrivate()).append(':'); builder.append(portal.getWorld().getName()).append(':'); - builder.append(portal.isFree()).append(':'); - builder.append(portal.isBackwards()).append(':'); - builder.append(portal.isShown()).append(':'); - builder.append(portal.isNoNetwork()).append(':'); - builder.append(portal.isRandom()).append(':'); - builder.append(portal.isBungee()); + builder.append(portal.getOptions().isFree()).append(':'); + builder.append(portal.getOptions().isBackwards()).append(':'); + builder.append(portal.getOptions().isShown()).append(':'); + builder.append(portal.getOptions().isNoNetwork()).append(':'); + builder.append(portal.getOptions().isRandom()).append(':'); + builder.append(portal.getOptions().isBungee()); bw.append(builder.toString()); bw.newLine(); @@ -1038,8 +1039,8 @@ public class PortalHandler { portalCount++; //Open the gate if it's set as always open or if it's a bungee gate - if (portal.isFixed() && (Stargate.enableBungee && portal.isBungee() || portal.getDestination() != null && - portal.isAlwaysOn())) { + if (portal.isFixed() && (Stargate.enableBungee && portal.getOptions().isBungee() || + portal.getDestination() != null && portal.getOptions().isAlwaysOn())) { portal.open(true); openCount++; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java b/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java index 7f0eb0b..8c0da51 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java @@ -2,6 +2,8 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; +import org.bukkit.Axis; +import org.bukkit.World; import org.bukkit.block.BlockFace; /** @@ -55,6 +57,7 @@ public class PortalLocation { /** * Gets the location of the portal's sign + * * @return

The location of the portal's sign

*/ public BlockLocation getSignLocation() { @@ -63,6 +66,7 @@ public class PortalLocation { /** * The relative block vector pointing to the portal's button + * * @return

The relative location of the portal's button

*/ public RelativeBlockVector getButtonVector() { @@ -71,12 +75,32 @@ public class PortalLocation { /** * Gets the block face determining the button's direction + * * @return

The button's block face

*/ public BlockFace getButtonFacing() { return buttonFacing; } + /** + * Gets the rotation axis, which is the axis along which the gate is placed + *

The portal's rotation axis is the cross axis of the button's axis

+ * + * @return

The portal's rotation axis

+ */ + public Axis getRotationAxis() { + return getYaw() == 0.0F || getYaw() == 180.0F ? Axis.X : Axis.Z; + } + + /** + * Gets the world this portal resides in + * + * @return

The world this portal resides in

+ */ + public World getWorld() { + return topLeft.getWorld(); + } + /** * Sets the portal's top-left location * @@ -128,6 +152,7 @@ public class PortalLocation { /** * Sets the location of the portal's sign + * * @param signLocation

The new sign location

* @return

The portal location Object

*/ @@ -138,6 +163,7 @@ public class PortalLocation { /** * Sets the relative location of the portal's button + * * @param buttonVector

The new relative button location

* @return

The portal location Object

*/ @@ -148,6 +174,7 @@ public class PortalLocation { /** * Sets the block face for the direction the portal button is facing + * * @param buttonFacing

The new block face of the portal's button

* @return

The portal location Object

*/ diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 4b202df..521b388 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -17,7 +17,7 @@ public class StarGateThread implements Runnable { for (Iterator iterator = Stargate.openPortalsQueue.iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); // Skip always open and non-open gates - if (portal.isAlwaysOn() || !portal.isOpen()) { + if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) { continue; } if (time > portal.getOpenTime() + Stargate.getOpenTime()) { diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 616e347..33c4b1e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -190,11 +190,11 @@ public final class EconomyHandler { */ public static int getUseCost(Player player, Portal source, Portal destination) { //No payment required - if (!EconomyHandler.useEconomy() || source.isFree()) { + if (!EconomyHandler.useEconomy() || source.getOptions().isFree()) { return 0; } //Not charging for free destinations - if (destination != null && !EconomyHandler.chargeFreeDestination && destination.isFree()) { + if (destination != null && !EconomyHandler.chargeFreeDestination && destination.getOptions().isFree()) { return 0; } //Cost is 0 if the player owns this gate and funds go to the owner diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 9c6eacb..bfe8444 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -25,12 +25,12 @@ public final class PermissionHelper { Portal destination = portal.getDestination(); //Always-open gate -- Do nothing - if (portal.isAlwaysOn()) { + if (portal.getOptions().isAlwaysOn()) { return; } //Random gate -- Do nothing - if (portal.isRandom()) { + if (portal.getOptions().isRandom()) { return; } @@ -56,13 +56,13 @@ public final class PermissionHelper { } //Check if the player can use the private gate - if (portal.isPrivate() && !PermissionHelper.canPrivate(player, portal)) { + if (portal.getOptions().isPrivate() && !PermissionHelper.canPrivate(player, portal)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } //Destination blocked - if ((destination.isOpen()) && (!destination.isAlwaysOn())) { + if ((destination.isOpen()) && (!destination.getOptions().isAlwaysOn())) { Stargate.sendErrorMessage(player, Stargate.getString("blockMsg")); return; } @@ -98,13 +98,13 @@ public final class PermissionHelper { public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { boolean deny = false; // Check if player has access to this server for Bungee gates - if (entrancePortal.isBungee() && !PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { + if (entrancePortal.getOptions().isBungee() && !PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (!entrancePortal.isBungee() && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { + } else if (!entrancePortal.getOptions().isBungee() && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } @@ -219,7 +219,7 @@ public final class PermissionHelper { */ public static boolean isFree(Player player, Portal src, Portal dest) { // This gate is free - if (src.isFree()) { + if (src.getOptions().isFree()) { return true; } // Player gets free use @@ -227,7 +227,7 @@ public final class PermissionHelper { return true; } // Don't charge for free destination gates - return dest != null && !EconomyHandler.chargeFreeDestination && dest.isFree(); + return dest != null && !EconomyHandler.chargeFreeDestination && dest.getOptions().isFree(); } /** @@ -241,7 +241,7 @@ public final class PermissionHelper { */ public static boolean canSeePortal(Player player, Portal portal) { // The gate is not hidden - if (!portal.isHidden()) { + if (!portal.getOptions().isHidden()) { return true; } // The player is an admin with the ability to see hidden gates diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index 891c209..d84fa21 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -25,7 +25,7 @@ public final class SignHelper { //Default sign text drawInactiveSign(sign, portal); } else { - if (portal.isBungee()) { + if (portal.getOptions().isBungee()) { //Bungee sign drawBungeeSign(sign, portal); } else if (portal.isFixed()) { @@ -126,7 +126,7 @@ public final class SignHelper { private static void drawInactiveSign(Sign sign, Portal portal) { Stargate.setLine(sign, 1, Stargate.getString("signRightClick")); Stargate.setLine(sign, 2, Stargate.getString("signToUse")); - if (!portal.isNoNetwork()) { + if (!portal.getOptions().isNoNetwork()) { Stargate.setLine(sign, 3, "(" + portal.getNetwork() + ")"); } else { Stargate.setLine(sign, 3, ""); @@ -139,18 +139,18 @@ public final class SignHelper { * @param sign

The sign to draw on

*/ private static void drawFixedSign(Sign sign, Portal portal) { - if (portal.isRandom()) { + if (portal.getOptions().isRandom()) { Stargate.setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); } else { Stargate.setLine(sign, 1, ">" + portal.getDestinationName() + "<"); } - if (portal.isNoNetwork()) { + if (portal.getOptions().isNoNetwork()) { Stargate.setLine(sign, 2, ""); } else { Stargate.setLine(sign, 2, "(" + portal.getNetwork() + ")"); } Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); - if (destination == null && !portal.isRandom()) { + if (destination == null && !portal.getOptions().isRandom()) { Stargate.setLine(sign, 3, Stargate.getString("signDisconnected")); } else { Stargate.setLine(sign, 3, ""); From 6d5c4802bc5809676e5e02f04b3db05a3450cb73 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 15:28:12 +0200 Subject: [PATCH 115/378] Creates some new methods to get a location from a relative location which I can actually understand --- .../stargate/container/BlockLocation.java | 15 +++++ .../listener/PlayerEventListener.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 65 ++++++++----------- .../stargate/portal/PortalHandler.java | 13 ++-- .../stargate/utility/DirectionHelper.java | 54 +++++++++++---- .../stargate/utility/PermissionHelper.java | 2 +- .../stargate/utility/SignHelper.java | 2 +- 7 files changed, 94 insertions(+), 59 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index 7ea37e1..7fec741 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate.container; +import net.knarcraft.stargate.utility.DirectionHelper; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -8,6 +9,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Sign; import org.bukkit.block.data.type.WallSign; +import org.bukkit.util.Vector; /** * This class represents a block location @@ -81,6 +83,19 @@ public class BlockLocation extends Location { return newLocation.add(x, y, z); } + /** + * Gets a location relative to this block location + * + * @param vector

The relative block vector describing the relative location

+ * @param yaw

The yaw pointing in the distance direction

+ * @return

A location relative to this location

+ */ + public BlockLocation getRelativeLocation(RelativeBlockVector vector, double yaw) { + Vector combined = DirectionHelper.getCoordinateVectorFromRelativeVector(vector.getRight(), vector.getDepth(), + vector.getDistance(), yaw); + return makeRelative(combined.getBlockX(), combined.getBlockY(), combined.getBlockZ()); + } + /** * Makes a block location relative to the current origin according to given parameters * diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 9dcb908..885b0f7 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -217,7 +217,7 @@ public class PlayerEventListener implements Listener { } //Cycle portal destination - if ((!portal.isOpen()) && (!portal.isFixed())) { + if ((!portal.isOpen()) && (!portal.getOptions().isFixed())) { if (leftClick) { portal.cycleDestination(player, -1); } else { diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index bb47e36..0a635ae 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -314,7 +314,6 @@ public class Portal { if (frame == null) { frame = relativeBlockVectorsToBlockLocations(gate.getLayout().getBorder()); } - return frame; } @@ -398,7 +397,7 @@ public class Portal { Portal destination = getDestination(); // Only open destination if it's not-fixed or points at this portal - if (!options.isRandom() && destination != null && (!destination.isFixed() || + if (!options.isRandom() && destination != null && (!destination.options.isFixed() || destination.getDestinationName().equalsIgnoreCase(getName())) && !destination.isOpen()) { destination.open(openFor, false); destination.setDestination(this); @@ -413,16 +412,23 @@ public class Portal { * @param force

Whether to force this portal closed, even if it's set as always on

*/ public void close(boolean force) { - if (!isOpen) return; - // Call the StargateCloseEvent + if (!isOpen) { + return; + } + //Call the StargateCloseEvent StargateCloseEvent event = new StargateCloseEvent(this, force); Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) { + return; + } force = event.getForce(); - if (options.isAlwaysOn() && !force) return; // Only close always-open if forced + //Only close always-open if forced to + if (options.isAlwaysOn() && !force) { + return; + } - // Close this gate, then the dest gate. + //Close this gate, then the dest gate. Material closedType = gate.getPortalClosedBlock(); for (BlockLocation inside : getEntrances()) { Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, closedType, null)); @@ -470,28 +476,6 @@ public class Portal { return player != null && player.getName().equalsIgnoreCase(this.player.getName()); } - /** - * Gets whether this portal points to a fixed exit portal - * - *

A portal where portals can be chosen from a network is not fixed.

- * - * @return

True if this portal points to a fixed exit portal

- */ - public boolean isFixed() { - return options.isFixed(); - } - - /** - * Sets whether this portal points to a fixed exit portal - * - *

A portal where portals can be chosen from a network is not fixed.

- * - * @param fixed

True if this portal points to a fixed exit portal

- */ - public void setFixed(boolean fixed) { - options.setFixed(fixed); - } - /** * Teleports a player to this portal * @@ -693,22 +677,25 @@ public class Portal { if (openingWidth > 1) { newOffset -= 0.5; } - exitLocation = DirectionHelper.adjustLocation(exitLocation, newOffset, 0, 0, getModX(), getModZ()); + exitLocation = DirectionHelper.moveLocation(exitLocation, newOffset, 0, 0, getYaw()); //Move large entities further from the portal, especially if this portal will teleport them at once double entitySize = EntityHelper.getEntityMaxSize(entity); int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); if (entitySize > 1) { if (options.isAlwaysOn()) { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entityBoxSize / 2D), - getModX(), getModZ()); + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, (entityBoxSize / 2D), + getYaw()); } else { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, - (entitySize / 2D) - 1, getModX(), getModZ()); + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, + (entitySize / 2D) - 1, getYaw()); } } + + //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's + //moved one block out. if (entity instanceof AbstractHorse) { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, 1, getModX(), getModZ()); + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, 1, getYaw()); } return exitLocation; @@ -772,8 +759,8 @@ public class Portal { //Get the chunk in front of the gate corner Location cornerLocation = getBlockAt(vector).getLocation(); int blockOffset = options.isBackwards() ? -5 : 5; - Location fiveBlocksForward = DirectionHelper.adjustLocation(cornerLocation, 0, 0, blockOffset, - getModX(), getModZ()); + Location fiveBlocksForward = DirectionHelper.moveLocation(cornerLocation, 0, 0, blockOffset, + getYaw()); Chunk forwardChunk = fiveBlocksForward.getChunk(); //Load the chunks @@ -923,7 +910,7 @@ public class Portal { } Stargate.activePortalsQueue.remove(this); - if (isFixed()) { + if (options.isFixed()) { return; } destinations.clear(); @@ -938,7 +925,7 @@ public class Portal { * @return

Whether this portal is active

*/ public boolean isActive() { - return isFixed() || (destinations.size() > 0); + return options.isFixed() || (destinations.size() > 0); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 067f12b..6336838 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -85,7 +85,7 @@ public class PortalHandler { continue; } //Check if destination is a fixed portal not pointing to this portal - if (portal.isFixed() && !portal.getDestinationName().equalsIgnoreCase(entrancePortal.getName())) { + if (portal.getOptions().isFixed() && !portal.getDestinationName().equalsIgnoreCase(entrancePortal.getName())) { continue; } //Allow random use by non-players (Minecarts) @@ -157,7 +157,7 @@ public class PortalHandler { continue; } //Update the portal's sign - if (origin.isFixed()) { + if (origin.getOptions().isFixed()) { origin.drawSign(); } //Close portal without destination @@ -186,7 +186,8 @@ public class PortalHandler { * @param portal

The portal to register

*/ private static void registerPortal(Portal portal) { - portal.setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || portal.getOptions().isBungee()); + portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || + portal.getOptions().isBungee()); String portalName = portal.getName().toLowerCase(); String networkName = portal.getNetwork().toLowerCase(); @@ -615,7 +616,7 @@ public class PortalHandler { continue; } //Update sign of fixed gates pointing at this gate - if (origin.isFixed()) { + if (origin.getOptions().isFixed()) { origin.drawSign(); } //Open any always on portal pointing at this portal @@ -800,7 +801,7 @@ public class PortalHandler { builder.append(portal.getYaw()).append(':'); builder.append(portal.getTopLeft().toString()).append(':'); builder.append(portal.getGate().getFilename()).append(':'); - builder.append(portal.isFixed() ? portal.getDestinationName() : "").append(':'); + builder.append(portal.getOptions().isFixed() ? portal.getDestinationName() : "").append(':'); builder.append(portal.getNetwork()).append(':'); UUID owner = portal.getOwnerUUID(); if (owner != null) { @@ -1039,7 +1040,7 @@ public class PortalHandler { portalCount++; //Open the gate if it's set as always open or if it's a bungee gate - if (portal.isFixed() && (Stargate.enableBungee && portal.getOptions().isBungee() || + if (portal.getOptions().isFixed() && (Stargate.enableBungee && portal.getOptions().isBungee() || portal.getDestination() != null && portal.getOptions().isAlwaysOn())) { portal.open(true); openCount++; diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 9f747fc..aec2874 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -85,6 +85,18 @@ public final class DirectionHelper { } } + /** + * Gets a block location relative to another + * + * @param topLeft

The block location to start at (Usually the top-left block of a portal)

+ * @param vector

The relative vector describing the relative location

+ * @param yaw

The yaw pointing outwards from the portal

+ * @return

A block location relative to the given location

+ */ + public static BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, double yaw) { + return topLeft.getRelativeLocation(vector, yaw); + } + /** * Gets the block at a relative block vector location * @@ -96,19 +108,39 @@ public final class DirectionHelper { } /** - * Adds a relative block vector to a location, accounting for direction + * Moves a location relatively * - * @param location

The location to adjust

- * @param right

The amount of blocks to the right to adjust

- * @param depth

The amount of blocks upward to adjust

- * @param distance

The distance outward to adjust

- * @param modX

The x modifier to use

- * @param modZ

The z modifier to use

- * @return

The altered location

+ * @param location

The location to move

+ * @param right

The amount to go right (When looking at the front of a portal)

+ * @param depth

The amount to go downward (When looking at the front of a portal)

+ * @param distance

The amount to go outward (When looking a the front of a portal)

+ * @param yaw

The yaw when looking directly outwards from a portal

+ * @return

A location relative to the given location

*/ - public static Location adjustLocation(Location location, double right, double depth, double distance, int modX, - int modZ) { - return location.add(-right * modX + distance * modZ, depth, -right * modZ + -distance * modX); + public static Location moveLocation(Location location, double right, double depth, double distance, double yaw) { + return location.add(getCoordinateVectorFromRelativeVector(right, depth, distance, yaw)); + } + + /** + * Gets a vector in Minecraft's normal X,Y,Z-space from a relative block vector + * + * @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 yaw

The yaw when looking directly outwards from a portal

+ * @return

A normal vector

+ */ + public static Vector getCoordinateVectorFromRelativeVector(double right, double depth, double distance, double yaw) { + Vector distanceVector = DirectionHelper.getDirectionVectorFromYaw(yaw); + distanceVector.multiply(distance); + + Vector rightVector = DirectionHelper.getDirectionVectorFromYaw(yaw - 90); + rightVector.multiply(right); + + Vector depthVector = new Vector(0, -1, 0); + depthVector.multiply(depth); + + return distanceVector.add(rightVector).add(depthVector); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index bfe8444..588247a 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -50,7 +50,7 @@ public final class PermissionHelper { } //Gate that someone else is using -- Deny access - if ((!portal.isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { + if ((!portal.getOptions().isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index d84fa21..2bcfc0e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -28,7 +28,7 @@ public final class SignHelper { if (portal.getOptions().isBungee()) { //Bungee sign drawBungeeSign(sign, portal); - } else if (portal.isFixed()) { + } else if (portal.getOptions().isFixed()) { //Sign pointing at one other portal drawFixedSign(sign, portal); } else { From a68dc4b4644d538d429903d3d3185217585e4d6e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 18:21:30 +0200 Subject: [PATCH 116/378] Updates the README with new info and fixes a ton of gramatical errors --- README.md | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3f3535d..922aea7 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ The options are the single letter, not the word. So to make a private hidden gat #### Fixed gates: - Fixed gates go to only one set destination. -- Fixed gates can be linked to other fixed gates, or normal gates. A normal gate cannot open a portal to a fixed gate +- Fixed gates can be linked to other fixed gates, or normal gates. A normal gate cannot open a portal to a fixed gate, however. - To create a fixed gate, specify a destination on the second line of the stargate sign. - Set the 4th line of the stargate sign to "A" to enable an always-open fixed gate. @@ -125,8 +125,8 @@ The options are the single letter, not the word. So to make a private hidden gat ## Using a gate: -- Right click the sign to choose a destination. -- Right click the button to open up a portal. +- Right-click the sign to choose a destination. +- Right-click the button to open up a portal. - Step through. ## Economy Support: @@ -147,7 +147,7 @@ toowner=true You can create as many gate formats as you want, the gate layouts are stored in `plugins/Stargate/gates/`. The .gate file must be laid out a specific way, the first lines will be config information, and after a blank line you -will lay out the gate format. Here is the default nether.gate file: +will lay out the gate format. Here is the default nethergate.gate file: ``` portal-open=NETHER_PORTAL @@ -263,11 +263,11 @@ permdebug: Whether to show massive permission debug output # Message Customization -It is possible to customize all of the messages Stargate displays, including the [Stargate] prefix. You can find the +It is possible to customize all the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/lang/chosenLanguage.txt. -If a string is removed, or left blank, it will default to the default english string. There are some special cases when -it comes to messages. When you see %variableName%, you need to keep this part in your string, as it will be replaced +If a string is removed, or left blank, it will default to the default english string. There are some special cases +regarding messages. When you see %variableName%, you need to keep this part in your string, as it will be replaced with relevant values. The full list of strings is as follows: @@ -315,10 +315,9 @@ bungeeSign=Teleport to #### \[Version 0.9.0.0] (WIP) EpicKnarvik97 fork - Changes entire path structure to a more modern and maven-compliant one -- Changes package structure to net.knarcaft.stargate.* +- Changes package structure to net.knarcraft.stargate.* - Moves language files into the resources folder - Fixes some bugs caused by language files not being read as UTF-8 -- Makes Blox into BlockLocation which now extends Location - Adds JavaDoc to a lot of the code - Adds Norwegian translation for both Norwegian languages - Adds missing dependency information to plugin.yml @@ -328,9 +327,17 @@ bungeeSign=Teleport to - Adds underwater portals - Makes it easier to add more default gates - Adds a new default gate which can be used underwater -- Adds more items usable as buttons (corals, chest, shulker box), which allows underwater portals +- Adds more items usable as buttons (corals, chest, shulker-box), which allows underwater portals - Splits a lot of the code into smaller objects - Moves duplicated code into helper classes +- Re-implements vehicle teleportation +- Makes boat teleportation work as expected +- Makes it possible to teleport a player riding a pig or a horse +- Makes both nether portals and end gateways work properly without causing mayhem +- Replaces the modX and modZ stuff with yaw calculation to make it easier to understand +- Comments all the code +- Extracts portal options and portal-related locations to try and reduce size +- Rewrites tons of code to make it more readable and manageable #### \[Version 0.8.0.3] PseudoKnight fork @@ -349,7 +356,7 @@ bungeeSign=Teleport to #### \[Version 0.8.0.0] PseudoKnight fork -- Update for 1.13/1.14 compatibility. This changes gate layouts to use new material names instead of numeric ids. You +- Update for 1.13/1.14 compatibility. This update changes gate layouts to use new material names instead of numeric ids. You need to update your gate layout configs. - Adds "verifyPortals" config option, which sets whether an old stargate's blocks are verified when loaded. - Adds UUID support. (falls back to player names) @@ -428,11 +435,11 @@ bungeeSign=Teleport to #### \[Version 0.7.7.5] -- Resolve issue of right clicking introduced in 1.3.1/2 +- Resolve issue of right-clicking introduced in 1.3.1/2 #### \[Version 0.7.7.4] -- Removed try/catch, it was still segfaulting. +- Removed try/catch, it was still segfault-ing. - Built against 1.3.1 #### \[Version 0.7.7.3] @@ -470,11 +477,11 @@ bungeeSign=Teleport to #### \[Version 0.7.6.5] - Resolve issue with buttons on glass gates falling off -- /sg reload can now be used ingame (stargate.admin.reload permission) +- /sg reload can now be used in-game (stargate.admin.reload permission) #### \[Version 0.7.6.4] -- Move blockBreak to HIGHEST priority, this resolves issues with region protection plugins +- Move blockBreak to the HIGHEST priority, this resolves issues with region protection plugins #### \[Version 0.7.6.3] @@ -562,7 +569,7 @@ bungeeSign=Teleport to #### \[Version 0.7.4.3] -- Implement StargateAccessEvent, used for bypassing permission checks/denying access to gates. +- Implement StargateAccessEvent, used for bypassing permission checks/denying gate access. #### \[Version 0.7.4.2] @@ -603,7 +610,7 @@ bungeeSign=Teleport to #### \[Version 0.7.2] -- Make it so you can still destroy gates in Survival mode +- Make it so that you can still destroy gates in Survival mode #### \[Version 0.7.1] @@ -775,7 +782,7 @@ bungeeSign=Teleport to #### \[Version 0.3.2] -- Updated to latest RB +- Updated to the latest RB - Implemented proper vehicle handling - Added iConomy to vehicle handling - Can now set cost to go to creator on use @@ -791,8 +798,8 @@ bungeeSign=Teleport to #### \[Version 0.29] -- Added iConomy support. Currently only works with iConomy 4.4 until Niji fixes 4.5 -- Thanks @Jonbas for the base iConomy implementation +- Added iConomy support. It currently only works with iConomy 4.4 until Niji fixes 4.5 +- Thanks, @Jonbas, for the base iConomy implementation #### \[Version 0.28] @@ -896,8 +903,8 @@ bungeeSign=Teleport to #### \[Version 0.08] - Gates can now consist of any material. -- You can left or right click the button to open a gate -- Gates are now initialized on sign placement, not more right clicking! +- You can left-click or right-click the button to open a gate +- Gates are now initialized on sign placement, not more right-clicking! #### \[Version 0.07] From fff4d8d78b0b21469f33c80e80523d2395252ddc Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 18:23:42 +0200 Subject: [PATCH 117/378] Gets rid of the rest of the modX and modY usages, and removes some unused code --- .../knarcraft/stargate/LanguageLoader.java | 10 ++- .../java/net/knarcraft/stargate/Stargate.java | 3 + .../container/BlockChangeRequest.java | 33 +-------- .../stargate/container/BlockLocation.java | 66 +++++++----------- .../container/RelativeBlockVector.java | 31 +++++++++ .../stargate/event/StargateOpenEvent.java | 1 + .../stargate/event/StargatePlayerEvent.java | 1 + .../stargate/event/StargatePortalEvent.java | 8 +-- .../listener/PlayerEventListener.java | 2 +- .../stargate/listener/WorldEventListener.java | 2 +- .../net/knarcraft/stargate/portal/Gate.java | 68 ++++++------------- .../stargate/portal/GateHandler.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 60 ++++++---------- .../stargate/portal/PortalDirection.java | 6 -- .../stargate/portal/PortalHandler.java | 64 ++++++++--------- .../stargate/portal/PortalLocation.java | 43 +----------- .../stargate/utility/BungeeHelper.java | 2 +- .../stargate/utility/DirectionHelper.java | 14 +--- .../stargate/utility/EconomyHelper.java | 2 +- .../knarcraft/stargate/BlockLocationTest.java | 11 +-- 20 files changed, 150 insertions(+), 279 deletions(-) delete mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalDirection.java diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index 1cf4951..edae036 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -229,12 +229,16 @@ public class LanguageLoader { public void debug() { Set keys = loadedStringTranslations.keySet(); for (String key : keys) { - Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + loadedStringTranslations.get(key)); + Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + + loadedStringTranslations.get(key)); + } + if (loadedBackupStrings == null) { + return; } - if (loadedBackupStrings == null) return; keys = loadedBackupStrings.keySet(); for (String key : keys) { - Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " + loadedBackupStrings.get(key)); + Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " + + loadedBackupStrings.get(key)); } } diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 975c97c..741b1f0 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -322,6 +322,9 @@ public class Stargate extends JavaPlugin { // It is important to load languages here, as they are used during reloadGates() languageLoader = new LanguageLoader(languageFolder, Stargate.languageName); + if (debuggingEnabled) { + languageLoader.debug(); + } this.createMissingFolders(); this.loadGates(); diff --git a/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java b/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java index 57008c4..55e5269 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java @@ -8,9 +8,9 @@ import org.bukkit.Material; */ public class BlockChangeRequest { - private BlockLocation blockLocation; - private Material newMaterial; - private Axis newAxis; + private final BlockLocation blockLocation; + private final Material newMaterial; + private final Axis newAxis; /** * Instantiates a new block change request @@ -34,15 +34,6 @@ public class BlockChangeRequest { return blockLocation; } - /** - * Sets the location of the block - * - * @param blockLocation

The new location of the block

- */ - public void setBlockLocation(BlockLocation blockLocation) { - this.blockLocation = blockLocation; - } - /** * Gets the material to change the block into * @@ -52,15 +43,6 @@ public class BlockChangeRequest { return newMaterial; } - /** - * Sets the material to change the block into - * - * @param material

The new material

- */ - public void setMaterial(Material material) { - newMaterial = material; - } - /** * Gets the axis to orient the block along * @@ -70,13 +52,4 @@ public class BlockChangeRequest { return newAxis; } - /** - * Sets the axis to orient the block along - * - * @param axis

The new axis to orient the block along

- */ - public void setAxis(Axis axis) { - newAxis = axis; - } - } diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index 7fec741..36f3386 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -62,73 +62,53 @@ public class BlockLocation extends Location { * @param z

The z position relative to this block's position

* @return

A new block location

*/ - public BlockLocation makeRelative(int x, int y, int z) { + public BlockLocation makeRelativeBlockLocation(int x, int y, int z) { return (BlockLocation) this.clone().add(x, y, z); } /** * Makes a location relative to the block location * - * @param x

The x position relative to this block's position

- * @param y

The y position relative to this block's position

- * @param z

The z position relative to this block's position

- * @param yaw

The yaw of the location

- * @param rotY

The y rotation of the location

+ * @param x

The x position relative to this block's position

+ * @param y

The y position relative to this block's position

+ * @param z

The z position relative to this block's position

+ * @param yaw

The yaw of the location

* @return

A new location

*/ - public Location makeRelativeLoc(double x, double y, double z, float yaw, float rotY) { + public Location makeRelativeLocation(double x, double y, double z, float yaw) { Location newLocation = this.clone(); newLocation.setYaw(yaw); - newLocation.setPitch(rotY); + newLocation.setPitch(0); return newLocation.add(x, y, z); } /** * Gets a location relative to this block location * - * @param vector

The relative block vector describing the relative location

- * @param yaw

The yaw pointing in the distance direction

+ * @param relativeVector

The relative block vector describing the relative location

+ * @param yaw

The yaw pointing in the distance direction

* @return

A location relative to this location

*/ - public BlockLocation getRelativeLocation(RelativeBlockVector vector, double yaw) { - Vector combined = DirectionHelper.getCoordinateVectorFromRelativeVector(vector.getRight(), vector.getDepth(), - vector.getDistance(), yaw); - return makeRelative(combined.getBlockX(), combined.getBlockY(), combined.getBlockZ()); - } - - /** - * 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) { - return makeRelative(-right * modX + distance * modZ, -depth * modY, -right * modZ + -distance * modX); + public BlockLocation getRelativeLocation(RelativeBlockVector relativeVector, double yaw) { + Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(relativeVector.getRight(), + relativeVector.getDepth(), relativeVector.getDistance(), yaw); + return makeRelativeBlockLocation(realVector.getBlockX(), realVector.getBlockY(), realVector.getBlockZ()); } /** * Makes a 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 yaw

The yaw of the location

- * @param rotY

Unused

- * @param modX

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

- * @param modY

Unused

- * @param modZ

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

+ * @param right

The amount of blocks to go right when looking the opposite direction from the yaw

+ * @param depth

The amount of blocks to go downwards when looking the opposite direction from the yaw

+ * @param distance

The amount of blocks to go outwards when looking the opposite direction from the yaw

+ * @param portalYaw

The yaw when looking out from the portal

+ * @param yaw

The yaw of the travelling entity

* @return A new location relative to this block location */ - public Location modRelativeLoc(double right, double depth, double distance, float yaw, float rotY, int modX, int modY, int modZ) { - return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, yaw, 0); + public Location getRelativeLocation(double right, double depth, double distance, float portalYaw, float yaw) { + Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(right, depth, distance, portalYaw); + return makeRelativeLocation(0.5 + realVector.getBlockX(), realVector.getBlockY(), + 0.5 + realVector.getBlockZ(), yaw); } /** @@ -193,7 +173,7 @@ public class BlockLocation extends Location { } else { return; } - parent = this.makeRelative(offsetX, offsetY, offsetZ); + parent = this.makeRelativeBlockLocation(offsetX, offsetY, offsetZ); } @Override diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 6c1a8bf..8e02bb3 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -14,6 +14,8 @@ public class RelativeBlockVector { private final int depth; private final int distance; + public enum Property {RIGHT, DEPTH, DISTANCE} + /** * Instantiates a new relative block vector * @@ -27,6 +29,35 @@ public class RelativeBlockVector { this.distance = distance; } + /** + * Adds a value to one of the properties of this relative block vector + * + * @param propertyToAddTo

The property to change

+ * @param valueToAdd

The value to add to the property

+ * @return

A new relative block vector with the property altered

+ */ + public RelativeBlockVector addToVector(Property propertyToAddTo, int valueToAdd) { + switch (propertyToAddTo) { + case RIGHT: + return new RelativeBlockVector(this.right + valueToAdd, this.depth, this.distance); + case DEPTH: + return new RelativeBlockVector(this.right, this.depth + valueToAdd, this.distance); + case DISTANCE: + return new RelativeBlockVector(this.right, this.depth, this.distance + valueToAdd); + default: + throw new IllegalArgumentException("Invalid relative block vector property given"); + } + } + + /** + * Gets a relative block vector which is this inverted (pointing in the opposite direction) + * + * @return

This vector, but inverted

+ */ + public RelativeBlockVector invert() { + return new RelativeBlockVector(-this.right, -this.depth, -this.distance); + } + /** * Gets the distance to the right relative to the origin * diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index 04bf752..1c7e649 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a player opens a stargate */ +@SuppressWarnings({"unused"}) public class StargateOpenEvent extends StargatePlayerEvent { private static final HandlerList handlers = new HandlerList(); diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java index bc7074d..a68db69 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java @@ -6,6 +6,7 @@ import org.bukkit.entity.Player; /** * An abstract event describing any stargate event where a player is involved */ +@SuppressWarnings("unused") public abstract class StargatePlayerEvent extends StargateEvent { private final Player player; diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java index ed13e26..0f30913 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java @@ -41,9 +41,9 @@ public class StargatePortalEvent extends StargatePlayerEvent { } /** - * Return the destination gate + * Return the destination portal * - * @return destination gate + * @return

The destination portal

*/ public Portal getDestination() { return destination; @@ -52,14 +52,14 @@ public class StargatePortalEvent extends StargatePlayerEvent { /** * Return the location of the players exit point * - * @return org.bukkit.Location Location of the exit point + * @return

Location of the exit point

*/ public Location getExit() { return exit; } /** - * Set the location of the players exit point + * Set the location of the player's exit point */ public void setExit(Location loc) { this.exit = loc; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 885b0f7..2e3d31d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -244,7 +244,7 @@ public class PlayerEventListener implements Listener { } /** - * This method handles right clicking of a sign or button belonging to a stargate + * This method handles right-clicking of a sign or button belonging to a stargate * * @param event

The event triggering the right-click

* @param player

The player doing the right-click

diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index f729fda..5f53cc6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -15,7 +15,7 @@ import org.bukkit.event.world.WorldUnloadEvent; public class WorldEventListener implements Listener { /** - * This listener listens for the loading of a world and loads all all gates from the world if not already loaded + * This listener listens for the loading of a world and loads all gates from the world if not already loaded * * @param event

The triggered world load event

*/ diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 51ae9d2..8fd74bd 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -26,8 +26,8 @@ public class Gate { private final Map types; //Gate materials - private Material portalOpenBlock; - private Material portalClosedBlock; + private final Material portalOpenBlock; + private final Material portalClosedBlock; private final Material portalButton; // Economy information @@ -74,15 +74,6 @@ public class Gate { return layout; } - /** - * Gets the material types each layout character represents - * - * @return

The material types each layout character represents

- */ - public Map getTypes() { - return types; - } - /** * Gets the material type used for this gate's control blocks * @@ -110,15 +101,6 @@ public class Gate { return portalOpenBlock; } - /** - * Sets the block to use for the opening when a portal using this gate is open - * - * @param type

The block type to use for the opening when open

- */ - public void setPortalOpenBlock(Material type) { - portalOpenBlock = type; - } - /** * Gets the block type to use for the opening when a portal using this gate is closed * @@ -128,15 +110,6 @@ public class Gate { return portalClosedBlock; } - /** - * Sets the block type to use for the opening when a portal using this gate is closed - * - * @param type

The block type to use for the opening when closed

- */ - public void setPortalClosedBlock(Material type) { - portalClosedBlock = type; - } - /** * Gets the material to use for a portal's button if using this gate type * @@ -186,36 +159,33 @@ public class Gate { * Checks whether a portal's gate matches this gate type * * @param topLeft

The top-left block of the portal's gate

- * @param modX

The x modifier used

- * @param modZ

The z modifier used

+ * @param yaw

The yaw when looking directly outwards

* @return

True if this gate matches the portal

*/ - public boolean matches(BlockLocation topLeft, int modX, int modZ) { - return matches(topLeft, modX, modZ, false); + public boolean matches(BlockLocation topLeft, double yaw) { + return matches(topLeft, yaw, false); } /** * Checks whether a portal's gate matches this gate type * * @param topLeft

The top-left block of the portal's gate

- * @param modX

The x modifier used

- * @param modZ

The z modifier used

+ * @param yaw

The yaw when looking directly outwards

* @param onCreate

Whether this is used in the context of creating a new gate

* @return

True if this gate matches the portal

*/ - public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) { - return verifyGateEntrancesMatch(topLeft, modX, modZ, onCreate) && verifyGateBorderMatches(topLeft, modX, modZ); + public boolean matches(BlockLocation topLeft, double yaw, boolean onCreate) { + return verifyGateEntrancesMatch(topLeft, yaw, onCreate) && verifyGateBorderMatches(topLeft, yaw); } /** * Verifies that all border blocks of a portal gate matches this gate type * * @param topLeft

The top-left block of the portal

- * @param modX

The x modifier used

- * @param modZ

The z modifier used

+ * @param yaw

The yaw when looking directly outwards

* @return

True if all border blocks of the gate match the layout

*/ - private boolean verifyGateBorderMatches(BlockLocation topLeft, int modX, int modZ) { + private boolean verifyGateBorderMatches(BlockLocation topLeft, double yaw) { Map portalTypes = new HashMap<>(types); for (RelativeBlockVector borderVector : layout.getBorder()) { int rowIndex = borderVector.getRight(); @@ -223,7 +193,7 @@ public class Gate { Character key = layout.getLayout()[lineIndex][rowIndex]; Material materialInLayout = portalTypes.get(key); - Material materialAtLocation = getBlockAt(topLeft, borderVector, modX, modZ).getType(); + Material materialAtLocation = getBlockAt(topLeft, borderVector, yaw).getType(); if (materialInLayout == null) { portalTypes.put(key, materialAtLocation); } else if (materialAtLocation != materialInLayout) { @@ -239,19 +209,20 @@ public class Gate { * Verifies that all entrances of a portal gate matches this gate type * * @param topLeft

The top-left block of this portal

- * @param modX

The x modifier used

- * @param modZ

The z modifier used

+ * @param yaw

The yaw when looking directly outwards

* @param onCreate

Whether this is used in the context of creating a new gate

* @return

Whether this is used in the context of creating a new gate

*/ - private boolean verifyGateEntrancesMatch(BlockLocation topLeft, int modX, int modZ, boolean onCreate) { + private boolean verifyGateEntrancesMatch(BlockLocation topLeft, double yaw, boolean onCreate) { if (Stargate.ignoreEntrance) { return true; } + Stargate.debug("verifyGateEntrancesMatch", String.valueOf(topLeft)); for (RelativeBlockVector entranceVector : layout.getEntrances()) { - Material type = getBlockAt(topLeft, entranceVector, modX, modZ).getType(); + Stargate.debug("verifyGateEntrancesMatch", String.valueOf(entranceVector)); + Material type = getBlockAt(topLeft, entranceVector, yaw).getType(); - // Ignore entrance if it's air and we're creating a new gate + //Ignore entrance if it's air, and we're creating a new gate if (onCreate && type == Material.AIR) { continue; } @@ -270,8 +241,8 @@ public class Gate { * @param vector

The relative block vector

* @return

The block at the given relative position

*/ - private BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, int modX, int modZ) { - return DirectionHelper.getBlockAt(topLeft, vector, modX, modZ); + private BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, double yaw) { + return DirectionHelper.getBlockAt(topLeft, vector, yaw); } /** @@ -371,6 +342,7 @@ public class Gate { * @param value

The value of the config key

* @throws IOException

If unable to write to the buffered writer

*/ + @SuppressWarnings("SameParameterValue") private void writeConfig(BufferedWriter bufferedWriter, String key, boolean value) throws IOException { writeConfig(bufferedWriter, "%s=%b", key, value); } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 3b5d700..b85f77c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -378,7 +378,7 @@ public class GateHandler { } if (files == null || files.length == 0) { - //The gates folder was not found. Assume this is the first run + //The gates-folder was not found. Assume this is the first run if (directory.mkdir()) { populateDefaults(gateFolder); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 0a635ae..8dc9afd 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -78,30 +78,24 @@ public class Portal { * @param button

The location of the portal's open button

* @param destination

The destination defined on the sign's destination line

* @param name

The name of the portal defined on the sign's first line

- * @param verified

Whether the portal's gate has been verified to match its template

* @param network

The network the portal belongs to, defined on the sign's network line

* @param gate

The gate template this portal uses

* @param ownerUUID

The UUID of the gate's owner

* @param ownerName

The name of the gate's owner

* @param options

A map containing all possible portal options

*/ - Portal(PortalLocation portalLocation, BlockLocation button, - String destination, String name, boolean verified, String network, Gate gate, UUID ownerUUID, - String ownerName, Map options) { + Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, String network, + Gate gate, UUID ownerUUID, String ownerName, Map options) { this.location = portalLocation; this.destination = destination; this.button = button; - this.verified = verified; + this.verified = false; this.network = network; this.name = name; this.gate = gate; this.ownerUUID = ownerUUID; this.ownerName = ownerName; this.options = new PortalOptions(options, destination.length() > 0); - - if (verified) { - this.drawSign(); - } } /** @@ -145,6 +139,7 @@ public class Portal { * * @param network

The new network for this gate

*/ + @SuppressWarnings("unused") public void setNetwork(String network) { this.network = network; } @@ -172,6 +167,7 @@ public class Portal { * * @param name

The new name of this portal

*/ + @SuppressWarnings("unused") public void setName(String name) { this.name = filterName(name); drawSign(); @@ -275,6 +271,7 @@ public class Portal { * * @param owner

The new UUID of this portal's owner

*/ + @SuppressWarnings("unused") public void setOwner(UUID owner) { this.ownerUUID = owner; } @@ -348,24 +345,22 @@ public class Portal { * Open this portal * * @param force

Whether to force this portal open, even if it's already open for some player

- * @return

True if the portal was opened

*/ - public boolean open(boolean force) { - return open(null, force); + public void open(boolean force) { + open(null, force); } /** * Open this portal * * @param force

Whether to force this portal open, even if it's already open for some player

- * @return

True if the portal was opened

*/ - public boolean open(Player openFor, boolean force) { + public void open(Player openFor, boolean force) { //Call the StargateOpenEvent StargateOpenEvent event = new StargateOpenEvent(openFor, this, force); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled() || (isOpen() && !event.getForce())) { - return false; + return; } //Change the opening blocks to the correct type @@ -376,7 +371,6 @@ public class Portal { } updatePortalOpenState(openFor); - return true; } /** @@ -401,7 +395,9 @@ public class Portal { destination.getDestinationName().equalsIgnoreCase(getName())) && !destination.isOpen()) { destination.open(openFor, false); destination.setDestination(this); - if (destination.isVerified()) destination.drawSign(); + if (destination.isVerified()) { + destination.drawSign(); + } } } } @@ -636,9 +632,11 @@ public class Portal { RelativeBlockVector relativeExit = gate.getLayout().getExit(); if (relativeExit != null) { BlockLocation exit = getBlockAt(relativeExit); - int back = (options.isBackwards()) ? -1 : 1; - exitLocation = exit.modRelativeLoc(0D, 0D, 1, traveller.getYaw(), - traveller.getPitch(), getModX() * back, 1, getModZ() * back); + float yaw = traveller.getYaw(); + if (options.isBackwards()) { + yaw += 180; + } + exitLocation = exit.getRelativeLocation(0D, 0D, 1, this.getYaw(), yaw); if (entity != null) { double entitySize = EntityHelper.getEntityMaxSize(entity); @@ -791,24 +789,6 @@ public class Portal { return this.location.getSignLocation(); } - /** - * Gets the x modifier used by this portal - * - * @return

The x modifier used by this portal

- */ - public int getModX() { - return this.location.getModX(); - } - - /** - * Gets the z modifier used by this portal - * - * @return

The z modifier used by this portal

- */ - public int getModZ() { - return this.location.getModZ(); - } - /** * Gets the rotation of this portal * @@ -864,7 +844,7 @@ public class Portal { if (!Stargate.verifyPortals) { return true; } - return gate.matches(getTopLeft(), getModX(), getModZ()); + return gate.matches(getTopLeft(), getYaw()); } /** @@ -1014,7 +994,7 @@ public class Portal { * @return

The block at the given relative position

*/ public BlockLocation getBlockAt(RelativeBlockVector vector) { - return DirectionHelper.getBlockAt(getTopLeft(), vector, getModX(), getModZ()); + return DirectionHelper.getBlockAt(getTopLeft(), vector, getYaw()); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java b/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java deleted file mode 100644 index d6bbb4a..0000000 --- a/src/main/java/net/knarcraft/stargate/portal/PortalDirection.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.knarcraft.stargate.portal; - -public class PortalDirection { - - -} diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 6336838..c11f5e1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -20,7 +20,6 @@ import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Player; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.util.Vector; import java.io.BufferedWriter; import java.io.File; @@ -245,6 +244,7 @@ public class PortalHandler { //Return early if the sign is not placed on a block, or the block is not a control block if (idParent == null || GateHandler.getGatesByControlBlock(idParent).length == 0) { + Stargate.debug("createPortal", "Control block not registered"); return null; } @@ -269,14 +269,10 @@ public class PortalHandler { //Get the direction the button should be facing BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw); - //Get the x and z modifiers - Vector direction = DirectionHelper.getDirectionVectorFromYaw(yaw); - //TODO: Figure out how modX and modZ really works and simplify it - int modX = -direction.getBlockZ(); - int modZ = direction.getBlockX(); - PortalLocation portalLocation = new PortalLocation(); - portalLocation.setButtonFacing(buttonFacing).setYaw(yaw).setModX(modX).setModZ(modZ).setSignLocation(signLocation); + portalLocation.setButtonFacing(buttonFacing).setYaw(yaw).setSignLocation(signLocation); + + Stargate.debug("createPortal", "Finished getting all portal info"); //Try and find a gate matching the new portal Gate gate = findMatchingGate(portalLocation, player); @@ -287,6 +283,7 @@ public class PortalHandler { //If the portal is a bungee portal and invalid, abort here if (!isValidBungeePortal(portalOptions, player, destinationName, network)) { + Stargate.debug("createPortal", "Portal is an invalid bungee portal"); return null; } @@ -344,7 +341,7 @@ public class PortalHandler { } //Check if a conflict exists - if (conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), modX, modZ, player)) { + if (conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), yaw, player)) { return null; } @@ -392,8 +389,7 @@ public class PortalHandler { //Get all gates with the used type of control blocks Gate[] possibleGates = GateHandler.getGatesByControlBlock(signParent); - int modX = portalLocation.getModX(); - int modZ = portalLocation.getModZ(); + double yaw = portalLocation.getYaw(); Gate gate = null; for (Gate possibleGate : possibleGates) { @@ -403,9 +399,8 @@ public class PortalHandler { portalLocation.setButtonVector(null); for (RelativeBlockVector controlVector : vectors) { //Assuming the top-left location is pointing to the gate's top-left location, check if it's a match - BlockLocation possibleTopLocation = parent.modRelative(-controlVector.getRight(), - -controlVector.getDepth(), -controlVector.getDistance(), modX, 1, modZ); - if (possibleGate.matches(possibleTopLocation, modX, modZ, true)) { + BlockLocation possibleTopLocation = parent.getRelativeLocation(controlVector.invert(), yaw); + if (possibleGate.matches(possibleTopLocation, portalLocation.getYaw(), true)) { gate = possibleGate; portalLocation.setTopLeft(possibleTopLocation); } else { @@ -422,19 +417,16 @@ public class PortalHandler { * * @param gate

The gate type of the new portal

* @param topLeft

The top-left block of the new portal

- * @param modX

The x-modifier for the new portal

- * @param modZ

The new z-modifier for the new portal

+ * @param yaw

The yaw when looking directly outwards from the portal

* @param player

The player creating the new portal

* @return

True if a conflict was found. False otherwise

*/ - private static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, int modX, int modZ, - Player player) { + private static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, double yaw, Player player) { //TODO: Make a quicker check. Could just check for control block conflicts if all code is changed to account for // getting several hits at a single location when checking for the existence of a portal. May make // everything slower overall? Would make for cooler gates though. for (RelativeBlockVector borderVector : gate.getLayout().getBorder()) { - BlockLocation borderBlockLocation = topLeft.modRelative(borderVector.getRight(), borderVector.getDepth(), - borderVector.getDistance(), modX, 1, modZ); + BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); if (getByBlock(borderBlockLocation.getBlock()) != null) { Stargate.debug("createPortal", "Gate conflicts with existing gate"); Stargate.sendErrorMessage(player, Stargate.getString("createConflict")); @@ -463,7 +455,7 @@ public class PortalHandler { Map portalOptions, String denyMessage, String[] lines, boolean deny) { Portal portal = new Portal(portalLocation, null, destinationName, portalName, - false, network, gate, player.getUniqueId(), player.getName(), portalOptions); + network, gate, player.getUniqueId(), player.getName(), portalOptions); int createCost = EconomyHandler.getCreateCost(player, gate); @@ -569,8 +561,10 @@ public class PortalHandler { */ private static void generatePortalButton(Portal portal, BlockLocation topLeft, RelativeBlockVector buttonVector, BlockFace buttonFacing) { - BlockLocation button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), - buttonVector.getDistance() + 1, portal.getModX(), 1, portal.getModZ()); + //Go one block outwards to find the button's location rather than the control block's location + BlockLocation button = topLeft.getRelativeLocation(buttonVector.addToVector( + RelativeBlockVector.Property.DISTANCE, 1), portal.getYaw()); + Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); buttonData.setFacing(buttonFacing); button.getBlock().setBlockData(buttonData); @@ -724,15 +718,15 @@ public class PortalHandler { adjacentPositions.add(centerLocation); for (int index = 1; index <= range; index++) { - adjacentPositions.add(centerLocation.makeRelative(index, 0, 0)); - adjacentPositions.add(centerLocation.makeRelative(-index, 0, 0)); - adjacentPositions.add(centerLocation.makeRelative(0, 0, index)); - adjacentPositions.add(centerLocation.makeRelative(0, 0, -index)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(index, 0, 0)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(-index, 0, 0)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(0, 0, index)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(0, 0, -index)); if (index < range) { - adjacentPositions.add(centerLocation.makeRelative(index, 0, index)); - adjacentPositions.add(centerLocation.makeRelative(-index, 0, -index)); - adjacentPositions.add(centerLocation.makeRelative(index, 0, -index)); - adjacentPositions.add(centerLocation.makeRelative(-index, 0, index)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(index, 0, index)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(-index, 0, -index)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(index, 0, -index)); + adjacentPositions.add(centerLocation.makeRelativeBlockLocation(-index, 0, index)); } } @@ -796,8 +790,8 @@ public class PortalHandler { builder.append(portal.getName()).append(':'); builder.append(portal.getSignLocation().toString()).append(':'); builder.append((button != null) ? button.toString() : "").append(':'); - builder.append(portal.getModX()).append(':'); - builder.append(portal.getModZ()).append(':'); + builder.append(0).append(':'); + builder.append(0).append(':'); builder.append(portal.getYaw()).append(':'); builder.append(portal.getTopLeft().toString()).append(':'); builder.append(portal.getGate().getFilename()).append(':'); @@ -958,8 +952,6 @@ public class PortalHandler { PortalLocation portalLocation = new PortalLocation(); portalLocation.setSignLocation(new BlockLocation(world, portalData[1])); BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; - portalLocation.setModX(Integer.parseInt(portalData[3])); - portalLocation.setModZ(Integer.parseInt(portalData[4])); portalLocation.setYaw(Float.parseFloat(portalData[5])); portalLocation.setTopLeft(new BlockLocation(world, portalData[6])); Gate gate = GateHandler.getGateByName(portalData[7]); @@ -995,7 +987,7 @@ public class PortalHandler { } //Creates the new portal - Portal portal = new Portal(portalLocation, button, destination, name, false, + Portal portal = new Portal(portalLocation, button, destination, name, network, gate, ownerUUID, ownerName, getPortalOptions(portalData)); registerPortal(portal); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java b/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java index 8c0da51..32d5e51 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java @@ -9,11 +9,10 @@ import org.bukkit.block.BlockFace; /** * Keeps track of location related data for a portal */ +@SuppressWarnings("UnusedReturnValue") public class PortalLocation { private BlockLocation topLeft; - private int modX; - private int modZ; private float yaw; private BlockLocation signLocation; private RelativeBlockVector buttonVector; @@ -28,24 +27,6 @@ public class PortalLocation { return topLeft; } - /** - * Gets the x-modifier for the portal - * - * @return

The x-modifier for the portal

- */ - public int getModX() { - return modX; - } - - /** - * Gets the z-modifier for the portal - * - * @return

The z-modifier for the portal

- */ - public int getModZ() { - return modZ; - } - /** * Gets the yaw for looking outwards from the portal * @@ -115,28 +96,6 @@ public class PortalLocation { return this; } - /** - * Sets the portal's x-modifier - * - * @param modX

The portal's new x-modifier

- * @return

The portal location Object

- */ - public PortalLocation setModX(int modX) { - this.modX = modX; - return this; - } - - /** - * Sets the portal's z-modifier - * - * @param modZ

The portal's new z-modifier

- * @return

The portal location Object

- */ - public PortalLocation setModZ(int modZ) { - this.modZ = modZ; - return this; - } - /** * Sets the portal's yaw * diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index a894503..1137b08 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -125,7 +125,7 @@ public final class BungeeHelper { Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); } else { Portal destinationPortal = PortalHandler.getBungeePortal(destination); - // Specified an invalid gate. For now we'll just let them connect at their current location + // Specified an invalid gate. For now, we'll just let them connect at their current location if (destinationPortal == null) { Stargate.logger.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); return; diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index aec2874..c0f3132 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -7,7 +7,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; /** - * This class helps with direction-dependent (modX, modZ) calculations + * This class helps with direction-dependent calculations */ public final class DirectionHelper { @@ -81,7 +81,7 @@ public final class DirectionHelper { } else if (yaw == 270) { return new Vector(1, 0, 0); } else { - throw new IllegalArgumentException("Invalid yaw given"); + throw new IllegalArgumentException(String.format("Invalid yaw %f given", yaw)); } } @@ -97,16 +97,6 @@ public final class DirectionHelper { return topLeft.getRelativeLocation(vector, yaw); } - /** - * Gets the block at a relative block vector location - * - * @param vector

The relative block vector

- * @return

The block at the given relative position

- */ - public static BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, int modX, int modZ) { - return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); - } - /** * Moves a location relatively * diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 31519ef..2b0d34b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -39,7 +39,7 @@ public final class EconomyHelper { return false; } - //Send the deduct message to the player + //Send the deduct-message to the player sendDeductMessage(entrancePortal.getName(), player, cost); if (entrancePortal.getGate().getToOwner()) { diff --git a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java index 8dd6426..0935057 100644 --- a/src/test/java/net/knarcraft/stargate/BlockLocationTest.java +++ b/src/test/java/net/knarcraft/stargate/BlockLocationTest.java @@ -62,7 +62,7 @@ public class BlockLocationTest { @Test public void makeRelativeTest() { BlockLocation location = new BlockLocation(mockWorld, 3, 7, 19); - BlockLocation newLocation = location.makeRelative(34, 65, 75); + BlockLocation newLocation = location.makeRelativeBlockLocation(34, 65, 75); assertEquals(37, newLocation.getBlockX()); assertEquals(72, newLocation.getBlockY()); assertEquals(94, newLocation.getBlockZ()); @@ -82,13 +82,4 @@ 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()); - } - } From 0c29788a3114bfcee883bafd9a1ffccbed9472e4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 18:59:14 +0200 Subject: [PATCH 118/378] Fixes the behavior of backwards portals Fixes a bug where backwards portals only rotated the player Fixes the rotation being wrong when teleporting from a backwards portal --- .../stargate/container/BlockLocation.java | 5 ++--- .../stargate/listener/PlayerEventListener.java | 2 +- .../listener/VehicleEventListener.java | 4 ++-- .../net/knarcraft/stargate/portal/Portal.java | 18 ++++++++---------- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index 36f3386..0d7fcf3 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -102,13 +102,12 @@ public class BlockLocation extends Location { * @param depth

The amount of blocks to go downwards when looking the opposite direction from the yaw

* @param distance

The amount of blocks to go outwards when looking the opposite direction from the yaw

* @param portalYaw

The yaw when looking out from the portal

- * @param yaw

The yaw of the travelling entity

* @return A new location relative to this block location */ - public Location getRelativeLocation(double right, double depth, double distance, float portalYaw, float yaw) { + public Location getRelativeLocation(double right, double depth, double distance, float portalYaw) { Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(right, depth, distance, portalYaw); return makeRelativeLocation(0.5 + realVector.getBlockX(), realVector.getBlockY(), - 0.5 + realVector.getBlockZ(), yaw); + 0.5 + realVector.getBlockZ(), portalYaw); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 2e3d31d..6e55cc8 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -118,7 +118,7 @@ public class PlayerEventListener implements Listener { horse.setOwner(player); } } - destination.teleport((Vehicle) playerVehicle, entrancePortal); + destination.teleport((Vehicle) playerVehicle); } else { destination.teleport(player, entrancePortal, event); } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 4a69c13..3b01193 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -70,7 +70,7 @@ public class VehicleEventListener implements Listener { return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); - destinationPortal.teleport(vehicle, entrancePortal); + destinationPortal.teleport(vehicle); } } @@ -109,7 +109,7 @@ public class VehicleEventListener implements Listener { } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); - destinationPortal.teleport(vehicle, entrancePortal); + destinationPortal.teleport(vehicle); entrancePortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 8dc9afd..f4dc24a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -484,7 +484,7 @@ public class Portal { Location exit = getExit(player, traveller); //Rotate the player to face out from the portal - adjustRotation(exit, origin); + adjustRotation(exit); //Call the StargatePortalEvent to allow plugins to change destination if (!origin.equals(this)) { @@ -514,11 +514,10 @@ public class Portal { * Adjusts the rotation of the player to face out from the portal * * @param exit

The location the player will exit from

- * @param origin

The portal the player entered from

*/ - private void adjustRotation(Location exit, Portal origin) { + private void adjustRotation(Location exit) { int adjust = 0; - if (options.isBackwards() != origin.options.isBackwards()) { + if (options.isBackwards()) { adjust = 180; } float newYaw = (this.getYaw() + adjust) % 360; @@ -530,9 +529,8 @@ public class Portal { * Teleports a vehicle to this portal * * @param vehicle

The vehicle to teleport

- * @param origin

The portal the vehicle entered

*/ - public void teleport(final Vehicle vehicle, Portal origin) { + public void teleport(final Vehicle vehicle) { Location traveller = vehicle.getLocation(); Location exit = getExit(vehicle, traveller); @@ -544,7 +542,7 @@ public class Portal { //Get new velocity Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(this.getYaw()); Vector newVelocity = newVelocityDirection.multiply(velocity); - adjustRotation(exit, origin); + adjustRotation(exit); List passengers = vehicle.getPassengers(); @@ -632,11 +630,11 @@ public class Portal { RelativeBlockVector relativeExit = gate.getLayout().getExit(); if (relativeExit != null) { BlockLocation exit = getBlockAt(relativeExit); - float yaw = traveller.getYaw(); + float portalYaw = this.getYaw(); if (options.isBackwards()) { - yaw += 180; + portalYaw += 180; } - exitLocation = exit.getRelativeLocation(0D, 0D, 1, this.getYaw(), yaw); + exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); if (entity != null) { double entitySize = EntityHelper.getEntityMaxSize(entity); From 2fec641d9d5696b991a05cec679d599dcdbcf5de Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 8 Oct 2021 23:23:06 +0200 Subject: [PATCH 119/378] Fixes typos --- README.md | 14 +++++++------- .../stargate/event/StargateActivateEvent.java | 2 +- .../stargate/event/StargateDeactivateEvent.java | 2 +- .../stargate/listener/VehicleEventListener.java | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 922aea7..0b8d508 100644 --- a/README.md +++ b/README.md @@ -403,7 +403,7 @@ bungeeSign=Teleport to #### \[Version 0.7.9.2] - Remove my custom sign class. Stupid Bukkit team. -- Will work with CB 1.4.5 builds, but now will break randomly due to Bukkit screwup +- Will work with CB 1.4.5 builds, but now will break randomly due to Bukkit screw-up - Update MetricsLite to R6 #### \[Version 0.7.9.1] @@ -472,7 +472,7 @@ bungeeSign=Teleport to #### \[Version 0.7.6.6] -- Check move/portal/interact/signchange events for cancellation +- Check move/portal/interact/sign-change events for cancellation #### \[Version 0.7.6.5] @@ -651,7 +651,7 @@ bungeeSign=Teleport to #### \[Version 0.6.5] -- Moved printed message config to a seperate file +- Moved printed message config to a separate file - Added permdebug option - Hopefully fix path issues some people were having - Fixed iConomy creation cost @@ -702,12 +702,12 @@ bungeeSign=Teleport to - Updated the teleport method - Remove always-open gates from lists -- Hopefully stop Stargate and Nether interference +- Hopefully stop Stargate and Nether interferenceF #### \[Version 0.4.9] - Left-click to scroll signs up -- Show "(Not Connected)" on fixed-gates with a non-existant destination +- Show "(Not Connected)" on fixed-gates with a non-existent destination - Added "maxgates" option - Removed debug message - Started work on disabling damage for lava gates, too much work to finish with the current implementation of @@ -816,7 +816,7 @@ bungeeSign=Teleport to #### \[Version 0.25] -- Fixed a bug with worlds in subfolders +- Fixed a bug with worlds in sub-folders - Fixed gates being destroyed with explosions - Added stargate.destroy.owner @@ -844,7 +844,7 @@ bungeeSign=Teleport to #### \[Version 0.19] -- Set button facing on new gates, fixes weirdass button glitch +- Set button facing on new gates, fixes weird-ass button glitch - Beginning of very buggy multi-world support #### \[Version 0.18] diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index b169580..c15fa72 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -27,7 +27,7 @@ public class StargateActivateEvent extends StargatePlayerEvent { * @param destination

The chosen destination to activate

*/ public StargateActivateEvent(Portal portal, Player player, List destinations, String destination) { - super("StargatActivateEvent", portal, player); + super("StargateActivateEvent", portal, player); this.destinations = destinations; this.destination = destination; diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index 241b6ac..5b10dbe 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -19,7 +19,7 @@ public class StargateDeactivateEvent extends StargateEvent { * @param portal

The portal which was deactivated

*/ public StargateDeactivateEvent(Portal portal) { - super("StargatDeactivateEvent", portal); + super("StargateDeactivateEvent", portal); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 3b01193..72e838a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -60,13 +60,13 @@ public class VehicleEventListener implements Listener { */ private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - Stargate.logger.info(Stargate.getString("prefox") + "Found passenger vehicle"); + Stargate.logger.info(Stargate.getString("prefix") + "Found passenger vehicle"); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Stargate.logger.info(Stargate.getString("prefox") + "Found empty vehicle"); + Stargate.logger.info(Stargate.getString("prefix") + "Found empty vehicle"); Portal destinationPortal = entrancePortal.getDestination(); if (destinationPortal == null) { - Stargate.logger.warning(Stargate.getString("prefox") + "Unable to find portal destination"); + Stargate.logger.warning(Stargate.getString("prefix") + "Unable to find portal destination"); return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); From 336c3c4bfbb17cff39bb39c2d6434f07a1f61e06 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 03:02:00 +0200 Subject: [PATCH 120/378] Updates information about plugin settings --- README.md | 68 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 0b8d508..f2d7f84 100644 --- a/README.md +++ b/README.md @@ -137,10 +137,12 @@ while the per-gate costs re defined in the .gate files. To define a certain cost .gate file: ``` -usecost=5 -destroycost=5 -createcost=5 -toowner=true +economy: + useEconomy: true + createCost: 5 + destroyCost: 5 + useCost: 5 + toOwner: true ``` # Custom Gate Layout @@ -231,34 +233,44 @@ There is a default gate type for underwater gates. There are no real restriction normal buttons cannot be used since they'd fall off. Using wall coral fans work much better, though `CHEST` and `SHULKER_BOX` works too. -Using `AIR` for a closed underwater gate looks weird, so `WATER` might be better. +Using `AIR` for a closed underwater gate looks weird, so `WATER` might be better. If using `AIR` for the closed gate, +you need to make sure it actually contains air when creating it. +For partially submerged portals, like ones used for boat teleportation, you need to keep water away +from the portal entrance/opening until it's been created. # Configuration ``` -default-gate-network - The default gate network -portal-folder - The folder your portal databases are saved in -gate-folder - The folder containing your .gate files -destroyexplosion - Whether to destroy a stargate with explosions, or stop an explosion if it contains a gates controls. -useeconomy - Whether or not to use Economy -createcost - The cost to create a stargate -destroycost - The cost to destroy a stargate (Can be negative for a "refund" -usecost - The cost to use a stargate -chargefreedestination - Enable to allow free travel from any gate to a free gate -freegatesgreen - Enable to make gates that won't cost the player money show up as green -toowner - Whether the money from gate-use goes to the owner or nobody -maxgates - If non-zero, will define the maximum amount of gates allowed on any network. -chosenLanguage - The language to use (Included languages: en, de) -destMemory - Whether to set the first destination as the last used destination for all gates -ignoreEntrance - Set this option to true to not check the entrance of a gate on startup. This is a workaround for snowmen breaking gates. -handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. -sortLists - If true, network lists will be sorted alphabetically. -protectEntrance - If true, will protect from users breaking gate entrance blocks (This is more resource intensive than the usual check, and should only be enabled for servers that use solid open/close blocks) -signColor: This allows you to specify the color of the gate signs. Valid colors: -verifyPortals: Whether or not all the non-sign blocks are checked to match the gate layout when an old stargate is loaded at startup. - -debug: Whether to show massive debug output -permdebug: Whether to show massive permission debug output +language - The language to use (Included languages: en, de, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) +folders: + portalFolder - The folder your portal databases are saved in + gateFolder - The folder containing your .gate files +gates: + maxGatesEachNetwork - If non-zero, will define the maximum amount of gates allowed on any network. + defaultGateNetwork - The default gate network + cosmetic: + rememberDestination - Whether to set the first destination as the last used destination for all gates + sortNetworkDestinations - If true, network lists will be sorted alphabetically. + signColor - This allows you to specify the color of the gate signs. + integrity: + destroyedByExplosion - Whether to destroy a stargate with explosions, or stop an explosion if it contains a gates controls. + verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when an old stargate is loaded at startup. + protectEntrance - If true, will protect from users breaking gate entrance blocks (This is more resource intensive than the usual check, and should only be enabled for servers that use solid open/close blocks) + ignoreEntranceSet this option to true to not check the entrance of a gate on startup. This is a workaround for snowmen breaking gates. + functionality: + enableBungee - Enable this for BungeeCord support. This allows portals across Bungee servers. + handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. +economy: + useEconomy - Whether or not to use Economy + createCost - The cost to create a stargate + destroyCost - The cost to destroy a stargate (Can be negative for a "refund" + useCost - The cost to use a stargate + toOwner - Whether the money from gate-use goes to the owner or nobody + chargeFreeDestination - Enable to allow free travel from any gate to a free gate + freeGatesGreen - Enable to make gates that won't cost the player money show up as green +debugging: + debug - Whether to show massive debug output + permissionDebug - Whether to show massive permission debug output ``` # Message Customization From f87ffc906cfc325a4bea4241aaa93eef1d9babaa Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 03:57:24 +0200 Subject: [PATCH 121/378] Minor comment and formatting cleanup --- README.md | 15 +++++++-------- .../net/knarcraft/stargate/LanguageLoader.java | 1 - .../java/net/knarcraft/stargate/Stargate.java | 10 ++++++---- .../stargate/listener/PortalEventListener.java | 4 ++++ .../java/net/knarcraft/stargate/portal/Gate.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 2 +- .../knarcraft/stargate/portal/PortalOption.java | 3 +++ .../knarcraft/stargate/thread/StarGateThread.java | 6 +++--- 8 files changed, 25 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index f2d7f84..b1d13c4 100644 --- a/README.md +++ b/README.md @@ -234,9 +234,8 @@ normal buttons cannot be used since they'd fall off. Using wall coral fans work `SHULKER_BOX` works too. Using `AIR` for a closed underwater gate looks weird, so `WATER` might be better. If using `AIR` for the closed gate, -you need to make sure it actually contains air when creating it. -For partially submerged portals, like ones used for boat teleportation, you need to keep water away -from the portal entrance/opening until it's been created. +you need to make sure it actually contains air when creating it. For partially submerged portals, like ones used for +boat teleportation, you need to keep water away from the portal entrance/opening until it's been created. # Configuration @@ -278,9 +277,9 @@ debugging: It is possible to customize all the messages Stargate displays, including the [Stargate] prefix. You can find the strings in plugins/Stargate/lang/chosenLanguage.txt. -If a string is removed, or left blank, it will default to the default english string. There are some special cases -regarding messages. When you see %variableName%, you need to keep this part in your string, as it will be replaced -with relevant values. +If a string is removed, or left blank, it will default to the default english string. There are some special cases +regarding messages. When you see %variableName%, you need to keep this part in your string, as it will be replaced with +relevant values. The full list of strings is as follows: @@ -368,8 +367,8 @@ bungeeSign=Teleport to #### \[Version 0.8.0.0] PseudoKnight fork -- Update for 1.13/1.14 compatibility. This update changes gate layouts to use new material names instead of numeric ids. You - need to update your gate layout configs. +- Update for 1.13/1.14 compatibility. This update changes gate layouts to use new material names instead of numeric ids. + You need to update your gate layout configs. - Adds "verifyPortals" config option, which sets whether an old stargate's blocks are verified when loaded. - Adds UUID support. (falls back to player names) diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/LanguageLoader.java index edae036..b3b24d9 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/LanguageLoader.java @@ -16,7 +16,6 @@ import java.util.Set; */ public class LanguageLoader { - // Variables private final String languageFolder; private final Map loadedBackupStrings; private String chosenLanguage; diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 741b1f0..a187dd1 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -73,11 +73,11 @@ public class Stargate extends JavaPlugin { private String dataFolderPath; public static ChatColor signColor; - // Used for debug + //Used for debug public static boolean debuggingEnabled = false; public static boolean permissionDebuggingEnabled = false; - // HashMap of player names for Bungee support + //HashMap of player names for Bungee support public static final Map bungeeQueue = new HashMap<>(); //World names that contain stargates public static final HashSet managedWorlds = new HashSet<>(); @@ -189,7 +189,9 @@ public class Stargate extends JavaPlugin { * @param error

Whether the message sent is an error

*/ private static void sendMessage(CommandSender player, String message, boolean error) { - if (message.isEmpty()) return; + if (message.isEmpty()) { + return; + } //Replace color codes with green? What's the deal with the dollar sign? message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); if (error) { @@ -330,7 +332,7 @@ public class Stargate extends JavaPlugin { this.loadGates(); this.loadAllPortals(); - // Check to see if Economy is loaded yet. + //Check to see if Economy is loaded yet. setupVaultEconomy(); //Run necessary threads diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 8b54f8e..c4b2451 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -6,6 +6,9 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.PortalCreateEvent; +/** + * Listens for and cancels relevant portal events + */ public class PortalEventListener implements Listener { @EventHandler @@ -13,6 +16,7 @@ public class PortalEventListener implements Listener { if (event.isCancelled()) { return; } + //Cancel nether portal creation when the portal is a StarGate portal for (BlockState block : event.getBlocks()) { if (PortalHandler.getByBlock(block.getBlock()) != null) { event.setCancelled(true); diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 8fd74bd..e071b60 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -30,7 +30,7 @@ public class Gate { private final Material portalClosedBlock; private final Material portalButton; - // Economy information + //Economy information private final int useCost; private final int createCost; private final int destroyCost; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index f4dc24a..f48c60d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -513,7 +513,7 @@ public class Portal { /** * Adjusts the rotation of the player to face out from the portal * - * @param exit

The location the player will exit from

+ * @param exit

The location the player will exit from

*/ private void adjustRotation(Location exit) { int adjust = 0; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOption.java b/src/main/java/net/knarcraft/stargate/portal/PortalOption.java index e989aec..6b68418 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOption.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOption.java @@ -1,5 +1,8 @@ package net.knarcraft.stargate.portal; +/** + * Each enum value represents one option a portal can have/use + */ public enum PortalOption { /** diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 521b388..b869971 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -13,10 +13,10 @@ public class StarGateThread implements Runnable { @Override public void run() { long time = System.currentTimeMillis() / 1000; - // Close open portals + //Close open portals for (Iterator iterator = Stargate.openPortalsQueue.iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); - // Skip always open and non-open gates + //Skip always open and non-open gates if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) { continue; } @@ -25,7 +25,7 @@ public class StarGateThread implements Runnable { iterator.remove(); } } - // Deactivate active portals + //Deactivate active portals for (Iterator iterator = Stargate.activePortalsQueue.iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); if (!portal.isActive()) { From 051a6b8f98e54a8b015827d0e5fd128243364404 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 15:09:14 +0200 Subject: [PATCH 122/378] Removes the temporary ignoreEntrances option and replaces it with proper snowman blocking. Fixes #3 Allows new gates to contain water as underwater gates are a thing now Adds a check to prevent snowmen from placing snow inside a portal's entrance Removes the ignoreEntrances option everywhere --- README.md | 2 +- .../java/net/knarcraft/stargate/Stargate.java | 3 --- .../stargate/listener/BlockEventListener.java | 26 +++++++++++++++++-- .../net/knarcraft/stargate/portal/Gate.java | 7 ++--- .../stargate/portal/PortalHandler.java | 6 +++++ src/main/resources/config-migrations.txt | 3 ++- src/main/resources/config.yml | 2 -- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b1d13c4..6062e71 100644 --- a/README.md +++ b/README.md @@ -255,7 +255,6 @@ gates: destroyedByExplosion - Whether to destroy a stargate with explosions, or stop an explosion if it contains a gates controls. verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when an old stargate is loaded at startup. protectEntrance - If true, will protect from users breaking gate entrance blocks (This is more resource intensive than the usual check, and should only be enabled for servers that use solid open/close blocks) - ignoreEntranceSet this option to true to not check the entrance of a gate on startup. This is a workaround for snowmen breaking gates. functionality: enableBungee - Enable this for BungeeCord support. This allows portals across Bungee servers. handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. @@ -349,6 +348,7 @@ bungeeSign=Teleport to - Comments all the code - Extracts portal options and portal-related locations to try and reduce size - Rewrites tons of code to make it more readable and manageable +- Implements proper snowman snow blocking, and removes the "temporary" ignoreEntrances option #### \[Version 0.8.0.3] PseudoKnight fork diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index a187dd1..1fea40c 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -68,8 +68,6 @@ public class Stargate extends JavaPlugin { public static boolean enableBungee = true; public static boolean verifyPortals = true; private static boolean destroyExplosion = false; - //Temp workaround for snowmen, don't check gate entrance - public static boolean ignoreEntrance = false; private String dataFolderPath; public static ChatColor signColor; @@ -453,7 +451,6 @@ public class Stargate extends JavaPlugin { //Integrity protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); - ignoreEntrance = newConfig.getBoolean("gates.integrity.ignoreEntrance"); destroyExplosion = newConfig.getBoolean("gates.integrity.destroyedByExplosion"); //Cosmetic diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 63fa088..56955ab 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -12,6 +12,7 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Player; +import org.bukkit.entity.Snowman; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -21,6 +22,7 @@ import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPistonEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.EntityBlockFormEvent; import org.bukkit.event.block.SignChangeEvent; import java.util.List; @@ -31,6 +33,26 @@ import java.util.List; @SuppressWarnings("unused") public class BlockEventListener implements Listener { + /** + * Detects snowmen ruining portals + * + * @param event

The triggered event

+ */ + @EventHandler + public void onBlockFormedByEntity(EntityBlockFormEvent event) { + if (event.isCancelled() || (!Stargate.protectEntrance && !Stargate.verifyPortals)) { + return; + } + //We are only interested in snowman events + if (!(event.getEntity() instanceof Snowman)) { + return; + } + //Cancel the event if a snowman is trying to place snow in the portal's entrance + if (PortalHandler.getByEntrance(event.getBlock()) != null) { + event.setCancelled(true); + } + } + /** * Detects sign changes to detect if the user is creating a new gate * @@ -66,7 +88,7 @@ public class BlockEventListener implements Listener { */ @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled()) { + if (event.isCancelled() || !Stargate.protectEntrance) { return; } Block block = event.getBlock(); @@ -74,7 +96,7 @@ public class BlockEventListener implements Listener { //Decide if a portal is broken Portal portal = PortalHandler.getByBlock(block); - if (portal == null && Stargate.protectEntrance) { + if (portal == null) { portal = PortalHandler.getByEntrance(block); } if (portal == null) { diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index e071b60..92145b4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -214,16 +214,13 @@ public class Gate { * @return

Whether this is used in the context of creating a new gate

*/ private boolean verifyGateEntrancesMatch(BlockLocation topLeft, double yaw, boolean onCreate) { - if (Stargate.ignoreEntrance) { - return true; - } Stargate.debug("verifyGateEntrancesMatch", String.valueOf(topLeft)); for (RelativeBlockVector entranceVector : layout.getEntrances()) { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(entranceVector)); Material type = getBlockAt(topLeft, entranceVector, yaw).getType(); - //Ignore entrance if it's air, and we're creating a new gate - if (onCreate && type == Material.AIR) { + //Ignore entrance if it's air or water, and we're creating a new gate + if (onCreate && (type == Material.AIR || type == Material.WATER)) { continue; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index c11f5e1..3f9d947 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -52,6 +52,12 @@ public class PortalHandler { } + /** + * Gets names of all portals within a network + * + * @param network

The network to get portals from

+ * @return

A list of portal names

+ */ public static List getNetwork(String network) { return allPortalNetworks.get(network.toLowerCase()); } diff --git a/src/main/resources/config-migrations.txt b/src/main/resources/config-migrations.txt index eb53155..9326497 100644 --- a/src/main/resources/config-migrations.txt +++ b/src/main/resources/config-migrations.txt @@ -5,7 +5,8 @@ default-gate-network=gates.defaultGateNetwork destroyexplosion=gates.integrity.destroyedByExplosion maxgates=gates.maxGatesEachNetwork destMemory=gates.cosmetic.rememberDestination -ignoreEntrance=gates.integrity.ignoreEntrance +ignoreEntrance= +gates.integrity.ignoreEntrance= handleVehicles=gates.functionality.handleVehicles sortLists=gates.cosmetic.sortNetworkDestinations protectEntrance=gates.integrity.protectEntrance diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 22dd8a1..9c53803 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -8,7 +8,6 @@ # maxGatesEachNetwork - The maximum number of gates allowed on a network - 0 for unlimited # language - The language file to load for messages # rememberDestination - Whether to remember the cursor location between uses -# ignoreEntrance - Ignore the entrance blocks of a gate when checking. Used to work around snowmen # handleVehicles - Whether to allow vehicles through gates # sortNetworkDestinations - Whether to sort network lists alphabetically # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) @@ -45,7 +44,6 @@ gates: destroyedByExplosion: false verifyPortals: false protectEntrance: false - ignoreEntrance: false functionality: enableBungee: false handleVehicles: true From ba3304a71644c3b4d2ce4a59f0badbee336445ba Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 17:03:19 +0200 Subject: [PATCH 123/378] Fixes a minecart rotation bug caused by changing the rotation of the deleted vehicle instead of the new one --- .../net/knarcraft/stargate/portal/Portal.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index f48c60d..0f10221 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -499,13 +499,14 @@ public class Portal { exit = stargatePortalEvent.getExit(); } + //Load chunks to make sure not to teleport to the void loadChunks(); - // If no event is passed in, assume it's a teleport, and act as such + //If no event is passed in, assume it's a teleport, and act as such if (event == null) { player.teleport(exit); } else { - // The new method to teleport in a move event is set the "to" field. + //The new method to teleport in a move event is set the "to" field. event.setTo(exit); } } @@ -546,13 +547,15 @@ public class Portal { List passengers = vehicle.getPassengers(); + //Load chunks to make sure not to teleport to the void loadChunks(); if (!passengers.isEmpty()) { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { - Stargate.logger.warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); + Stargate.logger.warning(Stargate.getString("prefix") + + "Unable to get the world to teleport the vehicle to"); return; } putPassengersInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); @@ -593,7 +596,7 @@ public class Portal { Vehicle newVehicle = vehicleWorld.spawn(exit, vehicle.getClass()); vehicle.eject(); vehicle.remove(); - vehicle.setRotation(exit.getYaw(), exit.getPitch()); + newVehicle.setRotation(exit.getYaw(), exit.getPitch()); handleVehiclePassengers(passengers, newVehicle); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); @@ -643,7 +646,8 @@ public class Portal { } } } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + "Missing destination point in .gate file " + gate.getFilename()); } return adjustExitLocation(traveller, exitLocation); @@ -734,13 +738,15 @@ public class Portal { Stargate.debug("adjustExitLocation", "Added half a block to get above a slab"); exitLocation.add(0, 0.5, 0); } else if (blockData.getMaterial() == Material.WATER) { + //If there's water outside, go one up to allow for boat teleportation exitLocation.add(0, 1, 0); } exitLocation.setPitch(traveller.getPitch()); return exitLocation; } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + "Unable to generate exit location"); + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + "Unable to generate exit location"); } return traveller; } From be8de83bcca96e7b709629aa542b029ec5cb17a1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 18:48:59 +0200 Subject: [PATCH 124/378] Forces a teleported horse to become tamed --- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 6e55cc8..d9e6bb5 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -114,7 +114,9 @@ public class PlayerEventListener implements Listener { //Make sure the horse can be sat on if (playerVehicle instanceof AbstractHorse) { AbstractHorse horse = ((AbstractHorse) playerVehicle); + //Make sure the horse is properly tamed if (!horse.isTamed()) { + horse.setTamed(true); horse.setOwner(player); } } From 3a8943baefabdfa068099ab9f6d42d4e8cdfaf26 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 23:38:55 +0200 Subject: [PATCH 125/378] Configures the maven-compiler-plugin to also compile the source code as Java 16 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 285e6f9..33b927f 100644 --- a/pom.xml +++ b/pom.xml @@ -75,8 +75,8 @@ maven-compiler-plugin 3.6.1 - 1.8 - 1.8 + 16 + 16
From 7a9dbb804641c2dda42107cc3a5ef9e7f10abd89 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 9 Oct 2021 23:41:19 +0200 Subject: [PATCH 126/378] Implements some Java 14 code migrations --- .../java/net/knarcraft/stargate/command/CommandReload.java | 3 +-- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 3 +-- src/main/java/net/knarcraft/stargate/portal/Portal.java | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index 79ba7fe..73cdf93 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -26,8 +26,7 @@ public class CommandReload implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - if (commandSender instanceof Player) { - Player player = (Player) commandSender; + if (commandSender instanceof Player player) { if (!player.hasPermission("stargate.reload")) { Stargate.sendErrorMessage(commandSender, "Permission Denied"); return true; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index d9e6bb5..9cfc4f3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -112,8 +112,7 @@ public class PlayerEventListener implements Listener { if (playerVehicle != null && !(playerVehicle instanceof Boat) && !(playerVehicle instanceof RideableMinecart)) { //Make sure the horse can be sat on - if (playerVehicle instanceof AbstractHorse) { - AbstractHorse horse = ((AbstractHorse) playerVehicle); + if (playerVehicle instanceof AbstractHorse horse) { //Make sure the horse is properly tamed if (!horse.isTamed()) { horse.setTamed(true); diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 0f10221..072dc7d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -980,14 +980,13 @@ public class Portal { */ public final void drawSign() { BlockState state = getSignLocation().getBlock().getState(); - if (!(state instanceof Sign)) { + if (!(state instanceof Sign sign)) { Stargate.logger.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); Stargate.debug("Portal::drawSign", "Block: " + getSignLocation().getBlock().getType() + " @ " + getSignLocation().getBlock().getLocation()); return; } - Sign sign = (Sign) state; SignHelper.drawSign(sign, this); } From 2abe10bcde59461c3b9dceee16f350f0d7eeadde Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 15:10:36 +0200 Subject: [PATCH 127/378] Improves the way chunks are loaded, and decreases the wait time before players are put into minecarts --- .../net/knarcraft/stargate/portal/Portal.java | 72 ++++++++++++------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 072dc7d..5e6a906 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -501,6 +501,8 @@ public class Portal { //Load chunks to make sure not to teleport to the void loadChunks(); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + this::unloadChunks, 4000); //If no event is passed in, assume it's a teleport, and act as such if (event == null) { @@ -549,6 +551,8 @@ public class Portal { //Load chunks to make sure not to teleport to the void loadChunks(); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + this::unloadChunks, 4000); if (!passengers.isEmpty()) { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { @@ -579,7 +583,7 @@ public class Portal { private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { vehicle.eject(); vehicle.teleport(exit); - handleVehiclePassengers(passengers, vehicle); + handleVehiclePassengers(passengers, vehicle, 6); } /** @@ -597,7 +601,7 @@ public class Portal { vehicle.eject(); vehicle.remove(); newVehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle); + handleVehiclePassengers(passengers, newVehicle, 1); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); } @@ -607,8 +611,9 @@ public class Portal { * * @param passengers

The passengers to handle

* @param targetVehicle

The vehicle the passengers should be put into

+ * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

*/ - private void handleVehiclePassengers(List passengers, Vehicle targetVehicle) { + private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, long delay) { for (Entity passenger : passengers) { passenger.eject(); //TODO: Fix random java.lang.IllegalStateException: Removing entity while ticking! @@ -616,7 +621,11 @@ public class Portal { Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); } Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> targetVehicle.addPassenger(passenger), 6); + () -> { + if (!targetVehicle.addPassenger(passenger)) { + Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); + } + }, delay); } } @@ -752,36 +761,47 @@ public class Portal { } /** - * Loads the chunks at the portal's corners + * Unloads the chunks outside the portal's entrance */ - public void loadChunks() { - for (RelativeBlockVector vector : gate.getLayout().getCorners()) { - Chunk chunk = getBlockAt(vector).getChunk(); - - //Get the chunk in front of the gate corner - Location cornerLocation = getBlockAt(vector).getLocation(); - int blockOffset = options.isBackwards() ? -5 : 5; - Location fiveBlocksForward = DirectionHelper.moveLocation(cornerLocation, 0, 0, blockOffset, - getYaw()); - Chunk forwardChunk = fiveBlocksForward.getChunk(); - - //Load the chunks - loadOneChunk(chunk); - loadOneChunk(forwardChunk); + private void unloadChunks() { + for (Chunk chunk : getChunksToLoad()) { + chunk.removePluginChunkTicket(Stargate.stargate); } } /** - * Loads one chunk - * - * @param chunk

The chunk to load

+ * Loads the chunks outside the portal's entrance */ - private void loadOneChunk(Chunk chunk) { - if (!getWorld().isChunkLoaded(chunk)) { - if (!chunk.load()) { - Stargate.debug("loadChunks", "Failed to load chunk " + chunk); + private void loadChunks() { + for (Chunk chunk : getChunksToLoad()) { + chunk.addPluginChunkTicket(Stargate.stargate); + } + } + + /** + * Gets all relevant chunks near this portal's entrance which need to be loaded before teleportation + * + * @return

A list of chunks to load

+ */ + private List getChunksToLoad() { + List chunksToLoad = new ArrayList<>(); + for (RelativeBlockVector vector : gate.getLayout().getEntrances()) { + BlockLocation entranceLocation = getBlockAt(vector); + Chunk chunk = entranceLocation.getChunk(); + if (!chunksToLoad.contains(chunk)) { + chunksToLoad.add(chunk); + } + + //Get the chunk in front of the gate corner + int blockOffset = options.isBackwards() ? -5 : 5; + Location fiveBlocksForward = DirectionHelper.moveLocation(entranceLocation, 0, 0, blockOffset, + getYaw()); + Chunk forwardChunk = fiveBlocksForward.getChunk(); + if (!chunksToLoad.contains(forwardChunk)) { + chunksToLoad.add(forwardChunk); } } + return chunksToLoad; } /** From 6ad7fa4cb90ed2cb84002642041aaedb87c28e4b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 16:14:51 +0200 Subject: [PATCH 128/378] Removes the IllegalStateException Removing entity while ticking! TODO as it seems to have been fixed by preventing portal creation --- src/main/java/net/knarcraft/stargate/portal/Portal.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 5e6a906..aac8532 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -616,7 +616,6 @@ public class Portal { private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, long delay) { for (Entity passenger : passengers) { passenger.eject(); - //TODO: Fix random java.lang.IllegalStateException: Removing entity while ticking! if (!passenger.teleport(targetVehicle.getLocation())) { Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); } From b84700261704237b25750edcfcfeb0343f950241 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 17:15:00 +0200 Subject: [PATCH 129/378] Adds some small changes which seem to completely fix all horse teleportation bugs. Fixes #1 --- .../net/knarcraft/stargate/portal/Portal.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index aac8532..e656c9e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -583,7 +583,7 @@ public class Portal { private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { vehicle.eject(); vehicle.teleport(exit); - handleVehiclePassengers(passengers, vehicle, 6); + handleVehiclePassengers(passengers, vehicle, 2); } /** @@ -616,15 +616,26 @@ public class Portal { private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, long delay) { for (Entity passenger : passengers) { passenger.eject(); - if (!passenger.teleport(targetVehicle.getLocation())) { - Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); - } Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> { - if (!targetVehicle.addPassenger(passenger)) { - Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); - } - }, delay); + () -> teleportAndAddPassenger(targetVehicle, passenger), delay); + } + } + + /** + * Teleports and adds a passenger to a vehicle + * + *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, + * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

+ * + * @param targetVehicle

The vehicle to add the passenger to

+ * @param passenger

The passenger to teleport and add

+ */ + private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { + if (!passenger.teleport(targetVehicle.getLocation())) { + Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); + } + if (!targetVehicle.addPassenger(passenger)) { + Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); } } From 69a62c921c400051daccc206181677557cf3b5f7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 17:21:19 +0200 Subject: [PATCH 130/378] Fixes the color inconsistency for the portal selection "arrows" for gates with colored names --- .../java/net/knarcraft/stargate/utility/SignHelper.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index 2bcfc0e..feaf8ba 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -82,9 +82,11 @@ public final class SignHelper { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + portal.getDestinationName() + "<"); + Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + + portal.getDestinationName() + (green ? ChatColor.DARK_GREEN : "") + "<"); } else { - Stargate.setLine(sign, signLineIndex, " >" + portal.getDestinationName() + "< "); + Stargate.setLine(sign, signLineIndex, ChatColor.BLACK + " >" + portal.getDestinationName() + + ChatColor.BLACK + "< "); } } From 38ea543b80111899f6f17b198dff6e5ccb9b7e1f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 22:33:30 +0200 Subject: [PATCH 131/378] Improves chunk unloading Adds all chunk unloading to a queue Adds a thread which unloads chunks Updates chunk unload requests such that a chunk won't be unloaded twice, and an old unloading request cannot unload a chunk too soon --- .../java/net/knarcraft/stargate/Stargate.java | 30 ++++++++++- .../container/ChunkUnloadRequest.java | 54 +++++++++++++++++++ .../net/knarcraft/stargate/portal/Portal.java | 19 ++----- .../stargate/thread/ChunkUnloadThread.java | 36 +++++++++++++ 4 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java create mode 100644 src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 1fea40c..dfb3ea7 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.container.BlockChangeRequest; +import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; @@ -15,6 +16,7 @@ import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.thread.BlockChangeThread; +import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.FileHelper; @@ -31,6 +33,7 @@ import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.scheduler.BukkitScheduler; import java.io.File; import java.io.IOException; @@ -38,6 +41,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; +import java.util.PriorityQueue; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; @@ -50,6 +54,7 @@ public class Stargate extends JavaPlugin { public static final Queue blockChangeRequestQueue = new LinkedList<>(); public static final ConcurrentLinkedQueue openPortalsQueue = new ConcurrentLinkedQueue<>(); public static final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); + public static final Queue chunkUnloadQueue = new PriorityQueue<>(); //Amount of seconds before deactivating/closing portals private static final int activeTime = 10; @@ -334,8 +339,10 @@ public class Stargate extends JavaPlugin { setupVaultEconomy(); //Run necessary threads - getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L); - getServer().getScheduler().runTaskTimer(this, new BlockChangeThread(), 0L, 1L); + BukkitScheduler scheduler = getServer().getScheduler(); + scheduler.runTaskTimer(this, new StarGateThread(), 0L, 100L); + scheduler.runTaskTimer(this, new BlockChangeThread(), 0L, 1L); + scheduler.runTaskTimer(this, new ChunkUnloadThread(), 0L, 100L); this.registerCommands(); } @@ -615,4 +622,23 @@ public class Stargate extends JavaPlugin { } } + /** + * Gets the chunk unload queue containing chunks to unload + * + * @return

The chunk unload queue

+ */ + public static Queue getChunkUnloadQueue() { + return chunkUnloadQueue; + } + + /** + * Adds a new chunk unload request to the chunk unload queue + * + * @param request

The new chunk unload request to add

+ */ + public static void addChunkUnloadRequest(ChunkUnloadRequest request) { + chunkUnloadQueue.removeIf((item) -> item.getChunkToUnload().equals(request.getChunkToUnload())); + chunkUnloadQueue.add(request); + } + } diff --git a/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java b/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java new file mode 100644 index 0000000..a2657ca --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java @@ -0,0 +1,54 @@ +package net.knarcraft.stargate.container; + +import org.bukkit.Chunk; +import org.jetbrains.annotations.NotNull; + +/** + * Requests the unloading of a chunk which has been previously loaded by the Stargate plugin + */ +public class ChunkUnloadRequest implements Comparable { + + private final Long unloadNanoTime; + private final Chunk chunkToUnload; + + /** + * Instantiates a new chunk unloading request + * + * @param chunkToUnload

The chunk to request the unloading of

+ * @param timeUntilUnload

The time in milliseconds to wait before unloading the chunk

+ */ + public ChunkUnloadRequest(Chunk chunkToUnload, Long timeUntilUnload) { + this.chunkToUnload = chunkToUnload; + long systemNanoTime = System.nanoTime(); + this.unloadNanoTime = systemNanoTime + (timeUntilUnload * 1000000); + } + + /** + * Gets the chunk to unload + * + * @return

The chunk to unload

+ */ + public Chunk getChunkToUnload() { + return this.chunkToUnload; + } + + /** + * Gets the time system nano time denoting at which time the unload request should be executed + * + * @return

The system nano time denoting when the chunk is to be unloaded

+ */ + public Long getUnloadNanoTime() { + return this.unloadNanoTime; + } + + @Override + public String toString() { + return "{" + chunkToUnload + ", " + unloadNanoTime + "}"; + } + + @Override + public int compareTo(@NotNull ChunkUnloadRequest otherRequest) { + return unloadNanoTime.compareTo(otherRequest.unloadNanoTime); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index e656c9e..2f476c8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; @@ -501,8 +502,6 @@ public class Portal { //Load chunks to make sure not to teleport to the void loadChunks(); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - this::unloadChunks, 4000); //If no event is passed in, assume it's a teleport, and act as such if (event == null) { @@ -551,8 +550,6 @@ public class Portal { //Load chunks to make sure not to teleport to the void loadChunks(); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - this::unloadChunks, 4000); if (!passengers.isEmpty()) { if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { @@ -628,7 +625,7 @@ public class Portal { * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

* * @param targetVehicle

The vehicle to add the passenger to

- * @param passenger

The passenger to teleport and add

+ * @param passenger

The passenger to teleport and add

*/ private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { if (!passenger.teleport(targetVehicle.getLocation())) { @@ -770,21 +767,15 @@ public class Portal { return traveller; } - /** - * Unloads the chunks outside the portal's entrance - */ - private void unloadChunks() { - for (Chunk chunk : getChunksToLoad()) { - chunk.removePluginChunkTicket(Stargate.stargate); - } - } - /** * Loads the chunks outside the portal's entrance */ private void loadChunks() { for (Chunk chunk : getChunksToLoad()) { chunk.addPluginChunkTicket(Stargate.stargate); + //Allow the chunk to unload after 3 seconds + Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); + Stargate.debug("loadChunks", "Added chunk unloading request for chunk " + chunk); } } diff --git a/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java b/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java new file mode 100644 index 0000000..49f0757 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java @@ -0,0 +1,36 @@ +package net.knarcraft.stargate.thread; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.ChunkUnloadRequest; +import org.bukkit.Chunk; + +import java.util.Queue; + +/** + * Unloads chunks which should no longer be forced to stay loaded + */ +public class ChunkUnloadThread implements Runnable { + + @Override + public void run() { + long systemNanoTime = System.nanoTime(); + Queue unloadQueue = Stargate.getChunkUnloadQueue(); + + //Peek at the first element to check if the chunk should be unloaded + ChunkUnloadRequest firstElement = unloadQueue.peek(); + if (firstElement != null) { + Stargate.debug("ChunkUnloadThread", "Found chunk unload request: " + firstElement); + Stargate.debug("ChunkUnloadThread", "Current time: " + systemNanoTime); + } + //Repeat until all un-loadable chunks have been processed + while (firstElement != null && firstElement.getUnloadNanoTime() < systemNanoTime) { + unloadQueue.remove(); + Chunk chunkToUnload = firstElement.getChunkToUnload(); + //Allow the chunk to be unloaded + chunkToUnload.removePluginChunkTicket(Stargate.stargate); + Stargate.debug("ChunkUnloadThread", "Unloaded chunk " + chunkToUnload); + firstElement = unloadQueue.peek(); + } + } + +} From 964eb0f8983d9cb78f0acdd25c73772e18b24f16 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 23:03:39 +0200 Subject: [PATCH 132/378] Adds a new The End- inspired gate for more default diversity --- .../net/knarcraft/stargate/portal/GateHandler.java | 1 + src/main/resources/gates/endgate.gate | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/main/resources/gates/endgate.gate diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index b85f77c..7139d26 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -400,6 +400,7 @@ public class GateHandler { private static void populateDefaults(String gateFolder) { loadGateFromJar("nethergate.gate", gateFolder); loadGateFromJar("watergate.gate", gateFolder); + loadGateFromJar("endgate.gate", gateFolder); } /** diff --git a/src/main/resources/gates/endgate.gate b/src/main/resources/gates/endgate.gate new file mode 100644 index 0000000..a2d1687 --- /dev/null +++ b/src/main/resources/gates/endgate.gate @@ -0,0 +1,12 @@ +portal-open=END_GATEWAY +portal-closed=AIR +button=BIRCH_BUTTON +toowner=false +X=END_STONE_BRICKS +-=END_STONE_BRICKS + + XX +X..X +-..- +X*.X + XX From f8fae1fbf15e17dee9a70c0cbe3a96f334b5484a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 23:11:52 +0200 Subject: [PATCH 133/378] Makes sure to ignore mounted players if handleVehicles is disabled --- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 9cfc4f3..55d30f4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -110,6 +110,9 @@ public class PlayerEventListener implements Listener { //Teleport the vehicle to the player Entity playerVehicle = player.getVehicle(); if (playerVehicle != null && !(playerVehicle instanceof Boat) && !(playerVehicle instanceof RideableMinecart)) { + if (!Stargate.handleVehicles) { + return; + } //Make sure the horse can be sat on if (playerVehicle instanceof AbstractHorse horse) { From 2e4d545955dc69109ab1af89b4d5a26a9f1f0f8e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 23:17:29 +0200 Subject: [PATCH 134/378] Changes the vehicle check to prevent players in boats from leaving their boat to teleport --- .../knarcraft/stargate/listener/PlayerEventListener.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 55d30f4..bdab69a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -109,11 +109,10 @@ public class PlayerEventListener implements Listener { //Teleport the vehicle to the player Entity playerVehicle = player.getVehicle(); + if (playerVehicle != null && !Stargate.handleVehicles) { + return; + } if (playerVehicle != null && !(playerVehicle instanceof Boat) && !(playerVehicle instanceof RideableMinecart)) { - if (!Stargate.handleVehicles) { - return; - } - //Make sure the horse can be sat on if (playerVehicle instanceof AbstractHorse horse) { //Make sure the horse is properly tamed From 05123d54bd29820053c1802b2c13e9026f999bc8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 10 Oct 2021 23:38:20 +0200 Subject: [PATCH 135/378] Generifies the check for non-living vehicles just in case --- .../java/net/knarcraft/stargate/portal/Portal.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 2f476c8..7df9f4e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -25,11 +25,10 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Orientable; import org.bukkit.block.data.type.Slab; import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; -import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.util.Vector; @@ -552,7 +551,7 @@ public class Portal { loadChunks(); if (!passengers.isEmpty()) { - if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) { + if (!(vehicle instanceof LivingEntity)) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { Stargate.logger.warning(Stargate.getString("prefix") + @@ -584,7 +583,11 @@ public class Portal { } /** - * Creates a new vehicle equal to the player's previous vehicle and + * Creates a new vehicle equal to the player's previous vehicle and puts any passengers inside + * + *

While it is possible to teleport boats and minecarts using the same methods as "teleportLivingVehicle", this + * method works better with CraftBook with minecart options enabled. Using normal teleportation, CraftBook destroys + * the minecart once the player is ejected, causing the minecart to disappear and the player to teleport without it.

* * @param vehicle

The player's old vehicle

* @param passengers

A list of all passengers in the vehicle

From 1bf9914c3993571b7dafb5f78636ac3f89026ace Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 11 Oct 2021 00:03:49 +0200 Subject: [PATCH 136/378] Generifies another vehicle check --- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index bdab69a..f40b40d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -14,11 +14,10 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; -import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -112,7 +111,7 @@ public class PlayerEventListener implements Listener { if (playerVehicle != null && !Stargate.handleVehicles) { return; } - if (playerVehicle != null && !(playerVehicle instanceof Boat) && !(playerVehicle instanceof RideableMinecart)) { + if (playerVehicle instanceof LivingEntity) { //Make sure the horse can be sat on if (playerVehicle instanceof AbstractHorse horse) { //Make sure the horse is properly tamed From 9efc960696c19123ce25691e6120841d2af58361 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 11 Oct 2021 00:11:04 +0200 Subject: [PATCH 137/378] Makes sure to check entrance blocks when, and only when, protectEntrance is enabled --- .../stargate/listener/BlockEventListener.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 56955ab..5c19132 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -88,7 +88,7 @@ public class BlockEventListener implements Listener { */ @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled() || !Stargate.protectEntrance) { + if (event.isCancelled()) { return; } Block block = event.getBlock(); @@ -96,7 +96,7 @@ public class BlockEventListener implements Listener { //Decide if a portal is broken Portal portal = PortalHandler.getByBlock(block); - if (portal == null) { + if (portal == null && Stargate.protectEntrance) { portal = PortalHandler.getByEntrance(block); } if (portal == null) { @@ -104,11 +104,11 @@ public class BlockEventListener implements Listener { } boolean deny = false; - String denyMsg = ""; + String denyMessage = ""; //Decide if the user can destroy the portal if (!PermissionHelper.canDestroyPortal(player, portal)) { - denyMsg = Stargate.getString("denyMsg"); + denyMessage = Stargate.getString("denyMsg"); deny = true; Stargate.logger.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); } @@ -116,7 +116,7 @@ public class BlockEventListener implements Listener { int cost = EconomyHandler.getDestroyCost(player, portal.getGate()); //Create and call a StarGateDestroyEvent - StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMsg, cost); + StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMessage, cost); Stargate.server.getPluginManager().callEvent(destroyEvent); if (destroyEvent.isCancelled()) { event.setCancelled(true); From 06757ef9eee989baf2df860ddbc7a480c416bcd8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 11 Oct 2021 01:20:50 +0200 Subject: [PATCH 138/378] Removes debug output for chunk unloading --- src/main/java/net/knarcraft/stargate/portal/Portal.java | 1 - .../net/knarcraft/stargate/thread/ChunkUnloadThread.java | 5 ----- 2 files changed, 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 7df9f4e..77a4857 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -778,7 +778,6 @@ public class Portal { chunk.addPluginChunkTicket(Stargate.stargate); //Allow the chunk to unload after 3 seconds Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); - Stargate.debug("loadChunks", "Added chunk unloading request for chunk " + chunk); } } diff --git a/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java b/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java index 49f0757..2c89db9 100644 --- a/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java @@ -18,17 +18,12 @@ public class ChunkUnloadThread implements Runnable { //Peek at the first element to check if the chunk should be unloaded ChunkUnloadRequest firstElement = unloadQueue.peek(); - if (firstElement != null) { - Stargate.debug("ChunkUnloadThread", "Found chunk unload request: " + firstElement); - Stargate.debug("ChunkUnloadThread", "Current time: " + systemNanoTime); - } //Repeat until all un-loadable chunks have been processed while (firstElement != null && firstElement.getUnloadNanoTime() < systemNanoTime) { unloadQueue.remove(); Chunk chunkToUnload = firstElement.getChunkToUnload(); //Allow the chunk to be unloaded chunkToUnload.removePluginChunkTicket(Stargate.stargate); - Stargate.debug("ChunkUnloadThread", "Unloaded chunk " + chunkToUnload); firstElement = unloadQueue.peek(); } } From b0c350a14045eaba0837ccb842e4ff927c015bb4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 11 Oct 2021 01:35:12 +0200 Subject: [PATCH 139/378] Updates README to reflect vehicle teleportation capabilities --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6062e71..35be1ae 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ can share a network or be split into clusters; they can be hidden on a network o - Vault economy support -- can add costs for create, destroy and use. - Multiple custom gate configurations - Message customization +- Teleport across worlds or servers (BungeeCord supported) +- Vehicle teleportation -- teleport minecarts, boats, horses, pigs and striders ## Background @@ -341,14 +343,17 @@ bungeeSign=Teleport to - Splits a lot of the code into smaller objects - Moves duplicated code into helper classes - Re-implements vehicle teleportation -- Makes boat teleportation work as expected -- Makes it possible to teleport a player riding a pig or a horse +- Makes boat teleportation work as expected, including being able to teleport with two passengers. This allows players + to use boats to transport creatures through portals and to other areas, or even worlds +- Makes it possible to teleport a player riding a living entity (a pig, a horse, a donkey, a zombie horse, a skeleton + horse or a strider). It does not work for entities the player cannot control, such as llamas. - Makes both nether portals and end gateways work properly without causing mayhem - Replaces the modX and modZ stuff with yaw calculation to make it easier to understand - Comments all the code - Extracts portal options and portal-related locations to try and reduce size - Rewrites tons of code to make it more readable and manageable - Implements proper snowman snow blocking, and removes the "temporary" ignoreEntrances option +- Adds a default gate using end stone bricks and end gateway for more default diversity #### \[Version 0.8.0.3] PseudoKnight fork From 72c1b5a2390eaa24d76dadde625316377d78f277 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 11 Oct 2021 20:13:50 +0200 Subject: [PATCH 140/378] Updates About information --- .../net/knarcraft/stargate/command/CommandAbout.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 03312f8..1470f46 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -16,10 +16,15 @@ public class CommandAbout implements CommandExecutor { 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"); + ChatColor textColor = ChatColor.GOLD; + ChatColor highlightColor = ChatColor.GREEN; + commandSender.sendMessage(textColor + "Stargate Plugin originally created by " + highlightColor + + "Drakia" + textColor + ", and revived by " + highlightColor + "EpicKnarvik97"); + commandSender.sendMessage(textColor + "Go to " + highlightColor + + "https://git.knarcraft.net/EpicKnarvik97/Stargate " + textColor + "for the official repository"); String author = Stargate.languageLoader.getString("author"); if (!author.isEmpty()) - commandSender.sendMessage(ChatColor.GOLD + "Language created by " + ChatColor.GREEN + author); + commandSender.sendMessage(textColor + "Language created by " + highlightColor + author); return true; } From 51afa1527f026845e9f52f9b6a2ba7fd0c235df5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 11 Oct 2021 20:16:36 +0200 Subject: [PATCH 141/378] Updates the API version used as 1.16 is no longer the target version --- README.md | 4 ++-- .../java/net/knarcraft/stargate/command/CommandStarGate.java | 3 ++- src/main/resources/plugin.yml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 35be1ae..1d1a1d0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ can share a network or be split into clusters; they can be hidden on a network o This was originally TheDgtl's Bukkit port of the Stargate plugin for hMod by Dinnerbone. This is a fork of [PseudoKnight's fork](https://github.com/PseudoKnight/Stargate-Bukkit). This fork's main purpose is to create a clean -version of Stargate compliant with Spigot 1.16, even if it means changing the entire project's previous structure. +version of Stargate compliant with Spigot 1.17, even if it means changing the entire project's previous structure. # Permissions @@ -324,7 +324,7 @@ bungeeSign=Teleport to # Changes -#### \[Version 0.9.0.0] (WIP) EpicKnarvik97 fork +#### \[Version 0.9.0.0] EpicKnarvik97 fork - Changes entire path structure to a more modern and maven-compliant one - Changes package structure to net.knarcraft.stargate.* diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index e94fe6a..82939ec 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -37,7 +37,8 @@ public class CommandStarGate implements CommandExecutor { } return false; } else { - commandSender.sendMessage(ChatColor.GOLD + "Stargate version " + ChatColor.GREEN + Stargate.getPluginVersion()); + commandSender.sendMessage(ChatColor.GOLD + "Stargate version " + + ChatColor.GREEN + Stargate.getPluginVersion()); return true; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c52e5a1..39ff56a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,7 +5,7 @@ description: Stargate mod for Bukkit author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] website: https://knarcraft.net -api-version: 1.16 +api-version: 1.17 softdepend: [ Vault ] commands: stargate: From 53cd55938b955ad8b30186b4d830b9796e024fe8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 12 Oct 2021 01:11:52 +0200 Subject: [PATCH 142/378] Fixes teleportation of players using end portals to and from the end --- .../java/net/knarcraft/stargate/Stargate.java | 2 + .../listener/PlayerEventListener.java | 25 -------- .../listener/PortalEventListener.java | 63 +++++++++++++++++++ .../listener/TeleportEventListener.java | 36 +++++++++++ .../net/knarcraft/stargate/portal/Portal.java | 2 +- 5 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index dfb3ea7..460f9c1 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.listener.EntityEventListener; import net.knarcraft.stargate.listener.PlayerEventListener; import net.knarcraft.stargate.listener.PluginEventListener; import net.knarcraft.stargate.listener.PortalEventListener; +import net.knarcraft.stargate.listener.TeleportEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; import net.knarcraft.stargate.portal.GateHandler; @@ -359,6 +360,7 @@ public class Stargate extends JavaPlugin { pluginManager.registerEvents(new PortalEventListener(), this); pluginManager.registerEvents(new WorldEventListener(), this); pluginManager.registerEvents(new PluginEventListener(this), this); + pluginManager.registerEvents(new TeleportEventListener(), this); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index f40b40d..2b1ebbb 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -10,7 +10,6 @@ import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.GameMode; -import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.AbstractHorse; @@ -25,9 +24,6 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.util.Objects; /** * This listener listens to any player-related events related to stargates @@ -63,27 +59,6 @@ public class PlayerEventListener implements Listener { portal.teleport(player, portal, null); } - /** - * This event handler handles some special teleportation events - * - *

This event cancels nether portal and end gateway teleportation if the user teleported from a stargate - * entrance. This prevents the user from just teleporting to the nether with the default portal design. - * Additionally, this event teleports any vehicles not detected by the VehicleMove event together with the player.

- * - * @param event

The event to check and possibly cancel

- */ - @EventHandler - public void onPlayerTeleport(PlayerTeleportEvent event) { - // cancel portal and end gateway 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 == - Objects.requireNonNull(event.getFrom().getWorld()).getEnvironment()) - && PortalHandler.getByAdjacentEntrance(event.getFrom()) != null) { - event.setCancelled(true); - } - } - /** * This event handler detects if a player moves into a portal * diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index c4b2451..29e86ba 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -1,16 +1,35 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.container.TwoTuple; +import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.world.PortalCreateEvent; +import java.util.ArrayList; +import java.util.List; + /** * Listens for and cancels relevant portal events */ public class PortalEventListener implements Listener { + private static final List> playersFromTheEnd = new ArrayList<>(); + + /** + * Listen for and abort vanilla portal creation caused by stargate creation + * + * @param event

The triggered event

+ */ @EventHandler public void onPortalCreation(PortalCreateEvent event) { if (event.isCancelled()) { @@ -25,4 +44,48 @@ public class PortalEventListener implements Listener { } } + /** + * Listen for entities entering an artificial end portal + * + * @param event

The triggered event

+ */ + @EventHandler + public void onEntityPortalEnter(EntityPortalEnterEvent event) { + Location location = event.getLocation(); + World world = location.getWorld(); + Entity entity = event.getEntity(); + //Block normal portal teleportation if teleporting from a stargate + if (entity instanceof Player && location.getBlock().getType() == Material.END_PORTAL && world != null && + world.getEnvironment() == World.Environment.THE_END) { + Portal portal = PortalHandler.getByAdjacentEntrance(location); + if (portal != null) { + playersFromTheEnd.add(new TwoTuple<>((Player) entity, portal.getDestination())); + } + } + } + + /** + * Listen for the respawn event to catch players teleporting from the end in an artificial end portal + * + * @param event

The triggered event

+ */ + @EventHandler + public void onRespawn(PlayerRespawnEvent event) { + Player respawningPlayer = event.getPlayer(); + playersFromTheEnd.forEach((tuple) -> { + //Check if player is actually teleporting from the end + if (tuple.getFirstValue() == respawningPlayer) { + Portal exitPortal = tuple.getSecondValue(); + //Need to make sure the player is allowed to exit from the portal + if (!exitPortal.isOpenFor(respawningPlayer)) { + return; + } + //Overwrite respawn location to respawn in front of the portal + event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation())); + //Properly close the portal to prevent it from staying in a locked state until it times out + exitPortal.close(false); + } + }); + } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java b/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java new file mode 100644 index 0000000..f796c51 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java @@ -0,0 +1,36 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.portal.PortalHandler; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerTeleportEvent; + +/** + * This listener listens to teleportation-related events + */ +@SuppressWarnings("unused") +public class TeleportEventListener implements Listener { + + /** + * This event handler handles some special teleportation events + * + *

This event cancels nether portal and end gateway teleportation if the user teleported from a stargate + * entrance. This prevents the user from just teleporting to the nether with the default portal design. + * Additionally, this event teleports any vehicles not detected by the VehicleMove event together with the player.

+ * + * @param event

The event to check and possibly cancel

+ */ + @EventHandler + public void onPlayerTeleport(PlayerTeleportEvent event) { + PlayerTeleportEvent.TeleportCause cause = event.getCause(); + + //Block normal portal teleportation if teleporting from a stargate + if (!event.isCancelled() && (cause == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL || + cause == PlayerTeleportEvent.TeleportCause.END_GATEWAY || + cause == PlayerTeleportEvent.TeleportCause.END_PORTAL) + && PortalHandler.getByAdjacentEntrance(event.getFrom()) != null) { + event.setCancelled(true); + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 77a4857..6f315ef 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -646,7 +646,7 @@ public class Portal { * @param traveller

The location of the entity travelling

* @return

The location the entity should be teleported to.

*/ - private Location getExit(Entity entity, Location traveller) { + public Location getExit(Entity entity, Location traveller) { Location exitLocation = null; // Check if the gate has an exit block RelativeBlockVector relativeExit = gate.getLayout().getExit(); From e14007380f7baa68a796008657bc64de4e9e39da Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 12 Oct 2021 02:47:09 +0200 Subject: [PATCH 143/378] Adds proper checking and odd case catching before teleporting players through artificial end portals Adds a proper permission check to make sure players are allowed to teleport through the artificial portal Adds a teleportation back to the entrance as the teleportation event cannot be properly cancelled Adds a proper class for storing info about the teleportation --- .../container/FromTheEndTeleportation.java | 43 +++++++++++++++++ .../listener/PlayerEventListener.java | 47 +------------------ .../listener/PortalEventListener.java | 27 ++++++----- .../stargate/utility/PermissionHelper.java | 44 +++++++++++++++++ 4 files changed, 103 insertions(+), 58 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java diff --git a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java new file mode 100644 index 0000000..364dfff --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java @@ -0,0 +1,43 @@ +package net.knarcraft.stargate.container; + +import net.knarcraft.stargate.portal.Portal; +import org.bukkit.entity.Player; + +/** + * This class represents a player teleporting from the end to the over-world using an artificial end portal + */ +public class FromTheEndTeleportation { + + private final Player teleportingPlayer; + private final Portal exitPortal; + + /** + * Instantiates a new teleportation from the end + * + * @param teleportingPlayer

The teleporting player

+ * @param exitPortal

The portal to exit from

+ */ + public FromTheEndTeleportation(Player teleportingPlayer, Portal exitPortal) { + this.teleportingPlayer = teleportingPlayer; + this.exitPortal = exitPortal; + } + + /** + * Gets the teleporting player + * + * @return

The teleporting player

+ */ + public Player getPlayer() { + return this.teleportingPlayer; + } + + /** + * Gets the portal to exit from + * + * @return

The portal to exit from

+ */ + public Portal getExit() { + return this.exitPortal; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 2b1ebbb..8dcfbfc 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -5,8 +5,6 @@ import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.utility.BungeeHelper; -import net.knarcraft.stargate.utility.EconomyHandler; -import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.GameMode; @@ -127,7 +125,7 @@ public class PlayerEventListener implements Listener { Portal destination = entrancePortal.getDestination(player); //Decide if the anything stops the player from teleport - if (!playerCanTeleport(entrancePortal, destination, player, event)) { + if (PermissionHelper.playerCannotTeleport(entrancePortal, destination, player, event)) { return false; } @@ -322,47 +320,4 @@ public class PlayerEventListener implements Listener { return true; } - /** - * Decide of the player can teleport through a portal - * - * @param entrancePortal

The portal the player is entering from

- * @param destination

The destination of the portal the player is inside

- * @param player

The player wanting to teleport

- * @param event

The move event causing the teleportation

- * @return

True if the player can teleport. False otherwise

- */ - private boolean playerCanTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) { - // No portal or not open - if (entrancePortal == null || !entrancePortal.isOpen()) { - return false; - } - - // Not open for this player - if (!entrancePortal.isOpenFor(player)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.teleport(player, entrancePortal, event); - return false; - } - - //No destination - if (!entrancePortal.getOptions().isBungee() && destination == null) { - return false; - } - - //Player cannot access portal - if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.teleport(player, entrancePortal, event); - entrancePortal.close(false); - return false; - } - - //Player cannot pay for teleportation - int cost = EconomyHandler.getUseCost(player, entrancePortal, destination); - if (cost > 0) { - return EconomyHelper.payTeleportFee(entrancePortal, player, cost); - } - return true; - } - } diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 29e86ba..2932fe1 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -1,8 +1,9 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.container.TwoTuple; +import net.knarcraft.stargate.container.FromTheEndTeleportation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -23,7 +24,7 @@ import java.util.List; */ public class PortalEventListener implements Listener { - private static final List> playersFromTheEnd = new ArrayList<>(); + private static final List playersFromTheEnd = new ArrayList<>(); /** * Listen for and abort vanilla portal creation caused by stargate creation @@ -55,12 +56,18 @@ public class PortalEventListener implements Listener { World world = location.getWorld(); Entity entity = event.getEntity(); //Block normal portal teleportation if teleporting from a stargate - if (entity instanceof Player && location.getBlock().getType() == Material.END_PORTAL && world != null && + if (entity instanceof Player player && location.getBlock().getType() == Material.END_PORTAL && world != null && world.getEnvironment() == World.Environment.THE_END) { Portal portal = PortalHandler.getByAdjacentEntrance(location); - if (portal != null) { - playersFromTheEnd.add(new TwoTuple<>((Player) entity, portal.getDestination())); + + //Remove any old player teleportations in case weird things happen + playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player)); + //Decide if the anything stops the player from teleporting + if (PermissionHelper.playerCannotTeleport(portal, portal.getDestination(), player, null)) { + //Teleport the player back to the portal they came in, just in case + playersFromTheEnd.add(new FromTheEndTeleportation(player, portal)); } + playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getDestination())); } } @@ -72,14 +79,10 @@ public class PortalEventListener implements Listener { @EventHandler public void onRespawn(PlayerRespawnEvent event) { Player respawningPlayer = event.getPlayer(); - playersFromTheEnd.forEach((tuple) -> { + playersFromTheEnd.forEach((teleportation) -> { //Check if player is actually teleporting from the end - if (tuple.getFirstValue() == respawningPlayer) { - Portal exitPortal = tuple.getSecondValue(); - //Need to make sure the player is allowed to exit from the portal - if (!exitPortal.isOpenFor(respawningPlayer)) { - return; - } + if (teleportation.getPlayer() == respawningPlayer) { + Portal exitPortal = teleportation.getExit(); //Overwrite respawn location to respawn in front of the portal event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation())); //Properly close the portal to prevent it from staying in a locked state until it times out diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 588247a..3be876d 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalOption; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerMoveEvent; /** * Helper class for deciding which actions a player is allowed to perform @@ -368,4 +369,47 @@ public final class PermissionHelper { return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); } + /** + * Decide of the player can teleport through a portal + * + * @param entrancePortal

The portal the player is entering from

+ * @param destination

The destination of the portal the player is inside

+ * @param player

The player wanting to teleport

+ * @param event

The move event causing the teleportation

+ * @return

True if the player cannot teleport. False otherwise

+ */ + public static boolean playerCannotTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) { + // No portal or not open + if (entrancePortal == null || !entrancePortal.isOpen()) { + return true; + } + + // Not open for this player + if (!entrancePortal.isOpenFor(player)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + entrancePortal.teleport(player, entrancePortal, event); + return true; + } + + //No destination + if (!entrancePortal.getOptions().isBungee() && destination == null) { + return true; + } + + //Player cannot access portal + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + entrancePortal.teleport(player, entrancePortal, event); + entrancePortal.close(false); + return true; + } + + //Player cannot pay for teleportation + int cost = EconomyHandler.getUseCost(player, entrancePortal, destination); + if (cost > 0) { + return !EconomyHelper.payTeleportFee(entrancePortal, player, cost); + } + return false; + } + } From 0709c18e306c6543498e2b3e3e1f14796d358e9a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 12 Oct 2021 03:48:13 +0200 Subject: [PATCH 144/378] Adjusts height to get above slabs to an entire block as empty minecarts clipped through single slab layers --- src/main/java/net/knarcraft/stargate/portal/Portal.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 6f315ef..0a7a5e6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -750,14 +750,15 @@ public class Portal { */ private Location adjustExitLocation(Location traveller, Location exitLocation) { 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) || (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { - Stargate.debug("adjustExitLocation", "Added half a block to get above a slab"); - exitLocation.add(0, 0.5, 0); + //Prevent traveller from spawning inside a slab + Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); + exitLocation.add(0, 1, 0); } else if (blockData.getMaterial() == Material.WATER) { //If there's water outside, go one up to allow for boat teleportation + Stargate.debug("adjustExitLocation", "Added a block to get above a block of water"); exitLocation.add(0, 1, 0); } From 5b6e3f81a6e044410e01a879d047cf2ddb2684cd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 12 Oct 2021 04:18:58 +0200 Subject: [PATCH 145/378] Updates readme to mark end portals as functional --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d1a1d0..1321864 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ X*.X The keys `portal-open` and `portal-closed` are used to define the material in the gate when it is open or closed. The material for `portal-closed` can be most things, including solid blocks. Some materials may act weirdly though. The material for `portal-open` can be any block the player can partially enter, even things like `GLOW_LICHEN`. -`NETHER_PORTAL` and `END_GATEWAY` work, but `END_PORTAL` does not. +`NETHER_PORTAL`, `END_GATEWAY` and `END_PORTAL` all work. The key `button` is used to define the type of button that is generated for this gate. It can be a button (of any type), a type of wall coral (dead or alive), a type of shulker box or a chest. @@ -354,6 +354,7 @@ bungeeSign=Teleport to - Rewrites tons of code to make it more readable and manageable - Implements proper snowman snow blocking, and removes the "temporary" ignoreEntrances option - Adds a default gate using end stone bricks and end gateway for more default diversity +- Makes portals using end portal blocks work as expected #### \[Version 0.8.0.3] PseudoKnight fork From 4bdc5b6bd93e7567792e8de02b5027c8bb960c98 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 12 Oct 2021 20:41:45 +0200 Subject: [PATCH 146/378] Populates default gates after migrating config to update default gates for old installations --- src/main/java/net/knarcraft/stargate/Stargate.java | 11 ++++++++++- .../net/knarcraft/stargate/portal/GateHandler.java | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 460f9c1..c9e2b60 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -381,8 +381,12 @@ public class Stargate extends JavaPlugin { this.reloadConfig(); newConfig = this.getConfig(); - if (newConfig.getString("lang") != null) { + boolean isMigrating = false; + if (newConfig.getString("lang") != null || + newConfig.getString("gates.integrity.ignoreEntrance") != null || + newConfig.getString("ignoreEntrance") != null) { migrateConfig(newConfig); + isMigrating = true; } // Copy default values if required @@ -399,6 +403,11 @@ public class Stargate extends JavaPlugin { debuggingEnabled = newConfig.getBoolean("debugging.debug"); permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug"); + //If users have an outdated config, assume they also need to update their default gates + if (isMigrating) { + GateHandler.populateDefaults(gateFolder); + } + //Gates loadGateConfig(); diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 7139d26..8993150 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -397,7 +397,7 @@ public class GateHandler { * * @param gateFolder

The folder containing gate config files

*/ - private static void populateDefaults(String gateFolder) { + public static void populateDefaults(String gateFolder) { loadGateFromJar("nethergate.gate", gateFolder); loadGateFromJar("watergate.gate", gateFolder); loadGateFromJar("endgate.gate", gateFolder); From f16a7089f481acf05ebe3346899446492cd15af9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 13 Oct 2021 13:35:56 +0200 Subject: [PATCH 147/378] Updates the comments for BlockLocation --- .../stargate/container/BlockLocation.java | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index 0d7fcf3..1f552fb 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -7,8 +7,8 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.Sign; -import org.bukkit.block.data.type.WallSign; import org.bukkit.util.Vector; /** @@ -16,7 +16,7 @@ import org.bukkit.util.Vector; * *

The BlockLocation class is basically a Location with some extra functionality. * Warning: Because of differences in the equals methods between Location and BlockLocation, a BlockLocation which - * equals another BlockLocation does not necessarily equal the name BlockLocation if treated as a Location.

+ * equals another BlockLocation does not necessarily equal the same BlockLocation if treated as a Location.

*/ public class BlockLocation extends Location { @@ -35,19 +35,19 @@ public class BlockLocation extends Location { } /** - * Copies a craftbukkit block + * Creates a block location from a block * - * @param block

The block to

+ * @param block

The block to get the location of

*/ public BlockLocation(Block block) { super(block.getWorld(), block.getX(), block.getY(), block.getZ()); } /** - * Gets a block from a string + * Gets a block location from a string * * @param world

The world the block exists in

- * @param string

A comma separated list of z, y and z coordinates as integers

+ * @param string

A comma separated list of x, y and z coordinates as integers

*/ public BlockLocation(World world, String string) { super(world, Integer.parseInt(string.split(",")[0]), Integer.parseInt(string.split(",")[1]), @@ -55,11 +55,11 @@ public class BlockLocation extends Location { } /** - * Makes a new block in a relative position to this block + * Creates a new block location in a relative position to this block location * - * @param x

The x position relative to this block's position

- * @param y

The y position relative to this block's position

- * @param z

The z position relative to this block's position

+ * @param x

The number of blocks to move in the x-direction

+ * @param y

The number of blocks to move in the y-direction

+ * @param z

The number of blocks to move in the z-direction

* @return

A new block location

*/ public BlockLocation makeRelativeBlockLocation(int x, int y, int z) { @@ -67,12 +67,12 @@ public class BlockLocation extends Location { } /** - * Makes a location relative to the block location + * Creates a location in a relative position to this block location * - * @param x

The x position relative to this block's position

- * @param y

The y position relative to this block's position

+ * @param x

The number of blocks to move in the x-direction

+ * @param y

The number of blocks to move in the y-direction

* @param z

The z position relative to this block's position

- * @param yaw

The yaw of the location

+ * @param yaw

The number of blocks to move in the z-direction

* @return

A new location

*/ public Location makeRelativeLocation(double x, double y, double z, float yaw) { @@ -86,7 +86,7 @@ public class BlockLocation extends Location { * Gets a location relative to this block location * * @param relativeVector

The relative block vector describing the relative location

- * @param yaw

The yaw pointing in the distance direction

+ * @param yaw

The yaw pointing outwards from a portal (in the relative vector's distance direction)

* @return

A location relative to this location

*/ public BlockLocation getRelativeLocation(RelativeBlockVector relativeVector, double yaw) { @@ -98,9 +98,12 @@ public class BlockLocation extends Location { /** * Makes a location relative to the current location according to given parameters * - * @param right

The amount of blocks to go right when looking the opposite direction from the yaw

- * @param depth

The amount of blocks to go downwards when looking the opposite direction from the yaw

- * @param distance

The amount of blocks to go outwards when looking the opposite direction from the yaw

+ *

The distance goes in the direction of the yaw. Right goes in the direction of (yaw - 90) degrees. + * Depth goes downwards following the -y direction.

+ * + * @param right

The amount of blocks to go right when looking towards a portal

+ * @param depth

The amount of blocks to go downwards when looking towards a portal

+ * @param distance

The amount of blocks to go outwards when looking towards a portal

* @param portalYaw

The yaw when looking out from the portal

* @return A new location relative to this block location */ @@ -111,18 +114,18 @@ public class BlockLocation extends Location { } /** - * Gets the type for the block at this location + * Gets the type of block at this block location * - * @return

The block material type

+ * @return

The block's material type

*/ public Material getType() { return this.getBlock().getType(); } /** - * Sets the type for the block at this location + * Sets the type of block at this location * - * @param type

The new block material type

+ * @param type

The block's new material type

*/ public void setType(Material type) { this.getBlock().setType(type); @@ -140,6 +143,9 @@ public class BlockLocation extends Location { /** * Gets this block location's parent block * + *

The parent block is the block the item at this block location is attached to. Usually this is the block a + * sign or wall sign is attached to.

+ * * @return

This block location's parent block

*/ public Block getParent() { @@ -163,11 +169,13 @@ public class BlockLocation extends Location { int offsetZ = 0; BlockData blockData = getBlock().getBlockData(); - if (blockData instanceof WallSign) { - BlockFace facing = ((WallSign) blockData).getFacing().getOppositeFace(); + if (blockData instanceof Directional) { + //Get the offset of the block "behind" this block + BlockFace facing = ((Directional) blockData).getFacing().getOppositeFace(); offsetX = facing.getModX(); offsetZ = facing.getModZ(); } else if (blockData instanceof Sign) { + //Get offset the block beneath the sign offsetY = -1; } else { return; @@ -195,21 +203,23 @@ public class BlockLocation extends Location { } @Override - public boolean equals(Object obj) { - if (this == obj) { + public boolean equals(Object object) { + if (this == object) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (object == null || getClass() != object.getClass()) { return false; } - BlockLocation blockLocation = (BlockLocation) obj; + BlockLocation blockLocation = (BlockLocation) object; World thisWorld = this.getWorld(); World otherWorld = blockLocation.getWorld(); + //Check if the worlds of the two locations match boolean worldsEqual = (thisWorld == null && otherWorld == null) || ((thisWorld != null && otherWorld != null) && thisWorld == otherWorld); + //As this is a block location, only the block coordinates are compared return blockLocation.getBlockX() == this.getBlockX() && blockLocation.getBlockY() == this.getBlockY() && blockLocation.getBlockZ() == this.getBlockZ() && worldsEqual; } From 0ab6cb52c00bd38185bca7d111baeb84b6fee2b6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 13 Oct 2021 14:08:38 +0200 Subject: [PATCH 148/378] Makes some small comment adjustments --- .../stargate/container/ChunkUnloadRequest.java | 5 +++-- .../stargate/container/FromTheEndTeleportation.java | 4 ++++ .../stargate/container/RelativeBlockVector.java | 10 +++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java b/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java index a2657ca..4c47d15 100644 --- a/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java +++ b/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java @@ -4,7 +4,7 @@ import org.bukkit.Chunk; import org.jetbrains.annotations.NotNull; /** - * Requests the unloading of a chunk which has been previously loaded by the Stargate plugin + * Represents a requests for the unloading of a chunk which has been previously loaded by the Stargate plugin */ public class ChunkUnloadRequest implements Comparable { @@ -33,7 +33,7 @@ public class ChunkUnloadRequest implements Comparable { } /** - * Gets the time system nano time denoting at which time the unload request should be executed + * Gets the system nano time denoting at which time the unload request should be executed * * @return

The system nano time denoting when the chunk is to be unloaded

*/ @@ -48,6 +48,7 @@ public class ChunkUnloadRequest implements Comparable { @Override public int compareTo(@NotNull ChunkUnloadRequest otherRequest) { + //Prioritize requests based on time until unload return unloadNanoTime.compareTo(otherRequest.unloadNanoTime); } diff --git a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java index 364dfff..0da7d6e 100644 --- a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java +++ b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java @@ -5,6 +5,10 @@ import org.bukkit.entity.Player; /** * This class represents a player teleporting from the end to the over-world using an artificial end portal + * + *

This is necessary because a player entering an end portal in the end is a special case. Instead of being + * teleported, the player is respawned. Because of this, the teleportation needs to be saved and later used to hijack + * the position of where the player is to respawn.

*/ public class FromTheEndTeleportation { diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 8e02bb3..30b23de 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -32,8 +32,8 @@ public class RelativeBlockVector { /** * Adds a value to one of the properties of this relative block vector * - * @param propertyToAddTo

The property to change

- * @param valueToAdd

The value to add to the property

+ * @param propertyToAddTo

The property to add to

+ * @param valueToAdd

The value to add to the property (negative to move in the opposite direction)

* @return

A new relative block vector with the property altered

*/ public RelativeBlockVector addToVector(Property propertyToAddTo, int valueToAdd) { @@ -61,7 +61,7 @@ public class RelativeBlockVector { /** * Gets the distance to the right relative to the origin * - * @return The distance to the right relative to the origin + * @return

The distance to the right relative to the origin

*/ public int getRight() { return right; @@ -70,7 +70,7 @@ public class RelativeBlockVector { /** * Gets the distance downward relative to the origin * - * @return The distance downward relative to the origin + * @return

The distance downward relative to the origin

*/ public int getDepth() { return depth; @@ -79,7 +79,7 @@ public class RelativeBlockVector { /** * Gets the distance outward relative to the origin * - * @return The distance outward relative to the origin + * @return

The distance outward relative to the origin

*/ public int getDistance() { return distance; From bf7a10636e3adf3f6558e6bf58452382a3fb39c6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 13 Oct 2021 15:45:15 +0200 Subject: [PATCH 149/378] Improves comments for Stargate events, and adds a new event for teleporting entities Adds information about what events can be used for Tries to clarify event comments where possible Renames The StargatePortalEvent to StargatePlayerPortalEvent Adds StargateEntityPortalEvent Makes the StargateEntityPortalEvent trigger whenever a vehicle is teleported Removes the unused event name for all events --- .../stargate/event/StargateAccessEvent.java | 30 ++++--- .../stargate/event/StargateActivateEvent.java | 34 ++++---- .../stargate/event/StargateCloseEvent.java | 23 ++--- .../stargate/event/StargateCreateEvent.java | 22 ++--- .../event/StargateDeactivateEvent.java | 6 +- .../stargate/event/StargateDestroyEvent.java | 24 ++--- .../event/StargateEntityPortalEvent.java | 87 +++++++++++++++++++ .../stargate/event/StargateEvent.java | 3 +- .../stargate/event/StargateOpenEvent.java | 24 ++--- .../stargate/event/StargatePlayerEvent.java | 5 +- ...nt.java => StargatePlayerPortalEvent.java} | 32 +++---- .../listener/PlayerEventListener.java | 2 +- .../listener/VehicleEventListener.java | 4 +- .../net/knarcraft/stargate/portal/Portal.java | 31 +++++-- 14 files changed, 223 insertions(+), 104 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java rename src/main/java/net/knarcraft/stargate/event/{StargatePortalEvent.java => StargatePlayerPortalEvent.java} (79%) diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 8370b0e..843b3d6 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a player attempts to access a stargate + * + *

This event can be used to override whether the player should be allowed to access the stargate.

*/ @SuppressWarnings("unused") public class StargateAccessEvent extends StargatePlayerEvent { @@ -17,25 +19,16 @@ public class StargateAccessEvent extends StargatePlayerEvent { /** * Instantiates a new stargate access event * - * @param player

The player involved in the vent

+ * @param player

The player involved in the event

* @param portal

The portal involved in the event

- * @param deny

Whether the event should be denied

+ * @param deny

Whether the stargate access should be denied

*/ public StargateAccessEvent(Player player, Portal portal, boolean deny) { - super("StargateAccessEvent", portal, player); + super(portal, player); this.deny = deny; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets whether the player should be denied access * @@ -46,14 +39,23 @@ public class StargateAccessEvent extends StargatePlayerEvent { } /** - * Sets whether to deny the player + * Sets whether to deny access to the player * - * @param deny

Whether to deny the player

+ * @param deny

Whether to deny access to the player

*/ public void setDeny(boolean deny) { this.deny = deny; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index c15fa72..3d09661 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -9,7 +9,9 @@ import java.util.List; /** * This event should be called whenever a player activates a stargate - *

Activation of a stargate happens when a player right-clicks the sign of a stargate.

+ * + *

Activation of a stargate happens when a player right-clicks the sign of a stargate. + * This event can be used to overwrite the selected destination, and all destinations the player can see.

*/ @SuppressWarnings("unused") public class StargateActivateEvent extends StargatePlayerEvent { @@ -24,24 +26,15 @@ public class StargateActivateEvent extends StargatePlayerEvent { * @param portal

The activated portal

* @param player

The player activating the portal

* @param destinations

The destinations available to the player using the portal

- * @param destination

The chosen destination to activate

+ * @param destination

The currently selected destination

*/ public StargateActivateEvent(Portal portal, Player player, List destinations, String destination) { - super("StargateActivateEvent", portal, player); + super(portal, player); this.destinations = destinations; this.destination = destination; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets the destinations available for the portal * @@ -61,23 +54,32 @@ public class StargateActivateEvent extends StargatePlayerEvent { } /** - * Gets the chosen destination to activate + * Gets the selected destination * - * @return

The chosen destination to activate

+ * @return

The selected destination

*/ public String getDestination() { return destination; } /** - * Sets (changes) the chosen destination to activate + * Sets (changes) the selected destination * - * @param destination

The new destination to activate

+ * @param destination

The new selected destination

*/ public void setDestination(String destination) { this.destination = destination; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index 8306a92..3f2ff07 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -6,6 +6,9 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a stargate is closed + * + *

This event can be used to overwrite whether the stargate should be forced to close, even if it's set as + * always-on.

*/ @SuppressWarnings("unused") public class StargateCloseEvent extends StargateEvent { @@ -20,20 +23,11 @@ public class StargateCloseEvent extends StargateEvent { * @param force

Whether to force the gate to close, even if set as always-on

*/ public StargateCloseEvent(Portal portal, boolean force) { - super("StargateCloseEvent", portal); + super(portal); this.force = force; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets whether to force the stargate to close * @@ -52,6 +46,15 @@ public class StargateCloseEvent extends StargateEvent { this.force = force; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + @NotNull @Override public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java index a703a3b..1f66e60 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a stargate is created + * + *

This event can be used to deny or change the cost of a stargate creation.

*/ @SuppressWarnings("unused") public class StargateCreateEvent extends StargatePlayerEvent { @@ -28,22 +30,13 @@ public class StargateCreateEvent extends StargatePlayerEvent { * @param cost

The cost of creating the new star gate

*/ public StargateCreateEvent(Player player, Portal portal, String[] lines, boolean deny, String denyReason, int cost) { - super("StargateCreateEvent", portal, player); + super(portal, player); this.lines = lines; this.deny = deny; this.denyReason = denyReason; this.cost = cost; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets a given line from the sign creating the star gate * @@ -109,6 +102,15 @@ public class StargateCreateEvent extends StargatePlayerEvent { this.cost = cost; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + @NotNull @Override public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index 5b10dbe..3314ac1 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -6,7 +6,9 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a stargate is deactivated - *

A deactivation is usually caused by no activity for a set amount of time.

+ * + *

A deactivation is usually caused by no activity for a set amount of time. + * This event can only be used to listen for de-activation events.

*/ @SuppressWarnings("unused") public class StargateDeactivateEvent extends StargateEvent { @@ -19,7 +21,7 @@ public class StargateDeactivateEvent extends StargateEvent { * @param portal

The portal which was deactivated

*/ public StargateDeactivateEvent(Portal portal) { - super("StargateDeactivateEvent", portal); + super(portal); } /** diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index 5032036..84bc981 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull; /** * This event represents an event where a star gate is destroyed or attempted to be destroyed + * + *

This event can be used to deny or change the cost of a stargate destruction.

*/ @SuppressWarnings("unused") public class StargateDestroyEvent extends StargatePlayerEvent { @@ -19,28 +21,19 @@ public class StargateDestroyEvent extends StargatePlayerEvent { /** * Instantiates a new Stargate Destroy Event * - * @param portal

The portal destroyed

+ * @param portal

The destroyed portal

* @param player

The player destroying the portal

* @param deny

Whether the event should be denied (cancelled)

* @param denyMsg

The message to display if the event is denied

* @param cost

The cost of destroying the portal

*/ public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { - super("StargateDestroyEvent", portal, player); + super(portal, player); this.deny = deny; this.denyReason = denyMsg; this.cost = cost; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets whether this event should be denied * @@ -95,6 +88,15 @@ public class StargateDestroyEvent extends StargatePlayerEvent { this.cost = cost; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + @NotNull @Override public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java new file mode 100644 index 0000000..1b6fa95 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java @@ -0,0 +1,87 @@ +package net.knarcraft.stargate.event; + +import net.knarcraft.stargate.portal.Portal; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +/** + * This event should be called whenever a non-player teleports through a stargate + * + *

This event can be used to overwrite the location the entity is teleported to.

+ */ +@SuppressWarnings("unused") +public class StargateEntityPortalEvent extends StargateEvent { + + private static final HandlerList handlers = new HandlerList(); + Entity travellingEntity; + private final Portal destination; + private Location exit; + + /** + * Instantiates a new stargate portal event + * + * @param travellingEntity

The entity travelling through this portal

+ * @param portal

The portal the entity entered from

+ * @param destination

The destination the entity should exit from

+ * @param exit

The exit location of the destination portal the entity will be teleported to

+ */ + public StargateEntityPortalEvent(Entity travellingEntity, Portal portal, Portal destination, Location exit) { + super(portal); + + this.travellingEntity = travellingEntity; + this.destination = destination; + this.exit = exit; + } + + /** + * Return the non-player entity teleporting + * + * @return

The non-player teleporting

+ */ + public Entity getEntity() { + return travellingEntity; + } + + /** + * Return the destination portal + * + * @return

The destination portal

+ */ + public Portal getDestination() { + return destination; + } + + /** + * Return the location of the players exit point + * + * @return

Location of the exit point

+ */ + public Location getExit() { + return exit; + } + + /** + * Set the location of the entity's exit point + */ + public void setExit(Location location) { + this.exit = location; + } + + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + @NotNull + public HandlerList getHandlers() { + return handlers; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index 6584355..f67a388 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -16,10 +16,9 @@ public abstract class StargateEvent extends Event implements Cancellable { /** * Instantiates a new stargate event * - * @param event

UNUSED

* @param portal

The portal involved in this stargate event

*/ - StargateEvent(String event, Portal portal) { + StargateEvent(Portal portal) { this.portal = portal; this.cancelled = false; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index 1c7e649..ce10534 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a player opens a stargate + * + *

This event can be used to overwrite whether the stargate should be forced to open, even if it's already open.

*/ @SuppressWarnings({"unused"}) public class StargateOpenEvent extends StargatePlayerEvent { @@ -18,24 +20,15 @@ public class StargateOpenEvent extends StargatePlayerEvent { * Instantiates a new stargate open event * * @param player

The player opening the stargate

- * @param portal

The portal opened

+ * @param portal

The opened portal

* @param force

Whether to force the portal open

*/ public StargateOpenEvent(Player player, Portal portal, boolean force) { - super("StargateOpenEvent", portal, player); + super(portal, player); this.force = force; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets whether the portal should be forced open * @@ -54,6 +47,15 @@ public class StargateOpenEvent extends StargatePlayerEvent { this.force = force; } + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; + } + @Override @NotNull public HandlerList getHandlers() { diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java index a68db69..14514f6 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java @@ -14,11 +14,10 @@ public abstract class StargatePlayerEvent extends StargateEvent { /** * Instantiates a new stargate player event * - * @param event

UNUSED

* @param portal

The portal involved in this stargate event

*/ - StargatePlayerEvent(String event, Portal portal, Player player) { - super(event, portal); + StargatePlayerEvent(Portal portal, Player player) { + super(portal); this.player = player; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java similarity index 79% rename from src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java rename to src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java index 0f30913..95b6939 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java @@ -8,38 +8,31 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a player teleports through a stargate + * + *

This event can be used to overwrite the location the player is teleported to.

*/ @SuppressWarnings("unused") -public class StargatePortalEvent extends StargatePlayerEvent { +public class StargatePlayerPortalEvent extends StargatePlayerEvent { private static final HandlerList handlers = new HandlerList(); private final Portal destination; private Location exit; /** - * Instantiates a new stargate portal event + * Instantiates a new stargate player portal event * * @param player

The player teleporting

* @param portal

The portal the player entered from

* @param destination

The destination the player should exit from

* @param exit

The exit location of the destination portal the user will be teleported to

*/ - public StargatePortalEvent(Player player, Portal portal, Portal destination, Location exit) { - super("StargatePortalEvent", portal, player); + public StargatePlayerPortalEvent(Player player, Portal portal, Portal destination, Location exit) { + super(portal, player); this.destination = destination; this.exit = exit; } - /** - * Gets a handler-list containing all event handlers - * - * @return

A handler-list with all event handlers

- */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Return the destination portal * @@ -61,8 +54,17 @@ public class StargatePortalEvent extends StargatePlayerEvent { /** * Set the location of the player's exit point */ - public void setExit(Location loc) { - this.exit = loc; + public void setExit(Location location) { + this.exit = location; + } + + /** + * Gets a handler-list containing all event handlers + * + * @return

A handler-list with all event handlers

+ */ + public static HandlerList getHandlerList() { + return handlers; } @Override diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 8dcfbfc..e765e7f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -93,7 +93,7 @@ public class PlayerEventListener implements Listener { horse.setOwner(player); } } - destination.teleport((Vehicle) playerVehicle); + destination.teleport((Vehicle) playerVehicle, entrancePortal); } else { destination.teleport(player, entrancePortal, event); } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 72e838a..75211c3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -70,7 +70,7 @@ public class VehicleEventListener implements Listener { return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); - destinationPortal.teleport(vehicle); + destinationPortal.teleport(vehicle, entrancePortal); } } @@ -109,7 +109,7 @@ public class VehicleEventListener implements Listener { } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); - destinationPortal.teleport(vehicle); + destinationPortal.teleport(vehicle, entrancePortal); entrancePortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 0a7a5e6..ae9dfa5 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -8,8 +8,9 @@ import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; +import net.knarcraft.stargate.event.StargateEntityPortalEvent; import net.knarcraft.stargate.event.StargateOpenEvent; -import net.knarcraft.stargate.event.StargatePortalEvent; +import net.knarcraft.stargate.event.StargatePlayerPortalEvent; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.SignHelper; @@ -486,17 +487,18 @@ public class Portal { //Rotate the player to face out from the portal adjustRotation(exit); - //Call the StargatePortalEvent to allow plugins to change destination + //Call the StargatePlayerPortalEvent to allow plugins to change destination if (!origin.equals(this)) { - StargatePortalEvent stargatePortalEvent = new StargatePortalEvent(player, origin, this, exit); - Stargate.server.getPluginManager().callEvent(stargatePortalEvent); + StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, + this, exit); + Stargate.server.getPluginManager().callEvent(stargatePlayerPortalEvent); //Teleport is cancelled. Teleport the player back to where it came from - if (stargatePortalEvent.isCancelled()) { + if (stargatePlayerPortalEvent.isCancelled()) { origin.teleport(player, origin, event); return; } //Update exit if needed - exit = stargatePortalEvent.getExit(); + exit = stargatePlayerPortalEvent.getExit(); } //Load chunks to make sure not to teleport to the void @@ -530,8 +532,9 @@ public class Portal { * Teleports a vehicle to this portal * * @param vehicle

The vehicle to teleport

+ * @param origin

The portal the vehicle teleports from

*/ - public void teleport(final Vehicle vehicle) { + public void teleport(final Vehicle vehicle, Portal origin) { Location traveller = vehicle.getLocation(); Location exit = getExit(vehicle, traveller); @@ -547,6 +550,20 @@ public class Portal { List passengers = vehicle.getPassengers(); + //Call the StargateEntityPortalEvent to allow plugins to change destination + if (!origin.equals(this)) { + StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(vehicle, origin, + this, exit); + Stargate.server.getPluginManager().callEvent(stargateEntityPortalEvent); + //Teleport is cancelled. Teleport the entity back to where it came from + if (stargateEntityPortalEvent.isCancelled()) { + origin.teleport(vehicle, origin); + return; + } + //Update exit if needed + exit = stargateEntityPortalEvent.getExit(); + } + //Load chunks to make sure not to teleport to the void loadChunks(); From 44325eeb6adb6b1bc9f9fa48ff8afca97717bf6e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 13 Oct 2021 16:46:30 +0200 Subject: [PATCH 150/378] Improves and fixes comments for listeners Removes the enableBungee check in the BungeeCordListener as it should only be listening if the option is enabled anyway Improves the checking for players teleporting from the end --- .../container/FromTheEndTeleportation.java | 13 ++++++++++ .../stargate/listener/BlockEventListener.java | 5 +++- .../stargate/listener/BungeeCordListener.java | 9 ++++--- .../listener/EntityEventListener.java | 1 + .../listener/PlayerEventListener.java | 16 ++++++------ .../listener/PortalEventListener.java | 26 ++++++++++--------- .../listener/TeleportEventListener.java | 6 ++--- .../listener/VehicleEventListener.java | 3 ++- .../stargate/listener/WorldEventListener.java | 5 ++-- 9 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java index 0da7d6e..54c7171 100644 --- a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java +++ b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java @@ -44,4 +44,17 @@ public class FromTheEndTeleportation { return this.exitPortal; } + @Override + public int hashCode() { + return teleportingPlayer.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof FromTheEndTeleportation otherTeleportation)) { + return false; + } + return teleportingPlayer.equals(otherTeleportation.teleportingPlayer); + } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 5c19132..26da8b1 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -36,6 +36,9 @@ public class BlockEventListener implements Listener { /** * Detects snowmen ruining portals * + *

If entrance protection or portal verification is enabled, the snowman will be prevented from placing snow in + * the portal entrance.

+ * * @param event

The triggered event

*/ @EventHandler @@ -71,7 +74,7 @@ public class BlockEventListener implements Listener { } final Portal portal = PortalHandler.createPortal(event, player); - // Not creating a gate, just placing a sign + //Not creating a gate, just placing a sign if (portal == null) { return; } diff --git a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java index 0d58dda..2a7d2e1 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java @@ -1,6 +1,5 @@ package net.knarcraft.stargate.listener; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.BungeeHelper; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; @@ -16,7 +15,7 @@ import org.jetbrains.annotations.NotNull; public class BungeeCordListener implements PluginMessageListener { /** - * Receive a plugin message + * Receives plugin messages * * @param channel

The channel the message was received on

* @param unused

Unused.

@@ -24,16 +23,18 @@ public class BungeeCordListener implements PluginMessageListener { */ @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, byte[] message) { - //Ignore plugin messages if bungee support is not enabled or some other plugin message is received - if (!Stargate.enableBungee || !channel.equals("BungeeCord")) { + //Ignore plugin messages if some other plugin message is received + if (!channel.equals("BungeeCord")) { return; } + //Try to read the plugin message String receivedMessage = BungeeHelper.readPluginMessage(message); if (receivedMessage == null) { return; } + //Use the message to initiate teleportation BungeeHelper.handleTeleportMessage(receivedMessage); } diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 3c32226..f50c7e6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -30,6 +30,7 @@ public class EntityEventListener implements Listener { } Entity entity = event.getEntity(); + //Cancel normal portal event is near a stargate if (PortalHandler.getByAdjacentEntrance(event.getFrom(), EntityHelper.getEntityMaxSizeInt(entity)) != null) { event.setCancelled(true); } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index e765e7f..eabed16 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -44,6 +44,7 @@ public class PlayerEventListener implements Listener { } Player player = event.getPlayer(); + //Check if the player is waiting to be teleported to a stargate String destination = Stargate.bungeeQueue.remove(player.getName().toLowerCase()); if (destination == null) { return; @@ -54,6 +55,7 @@ public class PlayerEventListener implements Listener { Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination); return; } + //Teleport the player to the stargate portal.teleport(player, portal, null); } @@ -85,13 +87,10 @@ public class PlayerEventListener implements Listener { return; } if (playerVehicle instanceof LivingEntity) { - //Make sure the horse can be sat on - if (playerVehicle instanceof AbstractHorse horse) { - //Make sure the horse is properly tamed - if (!horse.isTamed()) { - horse.setTamed(true); - horse.setOwner(player); - } + //Make sure any horses are properly tamed + if (playerVehicle instanceof AbstractHorse horse && !horse.isTamed()) { + horse.setTamed(true); + horse.setOwner(player); } destination.teleport((Vehicle) playerVehicle, entrancePortal); } else { @@ -110,7 +109,8 @@ public class PlayerEventListener implements Listener { * @param toLocation

The location the player is moving to

* @return

True if the event is relevant

*/ - private boolean isRelevantMoveEvent(PlayerMoveEvent event, Player player, BlockLocation fromLocation, BlockLocation toLocation) { + private boolean isRelevantMoveEvent(PlayerMoveEvent event, Player player, BlockLocation fromLocation, + BlockLocation toLocation) { //Check to see if the player moved to another block if (fromLocation.equals(toLocation)) { return false; diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 2932fe1..6a63dcd 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -27,7 +27,7 @@ public class PortalEventListener implements Listener { private static final List playersFromTheEnd = new ArrayList<>(); /** - * Listen for and abort vanilla portal creation caused by stargate creation + * Listens for and aborts vanilla portal creation caused by stargate creation * * @param event

The triggered event

*/ @@ -55,7 +55,7 @@ public class PortalEventListener implements Listener { Location location = event.getLocation(); World world = location.getWorld(); Entity entity = event.getEntity(); - //Block normal portal teleportation if teleporting from a stargate + //Hijack normal portal teleportation if teleporting from a stargate if (entity instanceof Player player && location.getBlock().getType() == Material.END_PORTAL && world != null && world.getEnvironment() == World.Environment.THE_END) { Portal portal = PortalHandler.getByAdjacentEntrance(location); @@ -79,16 +79,18 @@ public class PortalEventListener implements Listener { @EventHandler public void onRespawn(PlayerRespawnEvent event) { Player respawningPlayer = event.getPlayer(); - playersFromTheEnd.forEach((teleportation) -> { - //Check if player is actually teleporting from the end - if (teleportation.getPlayer() == respawningPlayer) { - Portal exitPortal = teleportation.getExit(); - //Overwrite respawn location to respawn in front of the portal - event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation())); - //Properly close the portal to prevent it from staying in a locked state until it times out - exitPortal.close(false); - } - }); + int playerIndex = playersFromTheEnd.indexOf(new FromTheEndTeleportation(respawningPlayer, null)); + if (playerIndex == -1) { + return; + } + FromTheEndTeleportation teleportation = playersFromTheEnd.get(playerIndex); + playersFromTheEnd.remove(playerIndex); + + Portal exitPortal = teleportation.getExit(); + //Overwrite respawn location to respawn in front of the portal + event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation())); + //Properly close the portal to prevent it from staying in a locked state until it times out + exitPortal.close(false); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java b/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java index f796c51..21a0118 100644 --- a/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java @@ -14,9 +14,9 @@ public class TeleportEventListener implements Listener { /** * This event handler handles some special teleportation events * - *

This event cancels nether portal and end gateway teleportation if the user teleported from a stargate - * entrance. This prevents the user from just teleporting to the nether with the default portal design. - * Additionally, this event teleports any vehicles not detected by the VehicleMove event together with the player.

+ *

This event cancels nether portal, end gateway and end portal teleportation if the user teleported from a + * stargate entrance. This prevents the user from just teleporting to the nether or the end with portals using + * the special teleportation blocks.

* * @param event

The event to check and possibly cancel

*/ diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 75211c3..bbc6aa6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -69,7 +69,8 @@ public class VehicleEventListener implements Listener { Stargate.logger.warning(Stargate.getString("prefix") + "Unable to find portal destination"); return; } - Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); + Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + + destinationPortal.getSignLocation()); destinationPortal.teleport(vehicle, entrancePortal); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 5f53cc6..f934418 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -36,8 +36,9 @@ public class WorldEventListener implements Listener { public void onWorldUnload(WorldUnloadEvent event) { Stargate.debug("onWorldUnload", "Reloading all Stargates"); World world = event.getWorld(); - if (Stargate.managedWorlds.contains(world.getName())) { - Stargate.managedWorlds.remove(world.getName()); + String worldName = world.getName(); + if (Stargate.managedWorlds.contains(worldName)) { + Stargate.managedWorlds.remove(worldName); PortalHandler.clearPortals(world); } } From 382156a7193f60c86311dbec45cd92c8f57cb64d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 15 Oct 2021 18:52:02 +0200 Subject: [PATCH 151/378] Adds missing information about gate economy config values --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 1321864..45a62b0 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,10 @@ will lay out the gate format. Here is the default nethergate.gate file: portal-open=NETHER_PORTAL portal-closed=AIR button=STONE_BUTTON +usecost=0 +createcost=0 +destroycost=0 +toowner=false X=OBSIDIAN -=OBSIDIAN @@ -172,8 +176,15 @@ material for `portal-closed` can be most things, including solid blocks. Some ma material for `portal-open` can be any block the player can partially enter, even things like `GLOW_LICHEN`. `NETHER_PORTAL`, `END_GATEWAY` and `END_PORTAL` all work. +The `usecost`, `createcost` and `destroycost` keys can be used to set an economy price for gates of this type, different +from the cost defined in the config. With economy enabled, all gates without these values set will use the values from +the config. If you want to have different costs for different portals, you must create different gate types and set +different costs for each one. The `toowner` key can be used to set whether funds withdrawn for using portals with this +gate type should go to the portal's owner. + The key `button` is used to define the type of button that is generated for this gate. It can be a button (of any type), a type of wall coral (dead or alive), a type of shulker box or a chest. + `X` and `-` are used to define block types for the layout (Any single-character can be used, such as `#`). In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will From 6e658003e013d08af651c9cd155c6b63798f76b0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 15 Oct 2021 19:23:17 +0200 Subject: [PATCH 152/378] Improves Gate comments where possible Renames types to characterMaterialMap Simplifies writeConfig to a single method --- .../net/knarcraft/stargate/portal/Gate.java | 140 ++++++++---------- 1 file changed, 58 insertions(+), 82 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 92145b4..1a7b6d6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -23,13 +23,11 @@ public class Gate { private final String filename; private final GateLayout layout; - private final Map types; - + private final Map characterMaterialMap; //Gate materials private final Material portalOpenBlock; private final Material portalClosedBlock; private final Material portalButton; - //Economy information private final int useCost; private final int createCost; @@ -39,23 +37,23 @@ public class Gate { /** * Instantiates a new gate * - * @param filename

The name of the gate which equal the name of the file

- * @param layout

The character layout defined in the gate file

- * @param types

The block types the different layout characters represent

- * @param portalOpenBlock

The material to set the non-frame to when the portal is open

- * @param portalClosedBlock

The material to set the non-frame to when the portal is closed

- * @param portalButton

The material to use for the portal button

- * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

- * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

- * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

- * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

+ * @param filename

The name of the gate file, including extension

+ * @param layout

The gate layout defined in the gate file

+ * @param characterMaterialMap

The material types the different layout characters represent

+ * @param portalOpenBlock

The material to set the opening to when the portal is open

+ * @param portalClosedBlock

The material to set the opening to when the portal is closed

+ * @param portalButton

The material to use for the portal button

+ * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

+ * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

+ * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

+ * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

*/ - public Gate(String filename, GateLayout layout, Map types, Material portalOpenBlock, + public Gate(String filename, GateLayout layout, Map characterMaterialMap, Material portalOpenBlock, Material portalClosedBlock, Material portalButton, int useCost, int createCost, int destroyCost, boolean toOwner) { this.filename = filename; this.layout = layout; - this.types = types; + this.characterMaterialMap = characterMaterialMap; this.portalOpenBlock = portalOpenBlock; this.portalClosedBlock = portalClosedBlock; this.portalButton = portalButton; @@ -66,9 +64,9 @@ public class Gate { } /** - * Gets the layout of this gate + * Gets this gate's layout * - * @return

The layout of this gate

+ * @return

This gate's layout

*/ public GateLayout getLayout() { return layout; @@ -80,13 +78,13 @@ public class Gate { * @return

The material type used for control blocks

*/ public Material getControlBlock() { - return types.get(GateHandler.getControlBlockCharacter()); + return characterMaterialMap.get(GateHandler.getControlBlockCharacter()); } /** - * Gets the filename of this gate + * Gets the filename of this gate's file * - * @return

The filename of this gate

+ * @return

The filename of this gate's file

*/ public String getFilename() { return filename; @@ -125,7 +123,7 @@ public class Gate { * @return

The cost of using a portal with this gate

*/ public int getUseCost() { - return useCost < 0 ? EconomyHandler.getUseCost() : useCost; + return useCost < 0 ? EconomyHandler.getDefaultUseCost() : useCost; } /** @@ -169,6 +167,10 @@ public class Gate { /** * Checks whether a portal's gate matches this gate type * + *

If enabling onCreate, opening blocks with materials AIR and WATER will be allowed even if the gate closed + * material is a different one. If checking and onCreate is not enabled, any inconsistency with opening blocks + * containing AIR or WATER will cause the gate to not match.

+ * * @param topLeft

The top-left block of the portal's gate

* @param yaw

The yaw when looking directly outwards

* @param onCreate

Whether this is used in the context of creating a new gate

@@ -179,23 +181,29 @@ public class Gate { } /** - * Verifies that all border blocks of a portal gate matches this gate type + * Verifies that all border blocks of a portal matches this gate type * * @param topLeft

The top-left block of the portal

- * @param yaw

The yaw when looking directly outwards

+ * @param yaw

The yaw when looking directly outwards from the portal

* @return

True if all border blocks of the gate match the layout

*/ private boolean verifyGateBorderMatches(BlockLocation topLeft, double yaw) { - Map portalTypes = new HashMap<>(types); + Map characterMaterialMap = new HashMap<>(this.characterMaterialMap); for (RelativeBlockVector borderVector : layout.getBorder()) { int rowIndex = borderVector.getRight(); int lineIndex = borderVector.getDepth(); Character key = layout.getLayout()[lineIndex][rowIndex]; - Material materialInLayout = portalTypes.get(key); - Material materialAtLocation = getBlockAt(topLeft, borderVector, yaw).getType(); + Material materialInLayout = characterMaterialMap.get(key); + Material materialAtLocation = DirectionHelper.getBlockAt(topLeft, borderVector, yaw).getType(); if (materialInLayout == null) { - portalTypes.put(key, materialAtLocation); + /* This generally should not happen with proper checking, but just in case a material character is not + * recognized, but still allowed in previous checks, verify the gate as long as all such instances of + * the character correspond to the same material in the physical gate. All subsequent gates will also + * need to match the first verified gate. */ + characterMaterialMap.put(key, materialAtLocation); + Stargate.debug("Gate::Matches", String.format("Missing layout material in %s. Using %s from the" + + " physical portal.", getFilename(), materialAtLocation)); } else if (materialAtLocation != materialInLayout) { Stargate.debug("Gate::Matches", String.format("Block Type Mismatch: %s != %s", materialAtLocation, materialInLayout)); @@ -217,7 +225,7 @@ public class Gate { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(topLeft)); for (RelativeBlockVector entranceVector : layout.getEntrances()) { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(entranceVector)); - Material type = getBlockAt(topLeft, entranceVector, yaw).getType(); + Material type = DirectionHelper.getBlockAt(topLeft, entranceVector, yaw).getType(); //Ignore entrance if it's air or water, and we're creating a new gate if (onCreate && (type == Material.AIR || type == Material.WATER)) { @@ -232,16 +240,6 @@ public class Gate { return true; } - /** - * Gets the block at a relative block vector location - * - * @param vector

The relative block vector

- * @return

The block at the given relative position

- */ - private BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, double yaw) { - return DirectionHelper.getBlockAt(topLeft, vector, yaw); - } - /** * Saves this gate to a file * @@ -253,6 +251,7 @@ public class Gate { try { BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(gateFolder + filename)); + //Save main material names writeConfig(bufferedWriter, "portal-open", portalOpenBlock.name()); writeConfig(bufferedWriter, "portal-closed", portalClosedBlock.name()); writeConfig(bufferedWriter, "button", portalButton.name()); @@ -260,12 +259,12 @@ public class Gate { //Save the values necessary for economy saveEconomyValues(bufferedWriter); - //Store type material type to use for frame blocks + //Store material types to use for frame blocks saveFrameBlockTypes(bufferedWriter); bufferedWriter.newLine(); - //Save the layout + //Save the gate layout layout.save(bufferedWriter); bufferedWriter.close(); @@ -278,15 +277,18 @@ public class Gate { * Saves current economy related values using a buffered writer * * @param bufferedWriter

The buffered writer to write to

- * * @throws IOException

If unable to write to the buffered writer

+ * @throws IOException

If unable to write to the buffered writer

*/ private void saveEconomyValues(BufferedWriter bufferedWriter) throws IOException { + //Write use cost if not disabled if (useCost != -1) { writeConfig(bufferedWriter, "usecost", useCost); } + //Write create cost if not disabled if (createCost != -1) { writeConfig(bufferedWriter, "createcost", createCost); } + //Write destroy cost if not disabled if (destroyCost != -1) { writeConfig(bufferedWriter, "destroycost", destroyCost); } @@ -300,10 +302,10 @@ public class Gate { * @throws IOException

If unable to write to the buffered writer

*/ private void saveFrameBlockTypes(BufferedWriter bufferedWriter) throws IOException { - for (Map.Entry entry : types.entrySet()) { + for (Map.Entry entry : characterMaterialMap.entrySet()) { Character type = entry.getKey(); Material value = entry.getValue(); - // Skip control values + //Skip characters not part of the frame if (type.equals(GateHandler.getAnythingCharacter()) || type.equals(GateHandler.getEntranceCharacter()) || type.equals(GateHandler.getExitCharacter())) { @@ -319,53 +321,27 @@ public class Gate { } } - /** - * Writes an integer to a config - * - * @param bufferedWriter

The buffered writer to write the config to

- * @param key

The config key to save

- * @param value

The value of the config key

- * @throws IOException

If unable to write to the buffered writer

- */ - private void writeConfig(BufferedWriter bufferedWriter, String key, int value) throws IOException { - writeConfig(bufferedWriter, "%s=%d", key, value); - } - - /** - * Writes a boolean to a config - * - * @param bufferedWriter

The buffered writer to write the config to

- * @param key

The config key to save

- * @param value

The value of the config key

- * @throws IOException

If unable to write to the buffered writer

- */ - @SuppressWarnings("SameParameterValue") - private void writeConfig(BufferedWriter bufferedWriter, String key, boolean value) throws IOException { - writeConfig(bufferedWriter, "%s=%b", key, value); - } - - /** - * Writes a string to a config - * - * @param bufferedWriter

The buffered writer to write the config to

- * @param key

The config key to save

- * @param value

The value of the config key

- * @throws IOException

If unable to write to the buffered writer

- */ - private void writeConfig(BufferedWriter bufferedWriter, String key, String value) throws IOException { - writeConfig(bufferedWriter, "%s=%s", key, value); - } - /** * Writes a formatted string to a buffered writer * * @param bufferedWriter

The buffered writer to write the formatted string to

- * @param format

The format to use

* @param key

The config key to save

* @param value

The config value to save

* @throws IOException

If unable to write to the buffered writer

*/ - private void writeConfig(BufferedWriter bufferedWriter, String format, String key, Object value) throws IOException { + private void writeConfig(BufferedWriter bufferedWriter, String key, Object value) throws IOException { + //Figure out the correct formatting to use + String format = "%s="; + if (value instanceof Boolean) { + format += "%b"; + } else if (value instanceof Integer) { + format += "%d"; + } else if (value instanceof String) { + format += "%s"; + } else { + throw new IllegalArgumentException("Unrecognized config value type"); + } + bufferedWriter.append(String.format(format, key, value)); bufferedWriter.newLine(); } From d45af537cde52f371c26633d214bc5423d22ddcf Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 15 Oct 2021 19:24:15 +0200 Subject: [PATCH 153/378] Removes the unused getCorners method --- .../net/knarcraft/stargate/portal/GateLayout.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 2b734ff..38e121a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -33,18 +33,6 @@ public class GateLayout { readLayout(); } - /** - * Gets two of the corners of the gate layout creating the smallest box the gate can be contained within - * - * @return

Two of the gate's corners

- */ - public RelativeBlockVector[] getCorners() { - return new RelativeBlockVector[]{ - new RelativeBlockVector(0, 0, 0), - new RelativeBlockVector(layout[0].length - 1, layout.length - 1, 1) - }; - } - /** * Gets the character array describing this layout * From e2c91c1feb63abf4398d0bf52de9361b4083c8c5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 15 Oct 2021 19:25:31 +0200 Subject: [PATCH 154/378] Changes EconomyHandler method names to be more consistent --- .../event/StargateEntityPortalEvent.java | 2 +- .../stargate/listener/VehicleEventListener.java | 4 ++-- .../stargate/utility/EconomyHandler.java | 16 ++++++++-------- .../stargate/utility/EconomyHelper.java | 8 ++++---- .../stargate/utility/PermissionHelper.java | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java index 1b6fa95..b392ee8 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; public class StargateEntityPortalEvent extends StargateEvent { private static final HandlerList handlers = new HandlerList(); - Entity travellingEntity; + final Entity travellingEntity; private final Portal destination; private Location exit; diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index bbc6aa6..57d3ad4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -102,9 +102,9 @@ public class VehicleEventListener implements Listener { } //Transfer payment if necessary - int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); + int cost = EconomyHandler.getDefaultUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { - if (!EconomyHelper.payTeleportFee(entrancePortal, player, cost)) { + if (EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost)) { return; } } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 33c4b1e..66cc35e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -32,7 +32,7 @@ public final class EconomyHandler { * * @return

The gate use cost

*/ - public static int getUseCost() { + public static int getDefaultUseCost() { return useCost; } @@ -43,7 +43,7 @@ public final class EconomyHandler { * * @param useCost

The gate use cost

*/ - public static void setUseCost(int useCost) { + public static void setDefaultUseCost(int useCost) { if (useCost < 0) { throw new IllegalArgumentException("Using a gate cannot cost a negative amount"); } @@ -66,7 +66,7 @@ public final class EconomyHandler { * * @param createCost

The gate creation cost

*/ - public static void setCreateCost(int createCost) { + public static void setDefaultCreateCost(int createCost) { EconomyHandler.createCost = createCost; } @@ -84,7 +84,7 @@ public final class EconomyHandler { * * @param destroyCost

The gate destruction cost

*/ - public static void setDestroyCost(int destroyCost) { + public static void setDefaultDestroyCost(int destroyCost) { EconomyHandler.destroyCost = destroyCost; } @@ -99,7 +99,7 @@ public final class EconomyHandler { if (skipPayment(cost)) { return true; } - // Charge player + //Charge player return EconomyHandler.chargePlayer(player, cost); } @@ -115,7 +115,7 @@ public final class EconomyHandler { if (skipPayment(cost)) { return true; } - // Charge player + //Charge player return EconomyHandler.chargePlayer(player, target, cost); } @@ -143,7 +143,7 @@ public final class EconomyHandler { if (!economyEnabled) { return false; } - // Check for Vault + //Check if vault is loaded Plugin vault = pluginManager.getPlugin("Vault"); if (vault != null && vault.isEnabled()) { RegisteredServiceProvider economyProvider = Stargate.server.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); @@ -188,7 +188,7 @@ public final class EconomyHandler { * @param destination

The destination portal

* @return

The cost of using the portal

*/ - public static int getUseCost(Player player, Portal source, Portal destination) { + public static int getDefaultUseCost(Player player, Portal source, Portal destination) { //No payment required if (!EconomyHandler.useEconomy() || source.getOptions().isFree()) { return 0; diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 2b0d34b..68ffcff 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -19,9 +19,9 @@ public final class EconomyHelper { * @param entrancePortal

The portal the player is entering

* @param player

The player wishing to teleport

* @param cost

The cost of teleportation

- * @return

True if payment was successful

+ * @return

False if payment was successful. True if the payment was unsuccessful

*/ - public static boolean payTeleportFee(Portal entrancePortal, Player player, int cost) { + public static boolean cannotPayTeleportFee(Portal entrancePortal, Player player, int cost) { boolean success; //Try to charge the player @@ -36,7 +36,7 @@ public final class EconomyHelper { if (!success) { sendInsufficientFundsMessage(entrancePortal.getName(), player, cost); entrancePortal.close(false); - return false; + return true; } //Send the deduct-message to the player @@ -55,7 +55,7 @@ public final class EconomyHelper { sendObtainMessage(entrancePortal.getName(), gateOwner, cost); } } - return true; + return false; } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 3be876d..6038151 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -405,9 +405,9 @@ public final class PermissionHelper { } //Player cannot pay for teleportation - int cost = EconomyHandler.getUseCost(player, entrancePortal, destination); + int cost = EconomyHandler.getDefaultUseCost(player, entrancePortal, destination); if (cost > 0) { - return !EconomyHelper.payTeleportFee(entrancePortal, player, cost); + return EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost); } return false; } From 5299efaa86eb3d38d626cf96a65cf8b1b883cd2d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 15 Oct 2021 19:46:25 +0200 Subject: [PATCH 155/378] Renames types to characterMaterialMap inside the GateHandler class --- .../java/net/knarcraft/stargate/Stargate.java | 8 +-- .../stargate/portal/GateHandler.java | 68 ++++++++++--------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index c9e2b60..0c3b72c 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -55,7 +55,7 @@ public class Stargate extends JavaPlugin { public static final Queue blockChangeRequestQueue = new LinkedList<>(); public static final ConcurrentLinkedQueue openPortalsQueue = new ConcurrentLinkedQueue<>(); public static final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); - public static final Queue chunkUnloadQueue = new PriorityQueue<>(); + private static final Queue chunkUnloadQueue = new PriorityQueue<>(); //Amount of seconds before deactivating/closing portals private static final int activeTime = 10; @@ -482,9 +482,9 @@ public class Stargate extends JavaPlugin { */ private void loadEconomyConfig() { EconomyHandler.economyEnabled = newConfig.getBoolean("economy.useEconomy"); - EconomyHandler.setCreateCost(newConfig.getInt("economy.createCost")); - EconomyHandler.setDestroyCost(newConfig.getInt("economy.destroyCost")); - EconomyHandler.setUseCost(newConfig.getInt("economy.useCost")); + EconomyHandler.setDefaultCreateCost(newConfig.getInt("economy.createCost")); + EconomyHandler.setDefaultDestroyCost(newConfig.getInt("economy.destroyCost")); + EconomyHandler.setDefaultUseCost(newConfig.getInt("economy.useCost")); EconomyHandler.toOwner = newConfig.getBoolean("economy.toOwner"); EconomyHandler.chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination"); EconomyHandler.freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen"); diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 8993150..fa20d6a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -117,24 +117,24 @@ public class GateHandler { */ private static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { List> design = new ArrayList<>(); - Map types = new HashMap<>(); + Map characterMaterialMap = new HashMap<>(); Map config = new HashMap<>(); Set frameTypes = new HashSet<>(); //Initialize types map - types.put(ENTRANCE, Material.AIR); - types.put(EXIT, Material.AIR); - types.put(ANYTHING, Material.AIR); + characterMaterialMap.put(ENTRANCE, Material.AIR); + characterMaterialMap.put(EXIT, Material.AIR); + characterMaterialMap.put(ANYTHING, Material.AIR); //Read the file into appropriate lists and maps - int cols = readGateFile(scanner, types, fileName, design, frameTypes, config); + int cols = readGateFile(scanner, characterMaterialMap, fileName, design, frameTypes, config); if (cols < 0) { return null; } Character[][] layout = generateLayoutMatrix(design, cols); //Create and validate the new gate - Gate gate = createGate(config, fileName, layout, types); + Gate gate = createGate(config, fileName, layout, characterMaterialMap); if (gate == null) { return null; } @@ -146,23 +146,25 @@ public class GateHandler { /** * Creates a new gate * - * @param config

The config map to get configuration values from

- * @param fileName

The name of the saved gate config file

- * @param layout

The layout matrix of the new gate

- * @param types

The mapping for used gate material types

+ * @param config

The config map to get configuration values from

+ * @param fileName

The name of the saved gate config file

+ * @param layout

The layout matrix of the new gate

+ * @param characterMaterialMap

The mapping for used gate material types

* @return

A new gate or null if the config is invalid

*/ private static Gate createGate(Map config, String fileName, Character[][] layout, - Map types) { + Map characterMaterialMap) { Material portalOpenBlock = readConfig(config, fileName, "portal-open", defaultPortalBlockOpen); Material portalClosedBlock = readConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); Material portalButton = readConfig(config, fileName, "button", defaultButton); int useCost = readConfig(config, fileName, "usecost"); int createCost = readConfig(config, fileName, "createcost"); int destroyCost = readConfig(config, fileName, "destroycost"); - boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : EconomyHandler.toOwner); + boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : + EconomyHandler.toOwner); - Gate gate = new Gate(fileName, new GateLayout(layout), types, portalOpenBlock, portalClosedBlock, portalButton, useCost, + Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, portalOpenBlock, portalClosedBlock, + portalButton, useCost, createCost, destroyCost, toOwner); if (!validateGate(gate, fileName)) { @@ -223,15 +225,15 @@ public class GateHandler { /** * Reads the gate file * - * @param scanner

The scanner to read from

- * @param types

The map of characters to store valid symbols in

- * @param fileName

The filename of the loaded gate config file

- * @param design

The list to store the loaded design to

- * @param frameTypes

The set of gate frame types to store to

- * @param config

The map of config values to store to

+ * @param scanner

The scanner to read from

+ * @param characterMaterialMap

The map of characters to store valid symbols in

+ * @param fileName

The filename of the loaded gate config file

+ * @param design

The list to store the loaded design to

+ * @param frameTypes

The set of gate frame types to store to

+ * @param config

The map of config values to store to

* @return

The column count/width of the loaded gate

*/ - private static int readGateFile(Scanner scanner, Map types, String fileName, + private static int readGateFile(Scanner scanner, Map characterMaterialMap, String fileName, List> design, Set frameTypes, Map config) { boolean designing = false; int cols = 0; @@ -240,13 +242,13 @@ public class GateHandler { String line = scanner.nextLine(); if (designing) { - cols = readGateDesignLine(line, cols, types, fileName, design); + cols = readGateDesignLine(line, cols, characterMaterialMap, fileName, design); if (cols < 0) { return -1; } } else { if (!line.isEmpty() && !line.startsWith("#")) { - readGateConfigValue(line, types, frameTypes, config); + readGateConfigValue(line, characterMaterialMap, frameTypes, config); } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { designing = true; } @@ -268,13 +270,13 @@ public class GateHandler { * * @param line

The line to read

* @param cols

The current max columns value of the design

- * @param types

The map of characters to check for valid symbols

+ * @param characterMaterialMap

The map of characters to check for valid symbols

* @param fileName

The filename of the loaded gate config file

* @param design

The list to store the loaded design to

* @return

The new max columns value of the design

*/ - private static int readGateDesignLine(String line, int cols, Map types, String fileName, - List> design) { + private static int readGateDesignLine(String line, int cols, Map characterMaterialMap, + String fileName, List> design) { List row = new ArrayList<>(); if (line.length() > cols) { @@ -282,8 +284,9 @@ public class GateHandler { } for (Character symbol : line.toCharArray()) { - if ((symbol.equals('?')) || (!types.containsKey(symbol))) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + symbol + "' in diagram"); + if ((symbol.equals('?')) || (!characterMaterialMap.containsKey(symbol))) { + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + + symbol + "' in diagram"); return -1; } row.add(symbol); @@ -297,13 +300,13 @@ public class GateHandler { * Reads one config value from the gate layout file * * @param line

The line to read

- * @param types

The map of characters to materials to store to

+ * @param characterMaterialMap

The map of characters to materials to store to

* @param frameTypes

The set of gate frame types to store to

* @param config

The map of config values to store to

* @throws Exception

If an invalid material is encountered

*/ - private static void readGateConfigValue(String line, Map types, Set frameTypes, - Map config) throws Exception { + private static void readGateConfigValue(String line, Map characterMaterialMap, + Set frameTypes, Map config) throws Exception { String[] split = line.split("="); String key = split[0].trim(); String value = split[1].trim(); @@ -314,7 +317,7 @@ public class GateHandler { if (id == null) { throw new Exception("Invalid material in line: " + line); } - types.put(symbol, id); + characterMaterialMap.put(symbol, id); frameTypes.add(id); } else { config.put(key, value); @@ -334,7 +337,8 @@ public class GateHandler { try { return Integer.parseInt(config.get(key)); } catch (NumberFormatException ex) { - Stargate.logger.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); + Stargate.logger.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", + ex.getClass().getName(), fileName, key)); } } From 59069d142301b7fcb1e7a373d97261d0d3e8b4c7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 15 Oct 2021 22:16:02 +0200 Subject: [PATCH 156/378] Improves comments in the GateHandler class and extracts some code into GateReader Moves code for reading .gate files into the GateReader helper class Improves all comments in GateHandler where possible Adds more helper comments --- .../java/net/knarcraft/stargate/Stargate.java | 2 +- .../stargate/portal/GateHandler.java | 252 ++++-------------- .../stargate/utility/GateReader.java | 212 +++++++++++++++ 3 files changed, 262 insertions(+), 204 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/GateReader.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 0c3b72c..2eecae4 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -405,7 +405,7 @@ public class Stargate extends JavaPlugin { //If users have an outdated config, assume they also need to update their default gates if (isMigrating) { - GateHandler.populateDefaults(gateFolder); + GateHandler.writeDefaultGatesToFolder(gateFolder); } //Gates diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index fa20d6a..b6f0087 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.EconomyHandler; +import net.knarcraft.stargate.utility.GateReader; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; import org.bukkit.block.Block; @@ -17,6 +18,10 @@ import java.util.Scanner; import java.util.Set; import java.util.logging.Level; +import static net.knarcraft.stargate.utility.GateReader.generateLayoutMatrix; +import static net.knarcraft.stargate.utility.GateReader.readGateConfig; +import static net.knarcraft.stargate.utility.GateReader.readGateFile; + /** * The gate handler keeps track of all gates */ @@ -93,10 +98,10 @@ public class GateHandler { } /** - * Loads a gate + * Loads a gate from a file * - * @param file

The file containing the gate's layout

- * @return

The loaded gate or null if unable to load the gate

+ * @param file

The file containing the gate data

+ * @return

The loaded gate, or null if unable to load the gate

*/ private static Gate loadGate(File file) { try (Scanner scanner = new Scanner(file)) { @@ -108,11 +113,11 @@ public class GateHandler { } /** - * Loads a gate + * Loads a gate from a file * - * @param fileName

The name of the file containing the gate layout

- * @param parentFolder

The parent folder of the layout file

- * @param scanner

The scanner to use for reading the gate layout

+ * @param fileName

The name of the file containing the gate data

+ * @param parentFolder

The parent folder of the gate data file

+ * @param scanner

The scanner to use for reading the gate data

* @return

The loaded gate or null if unable to load the gate

*/ private static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { @@ -121,17 +126,17 @@ public class GateHandler { Map config = new HashMap<>(); Set frameTypes = new HashSet<>(); - //Initialize types map + //Initialize character to material map characterMaterialMap.put(ENTRANCE, Material.AIR); characterMaterialMap.put(EXIT, Material.AIR); characterMaterialMap.put(ANYTHING, Material.AIR); //Read the file into appropriate lists and maps - int cols = readGateFile(scanner, characterMaterialMap, fileName, design, frameTypes, config); - if (cols < 0) { + int columns = readGateFile(scanner, characterMaterialMap, fileName, design, frameTypes, config); + if (columns < 0) { return null; } - Character[][] layout = generateLayoutMatrix(design, cols); + Character[][] layout = generateLayoutMatrix(design, columns); //Create and validate the new gate Gate gate = createGate(config, fileName, layout, characterMaterialMap); @@ -139,7 +144,8 @@ public class GateHandler { return null; } - gate.save(parentFolder + "/"); // Updates format for version changes + //Update gate file in case the format has changed between versions + gate.save(parentFolder + "/"); return gate; } @@ -149,23 +155,26 @@ public class GateHandler { * @param config

The config map to get configuration values from

* @param fileName

The name of the saved gate config file

* @param layout

The layout matrix of the new gate

- * @param characterMaterialMap

The mapping for used gate material types

- * @return

A new gate or null if the config is invalid

+ * @param characterMaterialMap

A map between layout characters and the material to use

+ * @return

A new gate, or null if the config is invalid

*/ private static Gate createGate(Map config, String fileName, Character[][] layout, Map characterMaterialMap) { - Material portalOpenBlock = readConfig(config, fileName, "portal-open", defaultPortalBlockOpen); - Material portalClosedBlock = readConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); - Material portalButton = readConfig(config, fileName, "button", defaultButton); - int useCost = readConfig(config, fileName, "usecost"); - int createCost = readConfig(config, fileName, "createcost"); - int destroyCost = readConfig(config, fileName, "destroycost"); + //Read relevant material types + Material portalOpenBlock = readGateConfig(config, fileName, "portal-open", defaultPortalBlockOpen); + Material portalClosedBlock = readGateConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); + Material portalButton = readGateConfig(config, fileName, "button", defaultButton); + + //Read economy values + int useCost = GateReader.readGateConfig(config, fileName, "usecost"); + int createCost = GateReader.readGateConfig(config, fileName, "createcost"); + int destroyCost = GateReader.readGateConfig(config, fileName, "destroycost"); boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : EconomyHandler.toOwner); + //Create the new gate Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, portalOpenBlock, portalClosedBlock, - portalButton, useCost, - createCost, destroyCost, toOwner); + portalButton, useCost, createCost, destroyCost, toOwner); if (!validateGate(gate, fileName)) { return null; @@ -174,7 +183,7 @@ public class GateHandler { } /** - * Validate that a gate is valid + * Validates that a gate is valid * * @param gate

The gate to validate

* @param fileName

The filename of the loaded gate file

@@ -195,177 +204,6 @@ public class GateHandler { return true; } - /** - * Generates a matrix storing the gate layout - * - * @param design

The design of the gate layout

- * @param cols

The largest amount of columns in the design

- * @return

A matrix containing the gate's layout

- */ - private static Character[][] generateLayoutMatrix(List> design, int cols) { - Character[][] layout = new Character[design.size()][cols]; - for (int lineIndex = 0; lineIndex < design.size(); lineIndex++) { - List row = design.get(lineIndex); - Character[] result = new Character[cols]; - - for (int rowIndex = 0; rowIndex < cols; rowIndex++) { - if (rowIndex < row.size()) { - result[rowIndex] = row.get(rowIndex); - } else { - //Add spaces to all lines which are too short - result[rowIndex] = ' '; - } - } - - layout[lineIndex] = result; - } - return layout; - } - - /** - * Reads the gate file - * - * @param scanner

The scanner to read from

- * @param characterMaterialMap

The map of characters to store valid symbols in

- * @param fileName

The filename of the loaded gate config file

- * @param design

The list to store the loaded design to

- * @param frameTypes

The set of gate frame types to store to

- * @param config

The map of config values to store to

- * @return

The column count/width of the loaded gate

- */ - private static int readGateFile(Scanner scanner, Map characterMaterialMap, String fileName, - List> design, Set frameTypes, Map config) { - boolean designing = false; - int cols = 0; - try { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - - if (designing) { - cols = readGateDesignLine(line, cols, characterMaterialMap, fileName, design); - if (cols < 0) { - return -1; - } - } else { - if (!line.isEmpty() && !line.startsWith("#")) { - readGateConfigValue(line, characterMaterialMap, frameTypes, config); - } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { - designing = true; - } - } - } - } catch (Exception ex) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); - return -1; - } finally { - if (scanner != null) { - scanner.close(); - } - } - return cols; - } - - /** - * Reads one design line of the gate layout file - * - * @param line

The line to read

- * @param cols

The current max columns value of the design

- * @param characterMaterialMap

The map of characters to check for valid symbols

- * @param fileName

The filename of the loaded gate config file

- * @param design

The list to store the loaded design to

- * @return

The new max columns value of the design

- */ - private static int readGateDesignLine(String line, int cols, Map characterMaterialMap, - String fileName, List> design) { - List row = new ArrayList<>(); - - if (line.length() > cols) { - cols = line.length(); - } - - for (Character symbol : line.toCharArray()) { - if ((symbol.equals('?')) || (!characterMaterialMap.containsKey(symbol))) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + - symbol + "' in diagram"); - return -1; - } - row.add(symbol); - } - - design.add(row); - return cols; - } - - /** - * Reads one config value from the gate layout file - * - * @param line

The line to read

- * @param characterMaterialMap

The map of characters to materials to store to

- * @param frameTypes

The set of gate frame types to store to

- * @param config

The map of config values to store to

- * @throws Exception

If an invalid material is encountered

- */ - private static void readGateConfigValue(String line, Map characterMaterialMap, - Set frameTypes, Map config) throws Exception { - String[] split = line.split("="); - String key = split[0].trim(); - String value = split[1].trim(); - - if (key.length() == 1) { - Character symbol = key.charAt(0); - Material id = Material.getMaterial(value); - if (id == null) { - throw new Exception("Invalid material in line: " + line); - } - characterMaterialMap.put(symbol, id); - frameTypes.add(id); - } else { - config.put(key, value); - } - } - - /** - * Reads an integer configuration key - * - * @param config

The configuration to read

- * @param fileName

The filename of the config file

- * @param key

The config key to read

- * @return

The read value, or -1 if it cannot be read

- */ - private static int readConfig(Map config, String fileName, String key) { - if (config.containsKey(key)) { - try { - return Integer.parseInt(config.get(key)); - } catch (NumberFormatException ex) { - Stargate.logger.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", - ex.getClass().getName(), fileName, key)); - } - } - - return -1; - } - - /** - * Gets the material defined in the config - * - * @param config

The config to read

- * @param fileName

The config file the config belongs to

- * @param key

The config key to read

- * @param defaultMaterial

The default material to use, in case the config is invalid

- * @return

The material to use

- */ - private static Material readConfig(Map config, String fileName, String key, Material defaultMaterial) { - if (config.containsKey(key)) { - Material material = Material.getMaterial(config.get(key)); - if (material != null) { - return material; - } else { - Stargate.logger.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, key)); - } - } - return defaultMaterial; - } - /** * Loads all gates inside the given folder * @@ -376,17 +214,20 @@ public class GateHandler { File[] files; if (directory.exists()) { + //Get all files with a .gate extension files = directory.listFiles((file) -> file.isFile() && file.getName().endsWith(".gate")); } else { + //Set files to empty list to signal that default gates need to be copied files = new File[0]; } if (files == null || files.length == 0) { //The gates-folder was not found. Assume this is the first run if (directory.mkdir()) { - populateDefaults(gateFolder); + writeDefaultGatesToFolder(gateFolder); } } else { + //Load and register the corresponding gate for each file for (File file : files) { Gate gate = loadGate(file); if (gate != null) { @@ -397,11 +238,11 @@ public class GateHandler { } /** - * Writes the default gate specifications to the given folder + * Writes the default gates to the given folder * * @param gateFolder

The folder containing gate config files

*/ - public static void populateDefaults(String gateFolder) { + public static void writeDefaultGatesToFolder(String gateFolder) { loadGateFromJar("nethergate.gate", gateFolder); loadGateFromJar("watergate.gate", gateFolder); loadGateFromJar("endgate.gate", gateFolder); @@ -414,9 +255,11 @@ public class GateHandler { * @param gateFolder

The folder containing gates

*/ private static void loadGateFromJar(String gateFile, String gateFolder) { + //Get an input stream for the internal file InputStream gateFileStream = Gate.class.getResourceAsStream("/gates/" + gateFile); if (gateFileStream != null) { Scanner scanner = new Scanner(gateFileStream); + //Load and register the gate Gate gate = loadGate(gateFile, gateFolder, scanner); if (gate != null) { registerGate(gate); @@ -440,6 +283,9 @@ public class GateHandler { /** * Gets the gates with the given control block * + *

The control block is the block type where the sign should be placed. It is used to decide whether a user + * is creating a new portal.

+ * * @param type

The type of the control block to check

* @return

A list of gates using the given material for control block

*/ @@ -455,13 +301,13 @@ public class GateHandler { } /** - * Gets a portal by its name (filename before .gate) + * Gets a portal given its filename * - * @param name

The name of the gate to get

- * @return

The gate with the given name

+ * @param fileName

The filename of the gate to get

+ * @return

The gate with the given filename

*/ - public static Gate getGateByName(String name) { - return gates.get(name); + public static Gate getGateByName(String fileName) { + return gates.get(fileName); } /** @@ -474,7 +320,7 @@ public class GateHandler { } /** - * Clears all loaded gates + * Clears all loaded gates and control blocks */ public static void clearGates() { gates.clear(); diff --git a/src/main/java/net/knarcraft/stargate/utility/GateReader.java b/src/main/java/net/knarcraft/stargate/utility/GateReader.java new file mode 100644 index 0000000..a04a10a --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/GateReader.java @@ -0,0 +1,212 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.Material; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; +import java.util.logging.Level; + +/** + * Helper class for reading gate files + */ +public final class GateReader { + + private GateReader() { + + } + + /** + * Reads a gate file + * + * @param scanner

The scanner to read from

+ * @param characterMaterialMap

The map of characters to store valid symbols in

+ * @param fileName

The filename of the loaded gate config file

+ * @param design

The list to store the loaded design/layout to

+ * @param frameTypes

The set to store frame/border materials to

+ * @param config

The map of config values to store to

+ * @return

The column count/width of the loaded gate

+ */ + public static int readGateFile(Scanner scanner, Map characterMaterialMap, String fileName, + List> design, Set frameTypes, Map config) { + boolean designing = false; + int columns = 0; + try { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + + if (designing) { + //If we have reached the gate's layout/design, read it + columns = readGateDesignLine(line, columns, characterMaterialMap, fileName, design); + if (columns < 0) { + return -1; + } + } else { + if (!line.isEmpty() && !line.startsWith("#")) { + //Read a normal config value + readGateConfigValue(line, characterMaterialMap, frameTypes, config); + } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { + //An empty line marks the start of the gate's layout/design + designing = true; + } + } + } + } catch (Exception ex) { + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + return -1; + } finally { + if (scanner != null) { + scanner.close(); + } + } + return columns; + } + + /** + * Reads one design line of the gate layout file + * + *

The max columns value is sent through this method in such a way that when the last gate design line is read, + * the max columns value contains the largest amount of columns (character) found in any of the design's lines.

+ * + * @param line

The line to read

+ * @param maxColumns

The current max columns value of the design

+ * @param characterMaterialMap

The map between characters and the corresponding materials to use

+ * @param fileName

The filename of the loaded gate config file

+ * @param design

The two-dimensional list to store the loaded design to

+ * @return

The new max columns value of the design

+ */ + private static int readGateDesignLine(String line, int maxColumns, Map characterMaterialMap, + String fileName, List> design) { + List row = new ArrayList<>(); + + //Update the max columns number if this line has more columns + if (line.length() > maxColumns) { + maxColumns = line.length(); + } + + for (Character symbol : line.toCharArray()) { + //Refuse read gate designs with unknown characters + if (symbol.equals('?') || (!characterMaterialMap.containsKey(symbol))) { + Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + + symbol + "' in diagram"); + return -1; + } + //Add the read character to the row + row.add(symbol); + } + + //Add this row of the gate's design to the two-dimensional design list + design.add(row); + return maxColumns; + } + + /** + * Reads one config value from the gate layout file + * + * @param line

The line to read

+ * @param characterMaterialMap

The character to material map to store to

+ * @param frameTypes

The set to store gate frame/border types to

+ * @param config

The config value map to store to

+ * @throws Exception

If an invalid material is encountered

+ */ + private static void readGateConfigValue(String line, Map characterMaterialMap, + Set frameTypes, Map config) throws Exception { + String[] split = line.split("="); + String key = split[0].trim(); + String value = split[1].trim(); + + if (key.length() == 1) { + //Read a gate frame material + Character symbol = key.charAt(0); + Material material = Material.getMaterial(value); + if (material == null) { + throw new Exception("Invalid material in line: " + line); + } + //Register the map between the read symbol and the corresponding material + characterMaterialMap.put(symbol, material); + //Save the material as one of the frame materials used for this kind of gate + frameTypes.add(material); + } else { + //Read a normal config value + config.put(key, value); + } + } + + /** + * Reads an integer configuration value + * + * @param config

The configuration to read

+ * @param fileName

The filename of the config file

+ * @param key

The config key to read

+ * @return

The read value, or -1 if it could not be read

+ */ + public static int readGateConfig(Map config, String fileName, String key) { + if (config.containsKey(key)) { + try { + return Integer.parseInt(config.get(key)); + } catch (NumberFormatException ex) { + Stargate.logger.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", + ex.getClass().getName(), fileName, key)); + } + } + + return -1; + } + + /** + * Reads a material configuration value + * + * @param config

The configuration to read

+ * @param fileName

The filename of the config file

+ * @param key

The config key to read

+ * @param defaultMaterial

The default material to use, in case the config is invalid

+ * @return

The material specified in the config, or the default material if it could not be read

+ */ + public static Material readGateConfig(Map config, String fileName, String key, + Material defaultMaterial) { + if (config.containsKey(key)) { + Material material = Material.getMaterial(config.get(key)); + if (material != null) { + return material; + } else { + Stargate.logger.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, + key)); + } + } + return defaultMaterial; + } + + /** + * Generates a matrix containing the gate layout + * + *

This basically changes the list of lists into a primitive matrix. Additionally, spaces are added to the end of + * each row which to too short relative to the longest row.

+ * + * @param design

The design of the gate layout

+ * @param columns

The largest amount of columns in the design

+ * @return

A matrix containing the gate's layout

+ */ + public static Character[][] generateLayoutMatrix(List> design, int columns) { + Character[][] layout = new Character[design.size()][columns]; + for (int lineIndex = 0; lineIndex < design.size(); lineIndex++) { + List row = design.get(lineIndex); + Character[] result = new Character[columns]; + + for (int rowIndex = 0; rowIndex < columns; rowIndex++) { + if (rowIndex < row.size()) { + result[rowIndex] = row.get(rowIndex); + } else { + //Add spaces to all lines which are too short + result[rowIndex] = ' '; + } + } + + layout[lineIndex] = result; + } + return layout; + } + +} From 3de785d5ab0f4bfee90b72333333866f1eb471b5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 16 Oct 2021 16:44:11 +0200 Subject: [PATCH 157/378] Improves and fixes comments for the gate layout class --- .../net/knarcraft/stargate/portal/Gate.java | 2 +- .../knarcraft/stargate/portal/GateLayout.java | 120 +++++++++--------- 2 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 1a7b6d6..9fdc3d8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -265,7 +265,7 @@ public class Gate { bufferedWriter.newLine(); //Save the gate layout - layout.save(bufferedWriter); + layout.saveLayout(bufferedWriter); bufferedWriter.close(); } catch (IOException ex) { diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 38e121a..00d3278 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.container.RelativeBlockVector; import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -12,7 +13,7 @@ import java.util.List; * *

The gate layout parses a layout described by a Character matrix and stores the different parts of the gate as * relative block vectors. All relative vectors has an origin in the top-left block when looking at the gate's front - * (the side with the sign)

+ * (the side with the sign). The origin of the relative vectors can also be seen as 0,0 in the character matrix.

*/ public class GateLayout { @@ -26,7 +27,7 @@ public class GateLayout { /** * Instantiates a new gate layout * - * @param layout

A character array describing the layout

+ * @param layout

A character matrix describing the layout

*/ public GateLayout(Character[][] layout) { this.layout = layout; @@ -43,7 +44,9 @@ public class GateLayout { } /** - * Gets the locations of entrances for this gate + * Gets the locations of all entrances for this gate + * + *

Entrances contain both the portal entrance blocks and the portal exit blocks.

* * @return

The locations of entrances for this gate

*/ @@ -73,9 +76,12 @@ public class GateLayout { } /** - * Gets other possible exits of the gate + * Gets all possible exit locations defined in the layout * - * @return

Other possible gate exits

+ *

This returns all blocks usable as exits. This basically means it returns the lowest block in each opening of + * the gate layout.

+ * + * @return

All possible exits

*/ public List getExits() { return exits; @@ -84,7 +90,8 @@ public class GateLayout { /** * Gets the locations of the control blocks for this gate * - *

The control blocks are the blocks where a sign can be placed to create a portal.

+ *

The control blocks are the blocks where a sign can be placed to create a portal. The control block without a + * sign will be used for the button if necessary. There will always be exactly two control blocks.

* * @return

The locations of the control blocks for this gate

*/ @@ -98,44 +105,24 @@ public class GateLayout { * @param bufferedWriter

The buffered writer to write to

* @throws IOException

If unable to write to the buffered writer

*/ - public void save(BufferedWriter bufferedWriter) throws IOException { + public void saveLayout(BufferedWriter bufferedWriter) throws IOException { for (Character[] line : this.layout) { - for (Character symbol : line) { - bufferedWriter.append(symbol); - } + bufferedWriter.append(Arrays.toString(line)); bufferedWriter.newLine(); } } /** - * Reads the gate layout to relative block vectors + * Reads the layout and stores key information + * + *

This methods reads the layout and stores exits, entrances, border blocks and control blocks.

*/ private void readLayout() { List entranceList = new ArrayList<>(); List borderList = new ArrayList<>(); List controlList = new ArrayList<>(); - RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; - RelativeBlockVector lastExit = null; - int[] exitDepths = readLayout(controlList, entranceList, borderList); - - //Generate other possible exits - for (int x = 0; x < exitDepths.length; x++) { - relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0); - } - - //Add non-null exits to the exits list - for (int x = relativeExits.length - 1; x >= 0; x--) { - if (relativeExits[x] != null) { - lastExit = relativeExits[x]; - } else { - relativeExits[x] = lastExit; - } - - if (exitDepths[x] > 0) { - this.exits.add(relativeExits[x]); - } - } + readLayout(controlList, entranceList, borderList); this.entrances = entranceList.toArray(this.entrances); this.border = borderList.toArray(this.border); @@ -148,55 +135,74 @@ public class GateLayout { * @param controlList

The list of control blocks to save to

* @param entranceList

The list of entrances to save to

* @param borderList

The list of border blocks to save to

- * @return

A list of depths of possible extra exits

*/ - private int[] readLayout(List controlList, List entranceList, - List borderList) { - //Store the depth/line of each + private void readLayout(List controlList, List entranceList, + List borderList) { + //Store the lowest opening for each column int[] exitDepths = new int[layout[0].length]; + //A row is the same as one line in the gate file int lineCount = layout.length; - for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) { - int rowSize = layout[lineIndex].length; - for (int rowIndex = 0; rowIndex < rowSize; rowIndex++) { - Character key = layout[lineIndex][rowIndex]; - parseLayoutCharacter(key, rowIndex, lineIndex, exitDepths, controlList, entranceList, borderList); + for (int rowIndex = 0; rowIndex < lineCount; rowIndex++) { + Character[] row = layout[rowIndex]; + int rowSize = row.length; + for (int columnIndex = 0; columnIndex < rowSize; columnIndex++) { + Character key = row[columnIndex]; + parseLayoutCharacter(key, columnIndex, rowIndex, exitDepths, controlList, entranceList, borderList); + } + } + + //Generate all possible exits + for (int x = 0; x < exitDepths.length; x++) { + //Ignore invalid exits + if (exitDepths[x] > 0) { + this.exits.add(new RelativeBlockVector(x, exitDepths[x], 0)); } } - return exitDepths; } /** * Parses one character of the layout * - * @param key

The character read

- * @param rowIndex

The row of the read character

- * @param lineIndex

The line of the read character

+ * @param key

The read character

+ * @param columnIndex

The column containing the read character

+ * @param rowIndex

The row containing the read character

* @param exitDepths

The list of exit depths to save to

* @param controlList

The list of control blocks to save to

* @param entranceList

The list of entrances to save to

* @param borderList

The list of border blocks to save to

*/ - private void parseLayoutCharacter(Character key, int rowIndex, int lineIndex, int[] exitDepths, + private void parseLayoutCharacter(Character key, int columnIndex, int rowIndex, int[] exitDepths, List controlList, List entranceList, List borderList) { - //Add control blocks + //Add control blocks to the control block list if (key.equals(GateHandler.getControlBlockCharacter())) { - controlList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); + controlList.add(new RelativeBlockVector(columnIndex, rowIndex, 0)); } - if (key.equals(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) { - //Register entrances - entranceList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); - //Find the lowest exit block at a given x position - exitDepths[rowIndex] = lineIndex; - //Register exit + if (isOpening(key)) { + //Register entrance + entranceList.add(new RelativeBlockVector(columnIndex, rowIndex, 0)); + //Overwrite the lowest exit location for this column/x-coordinate + exitDepths[columnIndex] = rowIndex; + //Register exit if found if (key.equals(GateHandler.getExitCharacter())) { - this.exitBlock = new RelativeBlockVector(rowIndex, lineIndex, 0); + this.exitBlock = new RelativeBlockVector(columnIndex, rowIndex, 0); } } else if (!key.equals(GateHandler.getAnythingCharacter())) { - //Add border - borderList.add(new RelativeBlockVector(rowIndex, lineIndex, 0)); + //Register border block + borderList.add(new RelativeBlockVector(columnIndex, rowIndex, 0)); } } + + /** + * Checks whether the given character represents a gate opening + * + * @param character

The character to check

+ * @return

True if the character represents an opening

+ */ + private boolean isOpening(Character character) { + return character.equals(GateHandler.getEntranceCharacter()) || character.equals(GateHandler.getExitCharacter()); + } + } From fabe0dda8032be087cc7f39dcc592b4ef9ced277 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 17 Oct 2021 22:47:27 +0200 Subject: [PATCH 158/378] Fixes inconsistencies in coloring of the portal name when drawing signs. The - is now white. --- src/main/java/net/knarcraft/stargate/utility/SignHelper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index feaf8ba..d725eb9 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -19,7 +19,8 @@ public final class SignHelper { for (int index = 0; index <= 3; index++) { sign.setLine(index, ""); } - Stargate.setLine(sign, 0, "-" + portal.getName() + "-"); + Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + ChatColor.BLACK + portal.getName() + + ChatColor.WHITE + "-"); if (!portal.isActive()) { //Default sign text From d9ae5456ccdbde05736d7892aafb5ee9dd46c8f4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 03:35:59 +0200 Subject: [PATCH 159/378] Improves permission checking for vehicles with multiple passengers Changes some log messages into debug messages Makes sure that all player passengers of a vehicle have their permissions verified and fee paid. This ensures passengers won't get a free ride, or be allowed to access restricted areas by playing stowaway. --- .../listener/VehicleEventListener.java | 73 +++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 57d3ad4..6eb1002 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalTeleporter; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; @@ -59,19 +60,22 @@ public class VehicleEventListener implements Listener { * @param vehicle

The vehicle passing through

*/ private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { + String route = "VehicleEventListener::teleportVehicle"; + String prefix = Stargate.getString("prefix"); + if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - Stargate.logger.info(Stargate.getString("prefix") + "Found passenger vehicle"); + Stargate.debug(route, prefix + "Found passenger vehicle"); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Stargate.logger.info(Stargate.getString("prefix") + "Found empty vehicle"); + Stargate.debug(route, prefix + "Found empty vehicle"); Portal destinationPortal = entrancePortal.getDestination(); if (destinationPortal == null) { - Stargate.logger.warning(Stargate.getString("prefix") + "Unable to find portal destination"); + Stargate.debug(route, prefix + "Unable to find portal destination"); return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); - destinationPortal.teleport(vehicle, entrancePortal); + new PortalTeleporter(destinationPortal).teleport(vehicle, entrancePortal); } } @@ -84,34 +88,77 @@ public class VehicleEventListener implements Listener { */ private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { Player player = (Player) passengers.get(0); + //On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open + // to one player at a time, we only need to check if the portal is open to the driver. if (!entrancePortal.isOpenFor(player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } + //If no destination exists, the teleportation cannot happen Portal destinationPortal = entrancePortal.getDestination(player); if (destinationPortal == null) { return; } - //Make sure the user can access the portal - if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.close(false); - return; + //Make sure all player passengers are allowed to, and can afford to, enter the portal + for (Entity entity : passengers) { + if (entity instanceof Player && !playerCanTeleport((Player) entity, entrancePortal, destinationPortal)) { + return; + } } - //Transfer payment if necessary - int cost = EconomyHandler.getDefaultUseCost(player, entrancePortal, destinationPortal); + //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be + // run after it has been confirmed that all passengers are able to pay + int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { - if (EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost)) { + if (!takePlayerPayment(passengers, entrancePortal, cost)) { return; } } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); - destinationPortal.teleport(vehicle, entrancePortal); + new PortalTeleporter(destinationPortal).teleport(vehicle, entrancePortal); entrancePortal.close(false); } + /** + * Takes payment from all player passengers + * + * @param passengers

All passengers in the teleporting vehicle

+ * @param entrancePortal

The portal the vehicle is entering from

+ * @param cost

The cost each player has to pay

+ * @return

True if all player passengers paid successfully

+ */ + private static boolean takePlayerPayment(List passengers, Portal entrancePortal, int cost) { + for (Entity entity : passengers) { + //If the passenger is a player, make it pay + if (entity instanceof Player && EconomyHelper.cannotPayTeleportFee(entrancePortal, (Player) entity, cost)) { + return false; + } + } + return true; + } + + /** + * Checks whether the given player is allowed to and can afford to teleport + * + * @param player

The player trying to teleport

+ * @param entrancePortal

The portal the player is entering

+ * @param destinationPortal

The portal the player is to exit from

+ * @return

True if the player is allowed to teleport and is able to pay necessary fees

+ */ + private static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { + //Make sure the user can access the portal + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + entrancePortal.close(false); + return false; + } + + //Transfer payment if necessary + int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); + return cost <= 0 || EconomyHandler.canAffordFee(player, cost); + } + } From f96e8ed2da8b46f170e9a282e886ec7797fa8cc8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 03:36:56 +0200 Subject: [PATCH 160/378] Adds a method for checking if a player can afford a given fee --- .../knarcraft/stargate/utility/EconomyHandler.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index 66cc35e..ff6be4b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -103,6 +103,17 @@ public final class EconomyHandler { return EconomyHandler.chargePlayer(player, cost); } + /** + * Checks whether the given player can afford the given fee + * + * @param player

The player to check

+ * @param cost

The fee to pay

+ * @return

True if the player can afford to pay the fee

+ */ + public static boolean canAffordFee(Player player, int cost) { + return economy.getBalance(player) > cost; + } + /** * Charges the player for an action, if required * @@ -188,7 +199,7 @@ public final class EconomyHandler { * @param destination

The destination portal

* @return

The cost of using the portal

*/ - public static int getDefaultUseCost(Player player, Portal source, Portal destination) { + public static int getUseCost(Player player, Portal source, Portal destination) { //No payment required if (!EconomyHandler.useEconomy() || source.getOptions().isFree()) { return 0; From 982d8abf65b3ab6f83ee75b3fa116d6db016b613 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 03:41:16 +0200 Subject: [PATCH 161/378] Extracts teleportation code into the PortalTeleporter class to improve readability --- .../listener/PlayerEventListener.java | 14 +- .../listener/PortalEventListener.java | 4 +- .../net/knarcraft/stargate/portal/Portal.java | 390 +--------------- .../stargate/portal/PortalTeleporter.java | 441 ++++++++++++++++++ .../stargate/utility/BungeeHelper.java | 3 +- .../stargate/utility/PermissionHelper.java | 13 +- 6 files changed, 476 insertions(+), 389 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index eabed16..a875559 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; @@ -56,7 +57,7 @@ public class PlayerEventListener implements Listener { return; } //Teleport the player to the stargate - portal.teleport(player, portal, null); + new PortalTeleporter(portal).teleport(player, portal, null); } /** @@ -92,9 +93,9 @@ public class PlayerEventListener implements Listener { horse.setTamed(true); horse.setOwner(player); } - destination.teleport((Vehicle) playerVehicle, entrancePortal); + new PortalTeleporter(destination).teleport((Vehicle) playerVehicle, entrancePortal); } else { - destination.teleport(player, entrancePortal, event); + new PortalTeleporter(destination).teleport(player, entrancePortal, event); } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); entrancePortal.close(false); @@ -124,6 +125,11 @@ public class PlayerEventListener implements Listener { Portal destination = entrancePortal.getDestination(player); + //Catch always open portals without a valid destination to prevent the user for being teleported and denied + if (destination == null) { + return false; + } + //Decide if the anything stops the player from teleport if (PermissionHelper.playerCannotTeleport(entrancePortal, destination, player, event)) { return false; @@ -300,7 +306,7 @@ public class PlayerEventListener implements Listener { } //Teleport the player back to this gate, for sanity's sake - entrancePortal.teleport(player, entrancePortal, event); + new PortalTeleporter(entrancePortal).teleport(player, entrancePortal, event); //Send the SGBungee packet first, it will be queued by BC if required if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 6a63dcd..8779181 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.container.FromTheEndTeleportation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalTeleporter; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.Material; @@ -88,7 +89,8 @@ public class PortalEventListener implements Listener { Portal exitPortal = teleportation.getExit(); //Overwrite respawn location to respawn in front of the portal - event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation())); + event.setRespawnLocation(new PortalTeleporter(exitPortal).getExit(respawningPlayer, + respawningPlayer.getLocation())); //Properly close the portal to prevent it from staying in a locked state until it times out exitPortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index ae9dfa5..b8d7e28 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -3,35 +3,20 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; -import net.knarcraft.stargate.event.StargateEntityPortalEvent; import net.knarcraft.stargate.event.StargateOpenEvent; -import net.knarcraft.stargate.event.StargatePlayerPortalEvent; import net.knarcraft.stargate.utility.DirectionHelper; -import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Axis; -import org.bukkit.Chunk; -import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -import org.bukkit.block.data.Bisected; -import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Orientable; -import org.bukkit.block.data.type.Slab; -import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -import org.bukkit.entity.Vehicle; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.Collections; @@ -39,7 +24,6 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.UUID; -import java.util.logging.Level; /** * This class represents a portal in space which points to one or several portals @@ -473,358 +457,6 @@ public class Portal { return player != null && player.getName().equalsIgnoreCase(this.player.getName()); } - /** - * 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(player, traveller); - - //Rotate the player to face out from the portal - adjustRotation(exit); - - //Call the StargatePlayerPortalEvent to allow plugins to change destination - if (!origin.equals(this)) { - StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, - this, exit); - Stargate.server.getPluginManager().callEvent(stargatePlayerPortalEvent); - //Teleport is cancelled. Teleport the player back to where it came from - if (stargatePlayerPortalEvent.isCancelled()) { - origin.teleport(player, origin, event); - return; - } - //Update exit if needed - exit = stargatePlayerPortalEvent.getExit(); - } - - //Load chunks to make sure not to teleport to the void - loadChunks(); - - //If no event is passed in, assume it's a teleport, and act as such - if (event == null) { - player.teleport(exit); - } else { - //The new method to teleport in a move event is set the "to" field. - event.setTo(exit); - } - } - - /** - * Adjusts the rotation of the player to face out from the portal - * - * @param exit

The location the player will exit from

- */ - private void adjustRotation(Location exit) { - int adjust = 0; - if (options.isBackwards()) { - adjust = 180; - } - float newYaw = (this.getYaw() + adjust) % 360; - Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); - exit.setYaw(newYaw); - } - - /** - * Teleports a vehicle to this portal - * - * @param vehicle

The vehicle to teleport

- * @param origin

The portal the vehicle teleports from

- */ - public void teleport(final Vehicle vehicle, Portal origin) { - Location traveller = vehicle.getLocation(); - Location exit = getExit(vehicle, traveller); - - double velocity = vehicle.getVelocity().length(); - - //Stop and teleport - vehicle.setVelocity(new Vector()); - - //Get new velocity - Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(this.getYaw()); - Vector newVelocity = newVelocityDirection.multiply(velocity); - adjustRotation(exit); - - List passengers = vehicle.getPassengers(); - - //Call the StargateEntityPortalEvent to allow plugins to change destination - if (!origin.equals(this)) { - StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(vehicle, origin, - this, exit); - Stargate.server.getPluginManager().callEvent(stargateEntityPortalEvent); - //Teleport is cancelled. Teleport the entity back to where it came from - if (stargateEntityPortalEvent.isCancelled()) { - origin.teleport(vehicle, origin); - return; - } - //Update exit if needed - exit = stargateEntityPortalEvent.getExit(); - } - - //Load chunks to make sure not to teleport to the void - loadChunks(); - - if (!passengers.isEmpty()) { - if (!(vehicle instanceof LivingEntity)) { - World vehicleWorld = exit.getWorld(); - if (vehicleWorld == null) { - Stargate.logger.warning(Stargate.getString("prefix") + - "Unable to get the world to teleport the vehicle to"); - return; - } - putPassengersInNewVehicle(vehicle, passengers, vehicleWorld, exit, newVelocity); - } else { - teleportLivingVehicle(vehicle, exit, passengers); - } - } else { - vehicle.teleport(exit); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> vehicle.setVelocity(newVelocity), 1); - } - } - - /** - * Teleport a vehicle which is not a minecart or a boat - * - * @param vehicle

The vehicle to teleport

- * @param exit

The location the vehicle will exit

- * @param passengers

The passengers of the vehicle

- */ - private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { - vehicle.eject(); - vehicle.teleport(exit); - handleVehiclePassengers(passengers, vehicle, 2); - } - - /** - * Creates a new vehicle equal to the player's previous vehicle and puts any passengers inside - * - *

While it is possible to teleport boats and minecarts using the same methods as "teleportLivingVehicle", this - * method works better with CraftBook with minecart options enabled. Using normal teleportation, CraftBook destroys - * the minecart once the player is ejected, causing the minecart to disappear and the player to teleport without it.

- * - * @param vehicle

The player's old vehicle

- * @param passengers

A list of all passengers in the vehicle

- * @param vehicleWorld

The world to spawn the new vehicle in

- * @param exit

The exit location to spawn the new vehicle on

- * @param newVelocity

The new velocity of the new vehicle

- */ - private void putPassengersInNewVehicle(Vehicle vehicle, List passengers, World vehicleWorld, Location exit, - Vector newVelocity) { - Vehicle newVehicle = vehicleWorld.spawn(exit, vehicle.getClass()); - vehicle.eject(); - vehicle.remove(); - newVehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle, 1); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> newVehicle.setVelocity(newVelocity), 1); - } - - /** - * Ejects, teleports and adds all passengers to the target vehicle - * - * @param passengers

The passengers to handle

- * @param targetVehicle

The vehicle the passengers should be put into

- * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

- */ - private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, long delay) { - for (Entity passenger : passengers) { - passenger.eject(); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> teleportAndAddPassenger(targetVehicle, passenger), delay); - } - } - - /** - * Teleports and adds a passenger to a vehicle - * - *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, - * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

- * - * @param targetVehicle

The vehicle to add the passenger to

- * @param passenger

The passenger to teleport and add

- */ - private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { - if (!passenger.teleport(targetVehicle.getLocation())) { - Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); - } - if (!targetVehicle.addPassenger(passenger)) { - Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); - } - } - - /** - * 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 - RelativeBlockVector relativeExit = gate.getLayout().getExit(); - if (relativeExit != null) { - BlockLocation exit = getBlockAt(relativeExit); - float portalYaw = this.getYaw(); - if (options.isBackwards()) { - portalYaw += 180; - } - exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); - - if (entity != null) { - double entitySize = EntityHelper.getEntityMaxSize(entity); - if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); - } - } - } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + - "Missing destination point in .gate file " + gate.getFilename()); - } - - return adjustExitLocation(traveller, exitLocation); - } - - /** - * Adjusts the positioning of the portal exit to prevent the given entity from suffocating - * - * @param relativeExit

The relative exit defined as the portal's exit

- * @param exitLocation

The currently calculated portal exit

- * @param entity

The travelling entity

- * @return

A location which won't suffocate the entity inside the portal

- */ - private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { - //Go left to find start of opening - RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); - - //Go right to find the end of the opening - RelativeBlockVector openingRight = getPortalExitEdge(relativeExit, 1); - - //Get the width to check if the entity fits - int openingWidth = openingRight.getRight() - openingLeft.getRight() + 1; - int existingOffset = relativeExit.getRight() - openingLeft.getRight(); - double newOffset = (openingWidth - existingOffset) / 2D; - - //Remove the half offset for better centering - if (openingWidth > 1) { - newOffset -= 0.5; - } - exitLocation = DirectionHelper.moveLocation(exitLocation, newOffset, 0, 0, getYaw()); - - //Move large entities further from the portal, especially if this portal will teleport them at once - double entitySize = EntityHelper.getEntityMaxSize(entity); - int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); - if (entitySize > 1) { - if (options.isAlwaysOn()) { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, (entityBoxSize / 2D), - getYaw()); - } else { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, - (entitySize / 2D) - 1, getYaw()); - } - } - - //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's - //moved one block out. - if (entity instanceof AbstractHorse) { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, 1, getYaw()); - } - - return exitLocation; - } - - /** - * Gets one of the edges of a portal's opening/exit - * - * @param relativeExit

The known exit to start from

- * @param direction

The direction to move (+1 for right, -1 for left)

- * @return

The right or left edge of the opening

- */ - private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { - RelativeBlockVector openingEdge = relativeExit; - do { - RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, - openingEdge.getDepth(), openingEdge.getDistance()); - if (gate.getLayout().getExits().contains(possibleOpening)) { - openingEdge = possibleOpening; - } else { - break; - } - } while (true); - return openingEdge; - } - - /** - * Adjusts an exit location with rotation and slab height incrementation - * - * @param traveller

The location of the travelling entity

- * @param exitLocation

The exit location generated

- * @return

The location the travelling entity should be teleported to

- */ - private Location adjustExitLocation(Location traveller, Location exitLocation) { - if (exitLocation != null) { - BlockData blockData = getWorld().getBlockAt(exitLocation).getBlockData(); - if ((blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) || - (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { - //Prevent traveller from spawning inside a slab - Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); - exitLocation.add(0, 1, 0); - } else if (blockData.getMaterial() == Material.WATER) { - //If there's water outside, go one up to allow for boat teleportation - Stargate.debug("adjustExitLocation", "Added a block to get above a block of water"); - exitLocation.add(0, 1, 0); - } - - exitLocation.setPitch(traveller.getPitch()); - return exitLocation; - } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + - "Unable to generate exit location"); - } - return traveller; - } - - /** - * Loads the chunks outside the portal's entrance - */ - private void loadChunks() { - for (Chunk chunk : getChunksToLoad()) { - chunk.addPluginChunkTicket(Stargate.stargate); - //Allow the chunk to unload after 3 seconds - Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); - } - } - - /** - * Gets all relevant chunks near this portal's entrance which need to be loaded before teleportation - * - * @return

A list of chunks to load

- */ - private List getChunksToLoad() { - List chunksToLoad = new ArrayList<>(); - for (RelativeBlockVector vector : gate.getLayout().getEntrances()) { - BlockLocation entranceLocation = getBlockAt(vector); - Chunk chunk = entranceLocation.getChunk(); - if (!chunksToLoad.contains(chunk)) { - chunksToLoad.add(chunk); - } - - //Get the chunk in front of the gate corner - int blockOffset = options.isBackwards() ? -5 : 5; - Location fiveBlocksForward = DirectionHelper.moveLocation(entranceLocation, 0, 0, blockOffset, - getYaw()); - Chunk forwardChunk = fiveBlocksForward.getChunk(); - if (!chunksToLoad.contains(forwardChunk)) { - chunksToLoad.add(forwardChunk); - } - } - return chunksToLoad; - } - /** * Gets the identity (sign) location of the portal * @@ -1017,7 +649,7 @@ public class Portal { } /** - * Draws the sign on this portal + * Draws this portal's sign */ public final void drawSign() { BlockState state = getSignLocation().getBlock().getState(); @@ -1032,7 +664,7 @@ public class Portal { } /** - * Gets the block at a relative block vector location + * Gets the block at the given location relative to this portal's location * * @param vector

The relative block vector

* @return

The block at the given relative position

@@ -1057,15 +689,16 @@ public class Portal { /** * Gets a list of block locations from a list of relative block vectors * + *

The block locations will be calculated by using this portal's top-left block as the origin for the relative + * vectors..

+ * * @param vectors

The relative block vectors to convert

* @return

A list of block locations

*/ private BlockLocation[] relativeBlockVectorsToBlockLocations(RelativeBlockVector[] vectors) { BlockLocation[] locations = new BlockLocation[vectors.length]; - int i = 0; - - for (RelativeBlockVector vector : vectors) { - locations[i++] = getBlockAt(vector); + for (int i = 0; i < vectors.length; i++) { + locations[i] = getBlockAt(vectors[i]); } return locations; } @@ -1086,14 +719,14 @@ public class Portal { } @Override - public boolean equals(Object obj) { - if (this == obj) { + public boolean equals(Object object) { + if (this == object) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (object == null || getClass() != object.getClass()) { return false; } - Portal other = (Portal) obj; + Portal other = (Portal) object; if (name == null) { if (other.name != null) { return false; @@ -1101,6 +734,7 @@ public class Portal { } else if (!name.equalsIgnoreCase(other.name)) { return false; } + //If none of the portals have a name, check if the network is the same if (network == null) { return other.network == null; } else { diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java new file mode 100644 index 0000000..7004608 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java @@ -0,0 +1,441 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.ChunkUnloadRequest; +import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.event.StargateEntityPortalEvent; +import net.knarcraft.stargate.event.StargatePlayerPortalEvent; +import net.knarcraft.stargate.utility.DirectionHelper; +import net.knarcraft.stargate.utility.EntityHelper; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Slab; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +/** + * The portal teleporter takes care of the actual portal teleportation + */ +public class PortalTeleporter { + + private final Portal portal; + + /** + * Instantiates a new portal teleporter + * + * @param portal

The portal which is the target of the teleportation

+ */ + public PortalTeleporter(Portal portal) { + this.portal = portal; + } + + /** + * Teleports a vehicle to this teleporter's portal + * + *

It is assumed that if a vehicle contains any players, their permissions have already been validated before + * calling this method.

+ * + * @param vehicle

The vehicle to teleport

+ * @param origin

The portal the vehicle teleports from

+ */ + public void teleport(final Vehicle vehicle, Portal origin) { + Location traveller = vehicle.getLocation(); + Location exit = getExit(vehicle, traveller); + + double velocity = vehicle.getVelocity().length(); + + //Stop and teleport + vehicle.setVelocity(new Vector()); + + //Get new velocity + Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); + Vector newVelocity = newVelocityDirection.multiply(velocity); + + //Make sure the vehicle points out from the portal + adjustRotation(exit); + + //Call the StargateEntityPortalEvent to allow plugins to change destination + if (!origin.equals(portal)) { + exit = triggerEntityPortalEvent(origin, exit, vehicle); + if (exit == null) { + return; + } + } + + //Teleport the vehicle + teleportVehicle(vehicle, exit, newVelocity); + } + + /** + * Teleports a vehicle with any passengers to the given location + * + * @param vehicle

The vehicle to teleport

+ * @param exit

The location the vehicle should be teleported to

+ * @param newVelocity

The velocity to give the vehicle right after teleportation

+ */ + private void teleportVehicle(Vehicle vehicle, Location exit, Vector newVelocity) { + //Load chunks to make sure not to teleport to the void + loadChunks(); + + List passengers = vehicle.getPassengers(); + if (!passengers.isEmpty()) { + if (!(vehicle instanceof LivingEntity)) { + //Teleport a normal vehicle with passengers (minecart or boat) + putPassengersInNewVehicle(vehicle, passengers, exit, newVelocity); + } else { + //Teleport a living vehicle with passengers (pig, horse, donkey, strider) + teleportLivingVehicle(vehicle, exit, passengers); + } + } else { + //Teleport an empty vehicle + vehicle.teleport(exit); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + () -> vehicle.setVelocity(newVelocity), 1); + } + } + + /** + * Triggers the entity portal event to allow plugins to change the exit location + * + * @param origin

The origin portal teleported from

+ * @param exit

The exit location to teleport the vehicle to

+ * @param vehicle

The teleporting vehicle

+ * @return

The location the vehicle should be teleported to, or null if the event was cancelled

+ */ + private Location triggerEntityPortalEvent(Portal origin, Location exit, Vehicle vehicle) { + StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(vehicle, origin, + portal, exit); + Stargate.server.getPluginManager().callEvent(stargateEntityPortalEvent); + //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake + if (stargateEntityPortalEvent.isCancelled()) { + new PortalTeleporter(origin).teleport(vehicle, origin); + return null; + } + return stargateEntityPortalEvent.getExit(); + } + + private Location triggerPlayerPortalEvent(Portal origin, Location exit, Player player, PlayerMoveEvent event) { + StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, + portal, exit); + Stargate.server.getPluginManager().callEvent(stargatePlayerPortalEvent); + //Teleport is cancelled. Teleport the player back to where it came from + if (stargatePlayerPortalEvent.isCancelled()) { + new PortalTeleporter(origin).teleport(player, origin, event); + return null; + } + return stargatePlayerPortalEvent.getExit(); + } + + /** + * Teleports a player to this teleporter's 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(player, traveller); + + //Rotate the player to face out from the portal + adjustRotation(exit); + + //Call the StargatePlayerPortalEvent to allow plugins to change destination + if (!origin.equals(portal)) { + exit = triggerPlayerPortalEvent(origin, exit, player, event); + if (exit == null) { + return; + } + } + + //Load chunks to make sure not to teleport to the void + loadChunks(); + + //If no event is passed in, assume it's a teleport, and act as such + if (event == null) { + player.teleport(exit); + } else { + //The new method to teleport in a move event is set the "to" field. + event.setTo(exit); + } + } + + /** + * Adjusts the rotation of the player to face out from the portal + * + * @param exit

The location the player will exit from

+ */ + private void adjustRotation(Location exit) { + int adjust = 0; + if (portal.getOptions().isBackwards()) { + adjust = 180; + } + float newYaw = (portal.getYaw() + adjust) % 360; + Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); + exit.setYaw(newYaw); + } + + /** + * Teleport a vehicle which is not a minecart or a boat + * + * @param vehicle

The vehicle to teleport

+ * @param exit

The location the vehicle will exit

+ * @param passengers

The passengers of the vehicle

+ */ + private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { + vehicle.eject(); + vehicle.teleport(exit); + handleVehiclePassengers(passengers, vehicle, 2); + } + + /** + * Creates a new vehicle equal to the player's previous vehicle and puts any passengers inside + * + *

While it is possible to teleport boats and minecarts using the same methods as "teleportLivingVehicle", this + * method works better with CraftBook with minecart options enabled. Using normal teleportation, CraftBook destroys + * the minecart once the player is ejected, causing the minecart to disappear and the player to teleport without it.

+ * + * @param vehicle

The player's old vehicle

+ * @param passengers

A list of all passengers in the vehicle

+ * @param exit

The exit location to spawn the new vehicle on

+ * @param newVelocity

The new velocity of the new vehicle

+ */ + private void putPassengersInNewVehicle(Vehicle vehicle, List passengers, Location exit, + Vector newVelocity) { + World vehicleWorld = exit.getWorld(); + if (vehicleWorld == null) { + Stargate.logger.warning(Stargate.getString("prefix") + + "Unable to get the world to teleport the vehicle to"); + return; + } + //Spawn a new vehicle + Vehicle newVehicle = vehicleWorld.spawn(exit, vehicle.getClass()); + //Remove the old vehicle + vehicle.eject(); + vehicle.remove(); + //Set rotation, add passengers and restore velocity + newVehicle.setRotation(exit.getYaw(), exit.getPitch()); + handleVehiclePassengers(passengers, newVehicle, 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + () -> newVehicle.setVelocity(newVelocity), 1); + } + + /** + * Ejects, teleports and adds all passengers to the target vehicle + * + * @param passengers

The passengers to handle

+ * @param targetVehicle

The vehicle the passengers should be put into

+ * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

+ */ + private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, long delay) { + for (Entity passenger : passengers) { + passenger.eject(); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, + () -> teleportAndAddPassenger(targetVehicle, passenger), delay); + } + } + + /** + * Teleports and adds a passenger to a vehicle + * + *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, + * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

+ * + * @param targetVehicle

The vehicle to add the passenger to

+ * @param passenger

The passenger to teleport and add

+ */ + private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { + if (!passenger.teleport(targetVehicle.getLocation())) { + Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); + } + if (!targetVehicle.addPassenger(passenger)) { + Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); + } + } + + /** + * 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 + RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); + if (relativeExit != null) { + BlockLocation exit = portal.getBlockAt(relativeExit); + float portalYaw = portal.getYaw(); + if (portal.getOptions().isBackwards()) { + portalYaw += 180; + } + exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); + + if (entity != null) { + double entitySize = EntityHelper.getEntityMaxSize(entity); + if (entitySize > 1) { + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); + } + } + } else { + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + "Missing destination point in .gate file " + portal.getGate().getFilename()); + } + + return adjustExitLocation(traveller, exitLocation); + } + + /** + * Adjusts the positioning of the portal exit to prevent the given entity from suffocating + * + * @param relativeExit

The relative exit defined as the portal's exit

+ * @param exitLocation

The currently calculated portal exit

+ * @param entity

The travelling entity

+ * @return

A location which won't suffocate the entity inside the portal

+ */ + private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { + //Go left to find start of opening + RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); + + //Go right to find the end of the opening + RelativeBlockVector openingRight = getPortalExitEdge(relativeExit, 1); + + //Get the width to check if the entity fits + int openingWidth = openingRight.getRight() - openingLeft.getRight() + 1; + int existingOffset = relativeExit.getRight() - openingLeft.getRight(); + double newOffset = (openingWidth - existingOffset) / 2D; + + //Remove the half offset for better centering + if (openingWidth > 1) { + newOffset -= 0.5; + } + exitLocation = DirectionHelper.moveLocation(exitLocation, newOffset, 0, 0, portal.getYaw()); + + //Move large entities further from the portal, especially if this teleporter's portal will teleport them at once + double entitySize = EntityHelper.getEntityMaxSize(entity); + int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); + if (entitySize > 1) { + if (portal.getOptions().isAlwaysOn()) { + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, (entityBoxSize / 2D), + portal.getYaw()); + } else { + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, + (entitySize / 2D) - 1, portal.getYaw()); + } + } + + //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's + //moved one block out. + if (entity instanceof AbstractHorse) { + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, 1, portal.getYaw()); + } + + return exitLocation; + } + + /** + * Gets one of the edges of a portal's opening/exit + * + * @param relativeExit

The known exit to start from

+ * @param direction

The direction to move (+1 for right, -1 for left)

+ * @return

The right or left edge of the opening

+ */ + private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { + RelativeBlockVector openingEdge = relativeExit; + do { + RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, + openingEdge.getDepth(), openingEdge.getDistance()); + if (portal.getGate().getLayout().getExits().contains(possibleOpening)) { + openingEdge = possibleOpening; + } else { + break; + } + } while (true); + return openingEdge; + } + + /** + * Adjusts an exit location with rotation and slab height incrementation + * + * @param traveller

The location of the travelling entity

+ * @param exitLocation

The exit location generated

+ * @return

The location the travelling entity should be teleported to

+ */ + private Location adjustExitLocation(Location traveller, Location exitLocation) { + if (exitLocation != null) { + BlockData blockData = portal.getWorld().getBlockAt(exitLocation).getBlockData(); + if ((blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) || + (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { + //Prevent traveller from spawning inside a slab + Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); + exitLocation.add(0, 1, 0); + } else if (blockData.getMaterial() == Material.WATER) { + //If there's water outside, go one up to allow for boat teleportation + Stargate.debug("adjustExitLocation", "Added a block to get above a block of water"); + exitLocation.add(0, 1, 0); + } + + exitLocation.setPitch(traveller.getPitch()); + return exitLocation; + } else { + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + "Unable to generate exit location"); + } + return traveller; + } + + /** + * Loads the chunks outside the portal's entrance + */ + private void loadChunks() { + for (Chunk chunk : getChunksToLoad()) { + chunk.addPluginChunkTicket(Stargate.stargate); + //Allow the chunk to unload after 3 seconds + Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); + } + } + + /** + * Gets all relevant chunks near this teleporter's portal's entrance which need to be loaded before teleportation + * + * @return

A list of chunks to load

+ */ + private List getChunksToLoad() { + List chunksToLoad = new ArrayList<>(); + for (RelativeBlockVector vector : portal.getGate().getLayout().getEntrances()) { + BlockLocation entranceLocation = portal.getBlockAt(vector); + Chunk chunk = entranceLocation.getChunk(); + //Make sure not to load chunks twice + if (!chunksToLoad.contains(chunk)) { + chunksToLoad.add(chunk); + } + + //Get the chunk in front of the gate entrance + int blockOffset = portal.getOptions().isBackwards() ? -5 : 5; + Location fiveBlocksForward = DirectionHelper.moveLocation(entranceLocation, 0, 0, blockOffset, + portal.getYaw()); + //Load the chunk five blocks forward to make sure the teleported entity will never spawn in unloaded chunks + Chunk forwardChunk = fiveBlocksForward.getChunk(); + if (!chunksToLoad.contains(forwardChunk)) { + chunksToLoad.add(forwardChunk); + } + } + return chunksToLoad; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 1137b08..8380c8b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalTeleporter; import org.bukkit.entity.Player; import java.io.ByteArrayInputStream; @@ -130,7 +131,7 @@ public final class BungeeHelper { Stargate.logger.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); return; } - destinationPortal.teleport(player, destinationPortal, null); + new PortalTeleporter(destinationPortal).teleport(player, destinationPortal, null); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 6038151..308dfcf 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalOption; +import net.knarcraft.stargate.portal.PortalTeleporter; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; @@ -99,13 +100,15 @@ public final class PermissionHelper { public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { boolean deny = false; // Check if player has access to this server for Bungee gates - if (entrancePortal.getOptions().isBungee() && !PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { + if (entrancePortal.getOptions().isBungee() && !PermissionHelper.canAccessServer(player, + entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (!entrancePortal.getOptions().isBungee() && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { + } else if (!entrancePortal.getOptions().isBungee() && PermissionHelper.cannotAccessWorld(player, + destination.getWorld().getName())) { Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } @@ -387,7 +390,7 @@ public final class PermissionHelper { // Not open for this player if (!entrancePortal.isOpenFor(player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.teleport(player, entrancePortal, event); + new PortalTeleporter(entrancePortal).teleport(player, entrancePortal, event); return true; } @@ -399,13 +402,13 @@ public final class PermissionHelper { //Player cannot access portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.teleport(player, entrancePortal, event); + new PortalTeleporter(entrancePortal).teleport(player, entrancePortal, event); entrancePortal.close(false); return true; } //Player cannot pay for teleportation - int cost = EconomyHandler.getDefaultUseCost(player, entrancePortal, destination); + int cost = EconomyHandler.getUseCost(player, entrancePortal, destination); if (cost > 0) { return EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost); } From ac045fa7db547f9e294dc884214611f903efb7ce Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 04:00:18 +0200 Subject: [PATCH 162/378] Fixes a severe bug caused by trying to simplify GateLayout's saveLayout method --- src/main/java/net/knarcraft/stargate/portal/GateLayout.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index 00d3278..e9f4d11 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -107,7 +107,9 @@ public class GateLayout { */ public void saveLayout(BufferedWriter bufferedWriter) throws IOException { for (Character[] line : this.layout) { - bufferedWriter.append(Arrays.toString(line)); + for (Character character : line) { + bufferedWriter.append(character); + } bufferedWriter.newLine(); } } From 27b1f0641e2e88f794bba82fc935afdc7646f6a7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 14:57:12 +0200 Subject: [PATCH 163/378] Adds some block location tests --- .../stargate/container/BlockLocationTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java diff --git a/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java new file mode 100644 index 0000000..c3cd916 --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java @@ -0,0 +1,50 @@ +package net.knarcraft.stargate.container; + +import be.seeseemelk.mockbukkit.WorldMock; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class BlockLocationTest { + + @Test + public void makeRelativeBlockLocationTest() { + WorldMock world = new WorldMock(); + BlockLocation startLocation = new BlockLocation(world, 5, 4, 3); + + //Move to some other, different location + BlockLocation relativeLocation = startLocation.makeRelativeBlockLocation(4, 6, 8); + Assertions.assertNotEquals(startLocation, relativeLocation); + + //Move back to make sure we can go back to where we started by going in the opposite direction + BlockLocation sameAsStartLocation = relativeLocation.makeRelativeBlockLocation(-4, -6, -8); + Assertions.assertEquals(startLocation, sameAsStartLocation); + } + + @Test + public void getRelativeLocationTest() { + WorldMock world = new WorldMock(); + BlockLocation startLocation = new BlockLocation(world, 7, 3, 6); + + RelativeBlockVector relativeBlockVector = new RelativeBlockVector(2, 1, 3); + BlockLocation relativeLocation1 = startLocation.getRelativeLocation(relativeBlockVector, 0); + //With yaw = 0, going right goes in the x direction, and distance goes in the z direction, while y is decremented + BlockLocation targetLocation1 = new BlockLocation(world, 9, 2, 9); + Assertions.assertEquals(targetLocation1, relativeLocation1); + + BlockLocation relativeLocation2 = startLocation.getRelativeLocation(relativeBlockVector, 90); + //With yaw = 90, going right goes in the z direction, and distance goes in the -x direction, while y is decremented + BlockLocation targetLocation2 = new BlockLocation(world, 4, 2, 8); + Assertions.assertEquals(targetLocation2, relativeLocation2); + + BlockLocation relativeLocation3 = startLocation.getRelativeLocation(relativeBlockVector, 180); + //With yaw = 180, going right goes in the -x direction, and distance goes in the -z direction, while y is decremented + BlockLocation targetLocation3 = new BlockLocation(world, 5, 2, 3); + Assertions.assertEquals(targetLocation3, relativeLocation3); + + BlockLocation relativeLocation4 = startLocation.getRelativeLocation(relativeBlockVector, 270); + //With yaw = 270, going right goes in the -z direction, and distance goes in the x direction, while y is decremented + BlockLocation targetLocation4 = new BlockLocation(world, 10, 2, 4); + Assertions.assertEquals(targetLocation4, relativeLocation4); + } + +} From 8c16ddbed53725c5a604b4235ee112c8d50542ce Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 15:22:55 +0200 Subject: [PATCH 164/378] Adds some tests to the relative block vector --- .../container/RelativeBlockVectorTest.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java diff --git a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java new file mode 100644 index 0000000..54613f1 --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java @@ -0,0 +1,53 @@ +package net.knarcraft.stargate.container; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class RelativeBlockVectorTest { + + @Test + public void addToVectorTest() { + int right = 5; + int depth = 5; + int distance = 3; + + RelativeBlockVector relativeBlockVector = new RelativeBlockVector(right, depth, distance); + + for (int i = 0; i < 1000; i++) { + int randomValue = getRandomNumber(); + RelativeBlockVector newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.RIGHT, randomValue); + Assertions.assertEquals(new RelativeBlockVector(right + randomValue, depth, distance), newVector); + + newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.DISTANCE, randomValue); + Assertions.assertEquals(new RelativeBlockVector(right, depth, distance + randomValue), newVector); + + newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.DEPTH, randomValue); + Assertions.assertEquals(new RelativeBlockVector(right, depth + randomValue, distance), newVector); + } + } + + @Test + public void invertTest() { + for (int i = 0; i < 1000; i++) { + int randomNumber1 = getRandomNumber(); + int randomNumber2 = getRandomNumber(); + int randomNumber3 = getRandomNumber(); + + RelativeBlockVector relativeBlockVector = new RelativeBlockVector(randomNumber1, randomNumber2, + randomNumber3); + RelativeBlockVector invertedBlockVector = new RelativeBlockVector(-randomNumber1, -randomNumber2, + -randomNumber3); + Assertions.assertEquals(invertedBlockVector, relativeBlockVector.invert()); + } + } + + /** + * Gets a random number between -500 and 500 + * + * @return

A random number between -500 and 500

+ */ + private int getRandomNumber() { + return (int) ((Math.random() - 0.5) * 1000); + } + +} From f4ec5e05d6f2f407dd96c1ce51047d1d0b26d7a6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 18:34:35 +0200 Subject: [PATCH 165/378] Improves sign drawing during portal loading Adds "Invalid gate" to the last line of portals with an invalid or unloaded gate type Re-draws all portals' signs on load in case some invalid portals becomes valid. This also updates any formatting --- .../net/knarcraft/stargate/portal/PortalHandler.java | 10 ++++++++++ src/main/resources/lang/en.txt | 1 + 2 files changed, 11 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 3f9d947..1ff3bb6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -937,6 +937,11 @@ public class PortalHandler { Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), portalCounts.getFirstValue())); + + //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since + for (Portal portal : allPortals) { + portal.drawSign(); + } return true; } catch (Exception e) { Stargate.logger.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + lineIndex); @@ -962,6 +967,11 @@ public class PortalHandler { portalLocation.setTopLeft(new BlockLocation(world, portalData[6])); Gate gate = GateHandler.getGateByName(portalData[7]); if (gate == null) { + //Mark the sign as invalid to reduce some player confusion + Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); + Stargate.setLine(sign, 3, Stargate.getString("signInvalidGate")); + sign.update(); + Stargate.logger.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + " does not exist [" + portalData[7] + "]"); return; diff --git a/src/main/resources/lang/en.txt b/src/main/resources/lang/en.txt index b2250d5..3d40ae4 100644 --- a/src/main/resources/lang/en.txt +++ b/src/main/resources/lang/en.txt @@ -28,6 +28,7 @@ signRightClick=Right click signToUse=to use gate signRandom=Random signDisconnected=Disconnected +signInvalidGate=Invalid gate bungeeDisabled=BungeeCord support is disabled. bungeeDeny=You do not have permission to create BungeeCord gates. From 0506cf1b6121337212dc98027352cf8e2891f1a9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 18:38:36 +0200 Subject: [PATCH 166/378] Splits the PortalTeleporter into a PlayerTeleporter and a VehicleTeleporter for better structuring Moves player-related teleportation code to PlayerTeleporter, moves vehicle-related teleportation code to VehicleTeleporter and makes them both extend the Teleporter which now contains all common teleportation code. --- .../listener/PlayerEventListener.java | 11 +- .../listener/PortalEventListener.java | 4 +- .../listener/VehicleEventListener.java | 6 +- .../knarcraft/stargate/portal/GateLayout.java | 1 - .../stargate/portal/PlayerTeleporter.java | 79 ++++ .../stargate/portal/PortalTeleporter.java | 441 ------------------ .../knarcraft/stargate/portal/Teleporter.java | 228 +++++++++ .../stargate/portal/VehicleTeleporter.java | 188 ++++++++ .../stargate/utility/BungeeHelper.java | 4 +- .../stargate/utility/EconomyHandler.java | 2 +- .../stargate/utility/PermissionHelper.java | 6 +- 11 files changed, 512 insertions(+), 458 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java delete mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java create mode 100644 src/main/java/net/knarcraft/stargate/portal/Teleporter.java create mode 100644 src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index a875559..8ed2e48 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -2,9 +2,10 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalTeleporter; +import net.knarcraft.stargate.portal.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; @@ -57,7 +58,7 @@ public class PlayerEventListener implements Listener { return; } //Teleport the player to the stargate - new PortalTeleporter(portal).teleport(player, portal, null); + new PlayerTeleporter(portal, player).teleport(portal, null); } /** @@ -93,9 +94,9 @@ public class PlayerEventListener implements Listener { horse.setTamed(true); horse.setOwner(player); } - new PortalTeleporter(destination).teleport((Vehicle) playerVehicle, entrancePortal); + new VehicleTeleporter(destination, (Vehicle) playerVehicle).teleport(entrancePortal); } else { - new PortalTeleporter(destination).teleport(player, entrancePortal, event); + new PlayerTeleporter(destination, player).teleport(entrancePortal, event); } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); entrancePortal.close(false); @@ -306,7 +307,7 @@ public class PlayerEventListener implements Listener { } //Teleport the player back to this gate, for sanity's sake - new PortalTeleporter(entrancePortal).teleport(player, entrancePortal, event); + new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); //Send the SGBungee packet first, it will be queued by BC if required if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 8779181..e484895 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -1,9 +1,9 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.container.FromTheEndTeleportation; +import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalTeleporter; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.Material; @@ -89,7 +89,7 @@ public class PortalEventListener implements Listener { Portal exitPortal = teleportation.getExit(); //Overwrite respawn location to respawn in front of the portal - event.setRespawnLocation(new PortalTeleporter(exitPortal).getExit(respawningPlayer, + event.setRespawnLocation(new PlayerTeleporter(exitPortal, respawningPlayer).getExit(respawningPlayer, respawningPlayer.getLocation())); //Properly close the portal to prevent it from staying in a locked state until it times out exitPortal.close(false); diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 6eb1002..5a131f7 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,7 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalTeleporter; +import net.knarcraft.stargate.portal.VehicleTeleporter; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; @@ -75,7 +75,7 @@ public class VehicleEventListener implements Listener { } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); - new PortalTeleporter(destinationPortal).teleport(vehicle, entrancePortal); + new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); } } @@ -118,7 +118,7 @@ public class VehicleEventListener implements Listener { } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); - new PortalTeleporter(destinationPortal).teleport(vehicle, entrancePortal); + new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); entrancePortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java index e9f4d11..b2583d7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateLayout.java @@ -5,7 +5,6 @@ import net.knarcraft.stargate.container.RelativeBlockVector; import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java new file mode 100644 index 0000000..e71ec4d --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java @@ -0,0 +1,79 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.event.StargatePlayerPortalEvent; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerMoveEvent; + +/** + * The portal teleporter takes care of the actual portal teleportation for any players + */ +public class PlayerTeleporter extends Teleporter { + + private final Player player; + + /** + * Instantiates a new player teleporter + * + * @param portal

The portal which is the target of the teleportation

+ * @param player

The teleporting player

+ */ + public PlayerTeleporter(Portal portal, Player player) { + super(portal); + this.player = player; + } + + /** + * Teleports a player to this teleporter's portal + * + * @param origin

The portal the player teleports from

+ * @param event

The player move event triggering the event

+ */ + public void teleport(Portal origin, PlayerMoveEvent event) { + Location traveller = player.getLocation(); + Location exit = getExit(player, traveller); + + //Rotate the player to face out from the portal + adjustRotation(exit); + + //Call the StargatePlayerPortalEvent to allow plugins to change destination + if (!origin.equals(portal)) { + exit = triggerPlayerPortalEvent(origin, exit, event); + if (exit == null) { + return; + } + } + + //Load chunks to make sure not to teleport to the void + loadChunks(); + + //If no event is passed in, assume it's a teleport, and act as such + if (event == null) { + player.teleport(exit); + } else { + //The new method to teleport in a move event is set the "to" field. + event.setTo(exit); + } + } + + /** + * Triggers the player portal event to allow plugins to change the exit location + * + * @param origin

The origin portal teleported from

+ * @param exit

The exit location to teleport the player to

+ * @param event

The player move event which triggered the teleportation

+ * @return

The location the player should be teleported to, or null if the event was cancelled

+ */ + private Location triggerPlayerPortalEvent(Portal origin, Location exit, PlayerMoveEvent event) { + StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, portal, exit); + Stargate.server.getPluginManager().callEvent(stargatePlayerPortalEvent); + //Teleport is cancelled. Teleport the player back to where it came from + if (stargatePlayerPortalEvent.isCancelled()) { + new PlayerTeleporter(origin, player).teleport(origin, event); + return null; + } + return stargatePlayerPortalEvent.getExit(); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java deleted file mode 100644 index 7004608..0000000 --- a/src/main/java/net/knarcraft/stargate/portal/PortalTeleporter.java +++ /dev/null @@ -1,441 +0,0 @@ -package net.knarcraft.stargate.portal; - -import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.container.ChunkUnloadRequest; -import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.event.StargateEntityPortalEvent; -import net.knarcraft.stargate.event.StargatePlayerPortalEvent; -import net.knarcraft.stargate.utility.DirectionHelper; -import net.knarcraft.stargate.utility.EntityHelper; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.data.Bisected; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.type.Slab; -import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Vehicle; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; - -/** - * The portal teleporter takes care of the actual portal teleportation - */ -public class PortalTeleporter { - - private final Portal portal; - - /** - * Instantiates a new portal teleporter - * - * @param portal

The portal which is the target of the teleportation

- */ - public PortalTeleporter(Portal portal) { - this.portal = portal; - } - - /** - * Teleports a vehicle to this teleporter's portal - * - *

It is assumed that if a vehicle contains any players, their permissions have already been validated before - * calling this method.

- * - * @param vehicle

The vehicle to teleport

- * @param origin

The portal the vehicle teleports from

- */ - public void teleport(final Vehicle vehicle, Portal origin) { - Location traveller = vehicle.getLocation(); - Location exit = getExit(vehicle, traveller); - - double velocity = vehicle.getVelocity().length(); - - //Stop and teleport - vehicle.setVelocity(new Vector()); - - //Get new velocity - Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); - Vector newVelocity = newVelocityDirection.multiply(velocity); - - //Make sure the vehicle points out from the portal - adjustRotation(exit); - - //Call the StargateEntityPortalEvent to allow plugins to change destination - if (!origin.equals(portal)) { - exit = triggerEntityPortalEvent(origin, exit, vehicle); - if (exit == null) { - return; - } - } - - //Teleport the vehicle - teleportVehicle(vehicle, exit, newVelocity); - } - - /** - * Teleports a vehicle with any passengers to the given location - * - * @param vehicle

The vehicle to teleport

- * @param exit

The location the vehicle should be teleported to

- * @param newVelocity

The velocity to give the vehicle right after teleportation

- */ - private void teleportVehicle(Vehicle vehicle, Location exit, Vector newVelocity) { - //Load chunks to make sure not to teleport to the void - loadChunks(); - - List passengers = vehicle.getPassengers(); - if (!passengers.isEmpty()) { - if (!(vehicle instanceof LivingEntity)) { - //Teleport a normal vehicle with passengers (minecart or boat) - putPassengersInNewVehicle(vehicle, passengers, exit, newVelocity); - } else { - //Teleport a living vehicle with passengers (pig, horse, donkey, strider) - teleportLivingVehicle(vehicle, exit, passengers); - } - } else { - //Teleport an empty vehicle - vehicle.teleport(exit); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> vehicle.setVelocity(newVelocity), 1); - } - } - - /** - * Triggers the entity portal event to allow plugins to change the exit location - * - * @param origin

The origin portal teleported from

- * @param exit

The exit location to teleport the vehicle to

- * @param vehicle

The teleporting vehicle

- * @return

The location the vehicle should be teleported to, or null if the event was cancelled

- */ - private Location triggerEntityPortalEvent(Portal origin, Location exit, Vehicle vehicle) { - StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(vehicle, origin, - portal, exit); - Stargate.server.getPluginManager().callEvent(stargateEntityPortalEvent); - //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake - if (stargateEntityPortalEvent.isCancelled()) { - new PortalTeleporter(origin).teleport(vehicle, origin); - return null; - } - return stargateEntityPortalEvent.getExit(); - } - - private Location triggerPlayerPortalEvent(Portal origin, Location exit, Player player, PlayerMoveEvent event) { - StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, - portal, exit); - Stargate.server.getPluginManager().callEvent(stargatePlayerPortalEvent); - //Teleport is cancelled. Teleport the player back to where it came from - if (stargatePlayerPortalEvent.isCancelled()) { - new PortalTeleporter(origin).teleport(player, origin, event); - return null; - } - return stargatePlayerPortalEvent.getExit(); - } - - /** - * Teleports a player to this teleporter's 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(player, traveller); - - //Rotate the player to face out from the portal - adjustRotation(exit); - - //Call the StargatePlayerPortalEvent to allow plugins to change destination - if (!origin.equals(portal)) { - exit = triggerPlayerPortalEvent(origin, exit, player, event); - if (exit == null) { - return; - } - } - - //Load chunks to make sure not to teleport to the void - loadChunks(); - - //If no event is passed in, assume it's a teleport, and act as such - if (event == null) { - player.teleport(exit); - } else { - //The new method to teleport in a move event is set the "to" field. - event.setTo(exit); - } - } - - /** - * Adjusts the rotation of the player to face out from the portal - * - * @param exit

The location the player will exit from

- */ - private void adjustRotation(Location exit) { - int adjust = 0; - if (portal.getOptions().isBackwards()) { - adjust = 180; - } - float newYaw = (portal.getYaw() + adjust) % 360; - Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); - exit.setYaw(newYaw); - } - - /** - * Teleport a vehicle which is not a minecart or a boat - * - * @param vehicle

The vehicle to teleport

- * @param exit

The location the vehicle will exit

- * @param passengers

The passengers of the vehicle

- */ - private void teleportLivingVehicle(Vehicle vehicle, Location exit, List passengers) { - vehicle.eject(); - vehicle.teleport(exit); - handleVehiclePassengers(passengers, vehicle, 2); - } - - /** - * Creates a new vehicle equal to the player's previous vehicle and puts any passengers inside - * - *

While it is possible to teleport boats and minecarts using the same methods as "teleportLivingVehicle", this - * method works better with CraftBook with minecart options enabled. Using normal teleportation, CraftBook destroys - * the minecart once the player is ejected, causing the minecart to disappear and the player to teleport without it.

- * - * @param vehicle

The player's old vehicle

- * @param passengers

A list of all passengers in the vehicle

- * @param exit

The exit location to spawn the new vehicle on

- * @param newVelocity

The new velocity of the new vehicle

- */ - private void putPassengersInNewVehicle(Vehicle vehicle, List passengers, Location exit, - Vector newVelocity) { - World vehicleWorld = exit.getWorld(); - if (vehicleWorld == null) { - Stargate.logger.warning(Stargate.getString("prefix") + - "Unable to get the world to teleport the vehicle to"); - return; - } - //Spawn a new vehicle - Vehicle newVehicle = vehicleWorld.spawn(exit, vehicle.getClass()); - //Remove the old vehicle - vehicle.eject(); - vehicle.remove(); - //Set rotation, add passengers and restore velocity - newVehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle, 1); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> newVehicle.setVelocity(newVelocity), 1); - } - - /** - * Ejects, teleports and adds all passengers to the target vehicle - * - * @param passengers

The passengers to handle

- * @param targetVehicle

The vehicle the passengers should be put into

- * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

- */ - private void handleVehiclePassengers(List passengers, Vehicle targetVehicle, long delay) { - for (Entity passenger : passengers) { - passenger.eject(); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, - () -> teleportAndAddPassenger(targetVehicle, passenger), delay); - } - } - - /** - * Teleports and adds a passenger to a vehicle - * - *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, - * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

- * - * @param targetVehicle

The vehicle to add the passenger to

- * @param passenger

The passenger to teleport and add

- */ - private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { - if (!passenger.teleport(targetVehicle.getLocation())) { - Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); - } - if (!targetVehicle.addPassenger(passenger)) { - Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); - } - } - - /** - * 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 - RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); - if (relativeExit != null) { - BlockLocation exit = portal.getBlockAt(relativeExit); - float portalYaw = portal.getYaw(); - if (portal.getOptions().isBackwards()) { - portalYaw += 180; - } - exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); - - if (entity != null) { - double entitySize = EntityHelper.getEntityMaxSize(entity); - if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); - } - } - } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + - "Missing destination point in .gate file " + portal.getGate().getFilename()); - } - - return adjustExitLocation(traveller, exitLocation); - } - - /** - * Adjusts the positioning of the portal exit to prevent the given entity from suffocating - * - * @param relativeExit

The relative exit defined as the portal's exit

- * @param exitLocation

The currently calculated portal exit

- * @param entity

The travelling entity

- * @return

A location which won't suffocate the entity inside the portal

- */ - private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { - //Go left to find start of opening - RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); - - //Go right to find the end of the opening - RelativeBlockVector openingRight = getPortalExitEdge(relativeExit, 1); - - //Get the width to check if the entity fits - int openingWidth = openingRight.getRight() - openingLeft.getRight() + 1; - int existingOffset = relativeExit.getRight() - openingLeft.getRight(); - double newOffset = (openingWidth - existingOffset) / 2D; - - //Remove the half offset for better centering - if (openingWidth > 1) { - newOffset -= 0.5; - } - exitLocation = DirectionHelper.moveLocation(exitLocation, newOffset, 0, 0, portal.getYaw()); - - //Move large entities further from the portal, especially if this teleporter's portal will teleport them at once - double entitySize = EntityHelper.getEntityMaxSize(entity); - int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); - if (entitySize > 1) { - if (portal.getOptions().isAlwaysOn()) { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, (entityBoxSize / 2D), - portal.getYaw()); - } else { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, - (entitySize / 2D) - 1, portal.getYaw()); - } - } - - //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's - //moved one block out. - if (entity instanceof AbstractHorse) { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, 1, portal.getYaw()); - } - - return exitLocation; - } - - /** - * Gets one of the edges of a portal's opening/exit - * - * @param relativeExit

The known exit to start from

- * @param direction

The direction to move (+1 for right, -1 for left)

- * @return

The right or left edge of the opening

- */ - private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { - RelativeBlockVector openingEdge = relativeExit; - do { - RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, - openingEdge.getDepth(), openingEdge.getDistance()); - if (portal.getGate().getLayout().getExits().contains(possibleOpening)) { - openingEdge = possibleOpening; - } else { - break; - } - } while (true); - return openingEdge; - } - - /** - * Adjusts an exit location with rotation and slab height incrementation - * - * @param traveller

The location of the travelling entity

- * @param exitLocation

The exit location generated

- * @return

The location the travelling entity should be teleported to

- */ - private Location adjustExitLocation(Location traveller, Location exitLocation) { - if (exitLocation != null) { - BlockData blockData = portal.getWorld().getBlockAt(exitLocation).getBlockData(); - if ((blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) || - (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { - //Prevent traveller from spawning inside a slab - Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); - exitLocation.add(0, 1, 0); - } else if (blockData.getMaterial() == Material.WATER) { - //If there's water outside, go one up to allow for boat teleportation - Stargate.debug("adjustExitLocation", "Added a block to get above a block of water"); - exitLocation.add(0, 1, 0); - } - - exitLocation.setPitch(traveller.getPitch()); - return exitLocation; - } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + - "Unable to generate exit location"); - } - return traveller; - } - - /** - * Loads the chunks outside the portal's entrance - */ - private void loadChunks() { - for (Chunk chunk : getChunksToLoad()) { - chunk.addPluginChunkTicket(Stargate.stargate); - //Allow the chunk to unload after 3 seconds - Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); - } - } - - /** - * Gets all relevant chunks near this teleporter's portal's entrance which need to be loaded before teleportation - * - * @return

A list of chunks to load

- */ - private List getChunksToLoad() { - List chunksToLoad = new ArrayList<>(); - for (RelativeBlockVector vector : portal.getGate().getLayout().getEntrances()) { - BlockLocation entranceLocation = portal.getBlockAt(vector); - Chunk chunk = entranceLocation.getChunk(); - //Make sure not to load chunks twice - if (!chunksToLoad.contains(chunk)) { - chunksToLoad.add(chunk); - } - - //Get the chunk in front of the gate entrance - int blockOffset = portal.getOptions().isBackwards() ? -5 : 5; - Location fiveBlocksForward = DirectionHelper.moveLocation(entranceLocation, 0, 0, blockOffset, - portal.getYaw()); - //Load the chunk five blocks forward to make sure the teleported entity will never spawn in unloaded chunks - Chunk forwardChunk = fiveBlocksForward.getChunk(); - if (!chunksToLoad.contains(forwardChunk)) { - chunksToLoad.add(forwardChunk); - } - } - return chunksToLoad; - } - -} diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java new file mode 100644 index 0000000..fb1c79b --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -0,0 +1,228 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.ChunkUnloadRequest; +import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.utility.DirectionHelper; +import net.knarcraft.stargate.utility.EntityHelper; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Slab; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Entity; +import org.bukkit.scheduler.BukkitScheduler; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +/** + * The portal teleporter takes care of common teleportation logic + */ +public abstract class Teleporter { + + protected final Portal portal; + protected final BukkitScheduler scheduler; + + /** + * Instantiates a new portal teleporter + * + * @param portal

The portal which is the target of the teleportation

+ */ + public Teleporter(Portal portal) { + this.portal = portal; + this.scheduler = Stargate.server.getScheduler(); + } + + + /** + * Adjusts the rotation of the exit to make the teleporting entity face directly out from the portal + * + * @param exit

The location the entity will exit from

+ */ + protected void adjustRotation(Location exit) { + int adjust = 0; + if (portal.getOptions().isBackwards()) { + adjust = 180; + } + float newYaw = (portal.getYaw() + adjust) % 360; + Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); + exit.setYaw(newYaw); + } + + /** + * 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 + RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); + if (relativeExit != null) { + BlockLocation exit = portal.getBlockAt(relativeExit); + float portalYaw = portal.getYaw(); + if (portal.getOptions().isBackwards()) { + portalYaw += 180; + } + exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); + + if (entity != null) { + double entitySize = EntityHelper.getEntityMaxSize(entity); + if (entitySize > 1) { + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); + } + } + } else { + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + "Missing destination point in .gate file " + portal.getGate().getFilename()); + } + + return adjustExitLocation(traveller, exitLocation); + } + + /** + * Adjusts the positioning of the portal exit to prevent the given entity from suffocating + * + * @param relativeExit

The relative exit defined as the portal's exit

+ * @param exitLocation

The currently calculated portal exit

+ * @param entity

The travelling entity

+ * @return

A location which won't suffocate the entity inside the portal

+ */ + private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { + //Go left to find start of opening + RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); + + //Go right to find the end of the opening + RelativeBlockVector openingRight = getPortalExitEdge(relativeExit, 1); + + //Get the width to check if the entity fits + int openingWidth = openingRight.getRight() - openingLeft.getRight() + 1; + int existingOffset = relativeExit.getRight() - openingLeft.getRight(); + double newOffset = (openingWidth - existingOffset) / 2D; + + //Remove the half offset for better centering + if (openingWidth > 1) { + newOffset -= 0.5; + } + exitLocation = DirectionHelper.moveLocation(exitLocation, newOffset, 0, 0, portal.getYaw()); + + //Move large entities further from the portal, especially if this teleporter's portal will teleport them at once + double entitySize = EntityHelper.getEntityMaxSize(entity); + int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); + if (entitySize > 1) { + if (portal.getOptions().isAlwaysOn()) { + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, (entityBoxSize / 2D), + portal.getYaw()); + } else { + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, + (entitySize / 2D) - 1, portal.getYaw()); + } + } + + //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's + //moved one block out. + if (entity instanceof AbstractHorse) { + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, 1, portal.getYaw()); + } + + return exitLocation; + } + + /** + * Gets one of the edges of a portal's opening/exit + * + * @param relativeExit

The known exit to start from

+ * @param direction

The direction to move (+1 for right, -1 for left)

+ * @return

The right or left edge of the opening

+ */ + private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { + RelativeBlockVector openingEdge = relativeExit; + do { + RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, + openingEdge.getDepth(), openingEdge.getDistance()); + if (portal.getGate().getLayout().getExits().contains(possibleOpening)) { + openingEdge = possibleOpening; + } else { + break; + } + } while (true); + return openingEdge; + } + + /** + * Adjusts an exit location with rotation and slab height incrementation + * + * @param traveller

The location of the travelling entity

+ * @param exitLocation

The exit location generated

+ * @return

The location the travelling entity should be teleported to

+ */ + private Location adjustExitLocation(Location traveller, Location exitLocation) { + if (exitLocation != null) { + BlockData blockData = portal.getWorld().getBlockAt(exitLocation).getBlockData(); + if ((blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) || + (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { + //Prevent traveller from spawning inside a slab + Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); + exitLocation.add(0, 1, 0); + } else if (blockData.getMaterial() == Material.WATER) { + //If there's water outside, go one up to allow for boat teleportation + Stargate.debug("adjustExitLocation", "Added a block to get above a block of water"); + exitLocation.add(0, 1, 0); + } + + exitLocation.setPitch(traveller.getPitch()); + return exitLocation; + } else { + Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + "Unable to generate exit location"); + } + return traveller; + } + + /** + * Loads the chunks outside the portal's entrance + */ + protected void loadChunks() { + for (Chunk chunk : getChunksToLoad()) { + chunk.addPluginChunkTicket(Stargate.stargate); + //Allow the chunk to unload after 3 seconds + Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); + } + } + + /** + * Gets all relevant chunks near this teleporter's portal's entrance which need to be loaded before teleportation + * + * @return

A list of chunks to load

+ */ + private List getChunksToLoad() { + List chunksToLoad = new ArrayList<>(); + for (RelativeBlockVector vector : portal.getGate().getLayout().getEntrances()) { + BlockLocation entranceLocation = portal.getBlockAt(vector); + Chunk chunk = entranceLocation.getChunk(); + //Make sure not to load chunks twice + if (!chunksToLoad.contains(chunk)) { + chunksToLoad.add(chunk); + } + + //Get the chunk in front of the gate entrance + int blockOffset = portal.getOptions().isBackwards() ? -5 : 5; + Location fiveBlocksForward = DirectionHelper.moveLocation(entranceLocation, 0, 0, blockOffset, + portal.getYaw()); + //Load the chunk five blocks forward to make sure the teleported entity will never spawn in unloaded chunks + Chunk forwardChunk = fiveBlocksForward.getChunk(); + if (!chunksToLoad.contains(forwardChunk)) { + chunksToLoad.add(forwardChunk); + } + } + return chunksToLoad; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java new file mode 100644 index 0000000..72462b3 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -0,0 +1,188 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.event.StargateEntityPortalEvent; +import net.knarcraft.stargate.utility.DirectionHelper; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Vehicle; +import org.bukkit.util.Vector; + +import java.util.List; + +/** + * The portal teleporter takes care of the actual portal teleportation for any vehicles + */ +public class VehicleTeleporter extends Teleporter { + + private final Vehicle teleportingVehicle; + + /** + * Instantiates a new vehicle teleporter + * + * @param portal

The portal which is the target of the teleportation

+ * @param teleportingVehicle

The teleporting vehicle

+ */ + public VehicleTeleporter(Portal portal, Vehicle teleportingVehicle) { + super(portal); + this.teleportingVehicle = teleportingVehicle; + } + + /** + * Teleports a vehicle to this teleporter's portal + * + *

It is assumed that if a vehicle contains any players, their permissions have already been validated before + * calling this method.

+ * + * @param origin

The portal the vehicle teleports from

+ */ + public void teleport(Portal origin) { + Location traveller = teleportingVehicle.getLocation(); + Location exit = getExit(teleportingVehicle, traveller); + + double velocity = teleportingVehicle.getVelocity().length(); + + //Stop and teleport + teleportingVehicle.setVelocity(new Vector()); + + //Get new velocity + Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); + Vector newVelocity = newVelocityDirection.multiply(velocity); + + //Make sure the vehicle points out from the portal + adjustRotation(exit); + + //Call the StargateEntityPortalEvent to allow plugins to change destination + if (!origin.equals(portal)) { + exit = triggerEntityPortalEvent(origin, exit); + if (exit == null) { + return; + } + } + + //Teleport the vehicle + teleportVehicle(exit, newVelocity); + } + + /** + * Teleports a vehicle with any passengers to the given location + * + * @param exit

The location the vehicle should be teleported to

+ * @param newVelocity

The velocity to give the vehicle right after teleportation

+ */ + private void teleportVehicle(Location exit, Vector newVelocity) { + //Load chunks to make sure not to teleport to the void + loadChunks(); + + List passengers = teleportingVehicle.getPassengers(); + if (!passengers.isEmpty()) { + if (!(teleportingVehicle instanceof LivingEntity)) { + //Teleport a normal vehicle with passengers (minecart or boat) + putPassengersInNewVehicle(passengers, exit, newVelocity); + } else { + //Teleport a living vehicle with passengers (pig, horse, donkey, strider) + teleportLivingVehicle(exit, passengers); + } + } else { + //Teleport an empty vehicle + teleportingVehicle.teleport(exit); + scheduler.scheduleSyncDelayedTask(Stargate.stargate, () -> teleportingVehicle.setVelocity(newVelocity), 1); + } + } + + /** + * Triggers the entity portal event to allow plugins to change the exit location + * + * @param origin

The origin portal teleported from

+ * @param exit

The exit location to teleport the vehicle to

+ * @return

The location the vehicle should be teleported to, or null if the event was cancelled

+ */ + private Location triggerEntityPortalEvent(Portal origin, Location exit) { + StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingVehicle, origin, + portal, exit); + Stargate.server.getPluginManager().callEvent(stargateEntityPortalEvent); + //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake + if (stargateEntityPortalEvent.isCancelled()) { + new VehicleTeleporter(origin, teleportingVehicle).teleport(origin); + return null; + } + return stargateEntityPortalEvent.getExit(); + } + + /** + * Teleport a vehicle which is not a minecart or a boat + * + * @param exit

The location the vehicle will exit

+ * @param passengers

The passengers of the vehicle

+ */ + private void teleportLivingVehicle(Location exit, List passengers) { + teleportingVehicle.eject(); + teleportingVehicle.teleport(exit); + handleVehiclePassengers(passengers, teleportingVehicle, 2); + } + + /** + * Creates a new vehicle equal to the player's previous vehicle and puts any passengers inside + * + *

While it is possible to teleport boats and minecarts using the same methods as "teleportLivingVehicle", this + * method works better with CraftBook with minecart options enabled. Using normal teleportation, CraftBook destroys + * the minecart once the player is ejected, causing the minecart to disappear and the player to teleport without it.

+ * + * @param passengers

A list of all passengers in the vehicle

+ * @param exit

The exit location to spawn the new vehicle on

+ * @param newVelocity

The new velocity of the new vehicle

+ */ + private void putPassengersInNewVehicle(List passengers, Location exit, + Vector newVelocity) { + World vehicleWorld = exit.getWorld(); + if (vehicleWorld == null) { + Stargate.logger.warning(Stargate.getString("prefix") + + "Unable to get the world to teleport the vehicle to"); + return; + } + //Spawn a new vehicle + Vehicle newVehicle = vehicleWorld.spawn(exit, teleportingVehicle.getClass()); + //Remove the old vehicle + teleportingVehicle.eject(); + teleportingVehicle.remove(); + //Set rotation, add passengers and restore velocity + newVehicle.setRotation(exit.getYaw(), exit.getPitch()); + handleVehiclePassengers(passengers, newVehicle, 1); + scheduler.scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); + } + + /** + * Ejects, teleports and adds all passengers to the target vehicle + * + * @param passengers

The passengers to handle

+ * @param vehicle

The vehicle the passengers should be put into

+ * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

+ */ + private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay) { + for (Entity passenger : passengers) { + passenger.eject(); + scheduler.scheduleSyncDelayedTask(Stargate.stargate, () -> teleportAndAddPassenger(vehicle, passenger), delay); + } + } + + /** + * Teleports and adds a passenger to a vehicle + * + *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, + * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

+ * + * @param targetVehicle

The vehicle to add the passenger to

+ * @param passenger

The passenger to teleport and add

+ */ + private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { + if (!passenger.teleport(targetVehicle.getLocation())) { + Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); + } + if (!targetVehicle.addPassenger(passenger)) { + Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 8380c8b..266fde6 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -1,9 +1,9 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalTeleporter; import org.bukkit.entity.Player; import java.io.ByteArrayInputStream; @@ -131,7 +131,7 @@ public final class BungeeHelper { Stargate.logger.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); return; } - new PortalTeleporter(destinationPortal).teleport(player, destinationPortal, null); + new PlayerTeleporter(destinationPortal, player).teleport(destinationPortal, null); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java index ff6be4b..73f2bdc 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java @@ -107,7 +107,7 @@ public final class EconomyHandler { * Checks whether the given player can afford the given fee * * @param player

The player to check

- * @param cost

The fee to pay

+ * @param cost

The fee to pay

* @return

True if the player can afford to pay the fee

*/ public static boolean canAffordFee(Player player, int cost) { diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 308dfcf..b0b5c38 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -2,9 +2,9 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateAccessEvent; +import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalOption; -import net.knarcraft.stargate.portal.PortalTeleporter; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; @@ -390,7 +390,7 @@ public final class PermissionHelper { // Not open for this player if (!entrancePortal.isOpenFor(player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - new PortalTeleporter(entrancePortal).teleport(player, entrancePortal, event); + new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); return true; } @@ -402,7 +402,7 @@ public final class PermissionHelper { //Player cannot access portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - new PortalTeleporter(entrancePortal).teleport(player, entrancePortal, event); + new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); entrancePortal.close(false); return true; } From 82ed28bba0c23b995c48c175cca6f4854814d12e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 18:52:24 +0200 Subject: [PATCH 167/378] Removes the DirectionHelper's getBlockAt method as it only increased complexity --- .../java/net/knarcraft/stargate/portal/Gate.java | 6 +++--- .../java/net/knarcraft/stargate/portal/Portal.java | 3 +-- .../stargate/utility/DirectionHelper.java | 14 -------------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 9fdc3d8..7168d0d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -3,7 +3,6 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Material; @@ -195,7 +194,8 @@ public class Gate { Character key = layout.getLayout()[lineIndex][rowIndex]; Material materialInLayout = characterMaterialMap.get(key); - Material materialAtLocation = DirectionHelper.getBlockAt(topLeft, borderVector, yaw).getType(); + Material materialAtLocation = topLeft.getRelativeLocation(borderVector, yaw).getType(); + if (materialInLayout == null) { /* This generally should not happen with proper checking, but just in case a material character is not * recognized, but still allowed in previous checks, verify the gate as long as all such instances of @@ -225,7 +225,7 @@ public class Gate { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(topLeft)); for (RelativeBlockVector entranceVector : layout.getEntrances()) { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(entranceVector)); - Material type = DirectionHelper.getBlockAt(topLeft, entranceVector, yaw).getType(); + Material type = topLeft.getRelativeLocation(entranceVector, yaw).getType(); //Ignore entrance if it's air or water, and we're creating a new gate if (onCreate && (type == Material.AIR || type == Material.WATER)) { diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index b8d7e28..110a393 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -8,7 +8,6 @@ import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateOpenEvent; -import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Axis; import org.bukkit.Material; @@ -670,7 +669,7 @@ public class Portal { * @return

The block at the given relative position

*/ public BlockLocation getBlockAt(RelativeBlockVector vector) { - return DirectionHelper.getBlockAt(getTopLeft(), vector, getYaw()); + return getTopLeft().getRelativeLocation(vector, getYaw()); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index c0f3132..5564633 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -1,7 +1,5 @@ package net.knarcraft.stargate.utility; -import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.container.RelativeBlockVector; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; @@ -85,18 +83,6 @@ public final class DirectionHelper { } } - /** - * Gets a block location relative to another - * - * @param topLeft

The block location to start at (Usually the top-left block of a portal)

- * @param vector

The relative vector describing the relative location

- * @param yaw

The yaw pointing outwards from the portal

- * @return

A block location relative to the given location

- */ - public static BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, double yaw) { - return topLeft.getRelativeLocation(vector, yaw); - } - /** * Moves a location relatively * From 1d4b988ca4fe8f75d0993c9c09024bffd21405b9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 19:12:30 +0200 Subject: [PATCH 168/378] Moves the rest of the sign drawing code from Portal to SignHelper --- .../stargate/listener/BlockEventListener.java | 3 +- .../net/knarcraft/stargate/portal/Portal.java | 34 +++++-------------- .../stargate/portal/PortalHandler.java | 11 +++--- .../stargate/utility/SignHelper.java | 18 ++++++++++ 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 26da8b1..d004382 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -8,6 +8,7 @@ import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -81,7 +82,7 @@ public class BlockEventListener implements Listener { Stargate.sendSuccessMessage(player, Stargate.getString("createMsg")); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> SignHelper.drawSign(portal), 1); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 110a393..e481377 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -8,12 +8,9 @@ import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateOpenEvent; -import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Axis; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import org.bukkit.block.data.Orientable; import org.bukkit.entity.Player; @@ -24,6 +21,8 @@ import java.util.Map; import java.util.Random; import java.util.UUID; +import static net.knarcraft.stargate.utility.SignHelper.drawSign; + /** * This class represents a portal in space which points to one or several portals */ @@ -154,7 +153,7 @@ public class Portal { @SuppressWarnings("unused") public void setName(String name) { this.name = filterName(name); - drawSign(); + drawSign(this); } /** @@ -374,13 +373,13 @@ public class Portal { player = openFor; Portal destination = getDestination(); - // Only open destination if it's not-fixed or points at this portal + //Only open destination if it's not-fixed or points at this portal if (!options.isRandom() && destination != null && (!destination.options.isFixed() || destination.getDestinationName().equalsIgnoreCase(getName())) && !destination.isOpen()) { destination.open(openFor, false); destination.setDestination(this); if (destination.isVerified()) { - destination.drawSign(); + drawSign(destination); } } } @@ -551,7 +550,7 @@ public class Portal { } destination = event.getDestination(); destinations = event.getDestinations(); - drawSign(); + drawSign(this); return true; } @@ -572,7 +571,7 @@ public class Portal { destinations.clear(); destination = ""; activePlayer = null; - drawSign(); + drawSign(this); } /** @@ -624,7 +623,7 @@ public class Portal { cycleDestination(direction); } openTime = System.currentTimeMillis() / 1000; - drawSign(); + drawSign(this); } /** @@ -636,7 +635,7 @@ public class Portal { int index = destinations.indexOf(destination); index += direction; - //Wrap around + //Wrap around if the last destination has been reached if (index >= destinations.size()) { index = 0; } else if (index < 0) { @@ -647,21 +646,6 @@ public class Portal { lastDestination = destination; } - /** - * Draws this portal's sign - */ - public final void drawSign() { - BlockState state = getSignLocation().getBlock().getState(); - if (!(state instanceof Sign sign)) { - Stargate.logger.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); - Stargate.debug("Portal::drawSign", "Block: " + getSignLocation().getBlock().getType() + " @ " - + getSignLocation().getBlock().getLocation()); - return; - } - - SignHelper.drawSign(sign, this); - } - /** * Gets the block at the given location relative to this portal's location * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 1ff3bb6..ddb6a70 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -9,6 +9,7 @@ import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; @@ -163,7 +164,7 @@ public class PortalHandler { } //Update the portal's sign if (origin.getOptions().isFixed()) { - origin.drawSign(); + SignHelper.drawSign(origin); } //Close portal without destination if (origin.getOptions().isAlwaysOn()) { @@ -584,7 +585,7 @@ public class PortalHandler { * @param destinationName

The name of the destination portal

*/ private static void updateNewPortal(Portal portal, String destinationName) { - portal.drawSign(); + SignHelper.drawSign(portal); //Open an always on portal if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { portal.open(true); @@ -592,7 +593,7 @@ public class PortalHandler { Portal destinationPortal = getByName(destinationName, portal.getNetwork()); if (destinationPortal != null) { portal.open(true); - destinationPortal.drawSign(); + SignHelper.drawSign(destinationPortal); } } else { //Update the block type for the portal's opening to the closed block @@ -617,7 +618,7 @@ public class PortalHandler { } //Update sign of fixed gates pointing at this gate if (origin.getOptions().isFixed()) { - origin.drawSign(); + SignHelper.drawSign(origin); } //Open any always on portal pointing at this portal if (origin.getOptions().isAlwaysOn()) { @@ -940,7 +941,7 @@ public class PortalHandler { //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since for (Portal portal : allPortals) { - portal.drawSign(); + SignHelper.drawSign(portal); } return true; } catch (Exception e) { diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index d725eb9..c8abba9 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -4,6 +4,8 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import org.bukkit.ChatColor; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; import org.bukkit.block.Sign; /** @@ -11,6 +13,22 @@ import org.bukkit.block.Sign; */ public final class SignHelper { + /** + * Draws this portal's sign + */ + public static void drawSign(Portal portal) { + Block signBlock = portal.getSignLocation().getBlock(); + BlockState state = signBlock.getState(); + if (!(state instanceof Sign sign)) { + Stargate.logger.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); + Stargate.debug("Portal::drawSign", "Block: " + signBlock.getType() + " @ " + + signBlock.getLocation()); + return; + } + + SignHelper.drawSign(sign, portal); + } + /** * Draws the sign on this portal */ From 635d08b1b3fdd76599a4651262d867c9387c4ed2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 20 Oct 2021 01:33:36 +0200 Subject: [PATCH 169/378] Makes the SignHelper helper class into the proper PortalSignDrawer which each Portal now has one instance of --- .../stargate/listener/BlockEventListener.java | 3 +- .../net/knarcraft/stargate/portal/Portal.java | 21 +++-- .../stargate/portal/PortalHandler.java | 11 ++- .../PortalSignDrawer.java} | 78 +++++++++++-------- 4 files changed, 65 insertions(+), 48 deletions(-) rename src/main/java/net/knarcraft/stargate/{utility/SignHelper.java => portal/PortalSignDrawer.java} (74%) diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index d004382..26da8b1 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -8,7 +8,6 @@ import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; -import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -82,7 +81,7 @@ public class BlockEventListener implements Listener { Stargate.sendSuccessMessage(player, Stargate.getString("createMsg")); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> SignHelper.drawSign(portal), 1); + Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index e481377..cce7cb3 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -21,8 +21,6 @@ import java.util.Map; import java.util.Random; import java.util.UUID; -import static net.knarcraft.stargate.utility.SignHelper.drawSign; - /** * This class represents a portal in space which points to one or several portals */ @@ -30,6 +28,7 @@ public class Portal { // Gate location block info private final PortalLocation location; + private final PortalSignDrawer signDrawer; // Block references private final Gate gate; @@ -79,6 +78,14 @@ public class Portal { this.ownerUUID = ownerUUID; this.ownerName = ownerName; this.options = new PortalOptions(options, destination.length() > 0); + this.signDrawer = new PortalSignDrawer(this); + } + + /** + * Re-draws the sign on this portal + */ + public void drawSign() { + this.signDrawer.drawSign(); } /** @@ -153,7 +160,7 @@ public class Portal { @SuppressWarnings("unused") public void setName(String name) { this.name = filterName(name); - drawSign(this); + this.drawSign(); } /** @@ -379,7 +386,7 @@ public class Portal { destination.open(openFor, false); destination.setDestination(this); if (destination.isVerified()) { - drawSign(destination); + destination.drawSign(); } } } @@ -550,7 +557,7 @@ public class Portal { } destination = event.getDestination(); destinations = event.getDestinations(); - drawSign(this); + this.drawSign(); return true; } @@ -571,7 +578,7 @@ public class Portal { destinations.clear(); destination = ""; activePlayer = null; - drawSign(this); + this.drawSign(); } /** @@ -623,7 +630,7 @@ public class Portal { cycleDestination(direction); } openTime = System.currentTimeMillis() / 1000; - drawSign(this); + this.drawSign(); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index ddb6a70..1ff3bb6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -9,7 +9,6 @@ import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; -import net.knarcraft.stargate.utility.SignHelper; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; @@ -164,7 +163,7 @@ public class PortalHandler { } //Update the portal's sign if (origin.getOptions().isFixed()) { - SignHelper.drawSign(origin); + origin.drawSign(); } //Close portal without destination if (origin.getOptions().isAlwaysOn()) { @@ -585,7 +584,7 @@ public class PortalHandler { * @param destinationName

The name of the destination portal

*/ private static void updateNewPortal(Portal portal, String destinationName) { - SignHelper.drawSign(portal); + portal.drawSign(); //Open an always on portal if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { portal.open(true); @@ -593,7 +592,7 @@ public class PortalHandler { Portal destinationPortal = getByName(destinationName, portal.getNetwork()); if (destinationPortal != null) { portal.open(true); - SignHelper.drawSign(destinationPortal); + destinationPortal.drawSign(); } } else { //Update the block type for the portal's opening to the closed block @@ -618,7 +617,7 @@ public class PortalHandler { } //Update sign of fixed gates pointing at this gate if (origin.getOptions().isFixed()) { - SignHelper.drawSign(origin); + origin.drawSign(); } //Open any always on portal pointing at this portal if (origin.getOptions().isAlwaysOn()) { @@ -941,7 +940,7 @@ public class PortalHandler { //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since for (Portal portal : allPortals) { - SignHelper.drawSign(portal); + portal.drawSign(); } return true; } catch (Exception e) { diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java similarity index 74% rename from src/main/java/net/knarcraft/stargate/utility/SignHelper.java rename to src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index c8abba9..9b85e0b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -1,22 +1,33 @@ -package net.knarcraft.stargate.utility; +package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.portal.Portal; -import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.utility.EconomyHandler; +import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.ChatColor; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; /** - * This class helps to draw the sign on a portal as it's a bit too complicated to be contained within the portal class + * The portal sign drawer draws the sing of a given portal */ -public final class SignHelper { +public class PortalSignDrawer { + + private final Portal portal; /** - * Draws this portal's sign + * Instantiates a new portal sign drawer + * + * @param portal

The portal whose sign this portal sign drawer is responsible for drawing

*/ - public static void drawSign(Portal portal) { + public PortalSignDrawer(Portal portal) { + this.portal = portal; + } + + /** + * Draws the sign of the portal this sign drawer is responsible for + */ + public void drawSign() { Block signBlock = portal.getSignLocation().getBlock(); BlockState state = signBlock.getState(); if (!(state instanceof Sign sign)) { @@ -26,33 +37,35 @@ public final class SignHelper { return; } - SignHelper.drawSign(sign, portal); + drawSign(sign); } /** - * Draws the sign on this portal + * Draws the sign of the portal this sign drawer is responsible for + * + * @param sign

The sign re-draw

*/ - public static void drawSign(Sign sign, Portal portal) { + public void drawSign(Sign sign) { //Clear sign for (int index = 0; index <= 3; index++) { sign.setLine(index, ""); } - Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + ChatColor.BLACK + portal.getName() + + Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.signColor + portal.getName() + ChatColor.WHITE + "-"); if (!portal.isActive()) { //Default sign text - drawInactiveSign(sign, portal); + drawInactiveSign(sign); } else { if (portal.getOptions().isBungee()) { //Bungee sign - drawBungeeSign(sign, portal); + drawBungeeSign(sign); } else if (portal.getOptions().isFixed()) { //Sign pointing at one other portal - drawFixedSign(sign, portal); + drawFixedSign(sign); } else { //Networking stuff - drawNetworkSign(sign, portal); + drawNetworkSign(sign); } } @@ -62,9 +75,9 @@ public final class SignHelper { /** * Draws a sign with choose-able network locations * - * @param sign

The sign to draw on

+ * @param sign

The sign to re-draw

*/ - private static void drawNetworkSign(Sign sign, Portal portal) { + private void drawNetworkSign(Sign sign) { int maxIndex = portal.getDestinations().size() - 1; int signLineIndex = 0; int destinationIndex = portal.getDestinations().indexOf(portal.getDestinationName()); @@ -72,21 +85,21 @@ public final class SignHelper { //Last, and not only entry. Draw the entry two back if ((destinationIndex == maxIndex) && (maxIndex > 1)) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2, portal); + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2); } //Not first entry. Draw the previous entry if (destinationIndex > 0) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 1, portal); + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 1); } //Draw the chosen entry (line 2 or 3) - drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex, portal); + drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex); //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 1)) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex + 1, portal); + drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex + 1); } //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { - drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 2, portal); + drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 2); } } @@ -97,15 +110,15 @@ public final class SignHelper { * @param sign

The sign to draw on

* @param signLineIndex

The line to draw on

*/ - private static void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex, Portal portal) { + private void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex) { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + portal.getDestinationName() + (green ? ChatColor.DARK_GREEN : "") + "<"); } else { - Stargate.setLine(sign, signLineIndex, ChatColor.BLACK + " >" + portal.getDestinationName() + - ChatColor.BLACK + "< "); + Stargate.setLine(sign, signLineIndex, Stargate.signColor + " >" + portal.getDestinationName() + + Stargate.signColor + "< "); } } @@ -117,8 +130,7 @@ public final class SignHelper { * @param signLineIndex

The line to draw on

* @param destinationIndex

The index of the destination to draw

*/ - private static void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex, - Portal portal) { + private void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex) { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinations().get(destinationIndex), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); @@ -131,9 +143,9 @@ public final class SignHelper { /** * Draws a bungee sign * - * @param sign

The sign to draw on

+ * @param sign

The sign to re-draw

*/ - private static void drawBungeeSign(Sign sign, Portal portal) { + private void drawBungeeSign(Sign sign) { Stargate.setLine(sign, 1, Stargate.getString("bungeeSign")); Stargate.setLine(sign, 2, ">" + portal.getDestinationName() + "<"); Stargate.setLine(sign, 3, "[" + portal.getNetwork() + "]"); @@ -142,9 +154,9 @@ public final class SignHelper { /** * Draws an inactive sign * - * @param sign

The sign to draw on

+ * @param sign

The sign to re-draw

*/ - private static void drawInactiveSign(Sign sign, Portal portal) { + private void drawInactiveSign(Sign sign) { Stargate.setLine(sign, 1, Stargate.getString("signRightClick")); Stargate.setLine(sign, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { @@ -157,9 +169,9 @@ public final class SignHelper { /** * Draws a sign pointing to a fixed location * - * @param sign

The sign to draw on

+ * @param sign

The sign to re-draw

*/ - private static void drawFixedSign(Sign sign, Portal portal) { + private void drawFixedSign(Sign sign) { if (portal.getOptions().isRandom()) { Stargate.setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); } else { From d2e8c81a5acbf0f2dfba0c536a86ac3ac9723c0e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 20 Oct 2021 16:09:35 +0200 Subject: [PATCH 170/378] Splits the portal class into Portal, PortalActivator, PortalOpener and PortalStructure PortalStructure now contains information about the gate's physical structure, such as the location of border blocks, the location of entrances, the gate type and the button location. PortalActivator is responsible for activating/de-activating portals, destination toggling and getting information about available destinations. PortalOpener is responsible for opening/closing a portal. It's also the place to go for checking if the portal is open for a given player. Comments of the Portal class have been improved, but the comments of the three new classes need fixing. --- .../java/net/knarcraft/stargate/Stargate.java | 4 +- .../listener/PlayerEventListener.java | 18 +- .../listener/PortalEventListener.java | 6 +- .../listener/VehicleEventListener.java | 10 +- .../net/knarcraft/stargate/portal/Portal.java | 601 +++--------------- .../stargate/portal/PortalActivator.java | 241 +++++++ .../stargate/portal/PortalHandler.java | 56 +- .../stargate/portal/PortalOpener.java | 203 ++++++ .../stargate/portal/PortalSignDrawer.java | 16 +- .../stargate/portal/PortalStructure.java | 147 +++++ .../stargate/thread/StarGateThread.java | 6 +- .../stargate/utility/EconomyHelper.java | 2 +- .../stargate/utility/PermissionHelper.java | 13 +- 13 files changed, 749 insertions(+), 574 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalActivator.java create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalOpener.java create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalStructure.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2eecae4..547cdd3 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -513,7 +513,7 @@ public class Stargate extends JavaPlugin { public void closeAllPortals() { // Close all gates prior to reloading for (Portal openPortal : openPortalsQueue) { - openPortal.close(true); + openPortal.getPortalOpener().closePortal(true); } } @@ -563,7 +563,7 @@ public class Stargate extends JavaPlugin { public void reload(CommandSender sender) { // Deactivate portals for (Portal activePortal : activePortalsQueue) { - activePortal.deactivate(); + activePortal.getPortalActivator().deactivate(); } // Close portals closeAllPortals(); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 8ed2e48..fef005d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalActivator; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; @@ -81,7 +82,7 @@ public class PlayerEventListener implements Listener { return; } Portal entrancePortal = PortalHandler.getByEntrance(toLocation); - Portal destination = entrancePortal.getDestination(player); + Portal destination = entrancePortal.getPortalActivator().getDestination(player); //Teleport the vehicle to the player Entity playerVehicle = player.getVehicle(); @@ -99,7 +100,7 @@ public class PlayerEventListener implements Listener { new PlayerTeleporter(destination, player).teleport(entrancePortal, event); } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); } /** @@ -124,7 +125,7 @@ public class PlayerEventListener implements Listener { return false; } - Portal destination = entrancePortal.getDestination(player); + Portal destination = entrancePortal.getPortalActivator().getDestination(player); //Catch always open portals without a valid destination to prevent the user for being teleported and denied if (destination == null) { @@ -200,10 +201,11 @@ public class PlayerEventListener implements Listener { //Cycle portal destination if ((!portal.isOpen()) && (!portal.getOptions().isFixed())) { + PortalActivator destinations = portal.getPortalActivator(); if (leftClick) { - portal.cycleDestination(player, -1); + destinations.cycleDestination(player, -1); } else { - portal.cycleDestination(player); + destinations.cycleDestination(player); } } } @@ -260,7 +262,7 @@ public class PlayerEventListener implements Listener { } PermissionHelper.openPortal(player, portal); - if (portal.isOpenFor(player)) { + if (portal.getPortalOpener().isOpenFor(player)) { event.setUseInteractedBlock(Event.Result.ALLOW); } } @@ -302,7 +304,7 @@ public class PlayerEventListener implements Listener { //Check if bungee is actually enabled if (!Stargate.enableBungee) { Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); return false; } @@ -323,7 +325,7 @@ public class PlayerEventListener implements Listener { // Close portal if required (Should never be) Stargate.debug("bungeeTeleport", "Teleported player to another server"); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); return true; } diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index e484895..fd26668 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -64,11 +64,11 @@ public class PortalEventListener implements Listener { //Remove any old player teleportations in case weird things happen playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player)); //Decide if the anything stops the player from teleporting - if (PermissionHelper.playerCannotTeleport(portal, portal.getDestination(), player, null)) { + if (PermissionHelper.playerCannotTeleport(portal, portal.getPortalActivator().getDestination(), player, null)) { //Teleport the player back to the portal they came in, just in case playersFromTheEnd.add(new FromTheEndTeleportation(player, portal)); } - playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getDestination())); + playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getPortalActivator().getDestination())); } } @@ -92,7 +92,7 @@ public class PortalEventListener implements Listener { event.setRespawnLocation(new PlayerTeleporter(exitPortal, respawningPlayer).getExit(respawningPlayer, respawningPlayer.getLocation())); //Properly close the portal to prevent it from staying in a locked state until it times out - exitPortal.close(false); + exitPortal.getPortalOpener().closePortal(false); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 5a131f7..6d10ec4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -68,7 +68,7 @@ public class VehicleEventListener implements Listener { teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { Stargate.debug(route, prefix + "Found empty vehicle"); - Portal destinationPortal = entrancePortal.getDestination(); + Portal destinationPortal = entrancePortal.getPortalActivator().getDestination(); if (destinationPortal == null) { Stargate.debug(route, prefix + "Unable to find portal destination"); return; @@ -90,13 +90,13 @@ public class VehicleEventListener implements Listener { Player player = (Player) passengers.get(0); //On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open // to one player at a time, we only need to check if the portal is open to the driver. - if (!entrancePortal.isOpenFor(player)) { + if (!entrancePortal.getPortalOpener().isOpenFor(player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } //If no destination exists, the teleportation cannot happen - Portal destinationPortal = entrancePortal.getDestination(player); + Portal destinationPortal = entrancePortal.getPortalActivator().getDestination(player); if (destinationPortal == null) { return; } @@ -119,7 +119,7 @@ public class VehicleEventListener implements Listener { Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); } /** @@ -152,7 +152,7 @@ public class VehicleEventListener implements Listener { //Make sure the user can access the portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); return false; } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index cce7cb3..2ea0332 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -1,24 +1,11 @@ package net.knarcraft.stargate.portal; -import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.event.StargateActivateEvent; -import net.knarcraft.stargate.event.StargateCloseEvent; -import net.knarcraft.stargate.event.StargateDeactivateEvent; -import net.knarcraft.stargate.event.StargateOpenEvent; -import org.bukkit.Axis; -import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.data.Orientable; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.Map; -import java.util.Random; import java.util.UUID; /** @@ -26,59 +13,77 @@ import java.util.UUID; */ public class Portal { - // Gate location block info + // Gate information + private final String name; + private final String network; + private final String ownerName; + private final UUID ownerUUID; + + private final PortalOptions options; + private final PortalOpener portalOpener; private final PortalLocation location; private final PortalSignDrawer signDrawer; - - // Block references - private final Gate gate; - private BlockLocation button; - private BlockLocation[] frame; - private BlockLocation[] entrances; - - // Gate information - private String name; - private String destination; - private String lastDestination = ""; - private String network; - private final String ownerName; - private UUID ownerUUID; - private boolean verified; - private final PortalOptions options; - - // In-use information - private Player player; - private Player activePlayer; - private List destinations = new ArrayList<>(); - private boolean isOpen = false; - private long openTime; + private final PortalStructure structure; + private final PortalActivator portalActivator; /** * Instantiates a new portal * * @param portalLocation

Object containing locations of all relevant blocks

* @param button

The location of the portal's open button

- * @param destination

The destination defined on the sign's destination line

+ * @param destination

The destination defined on the sign's destination line. "" for non-fixed gates

* @param name

The name of the portal defined on the sign's first line

- * @param network

The network the portal belongs to, defined on the sign's network line

- * @param gate

The gate template this portal uses

+ * @param network

The network the portal belongs to, defined on the sign's third

+ * @param gate

The gate type to use for this portal

* @param ownerUUID

The UUID of the gate's owner

* @param ownerName

The name of the gate's owner

- * @param options

A map containing all possible portal options

+ * @param options

A map containing all possible portal options, with true for the ones enabled

*/ - Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, String network, - Gate gate, UUID ownerUUID, String ownerName, Map options) { + public Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, String network, + Gate gate, UUID ownerUUID, String ownerName, Map options) { this.location = portalLocation; - this.destination = destination; - this.button = button; - this.verified = false; this.network = network; this.name = name; - this.gate = gate; this.ownerUUID = ownerUUID; this.ownerName = ownerName; this.options = new PortalOptions(options, destination.length() > 0); this.signDrawer = new PortalSignDrawer(this); + this.portalOpener = new PortalOpener(this, destination); + this.structure = new PortalStructure(this, gate, button); + this.portalActivator = portalOpener.getPortalOpener(); + } + + /** + * Gets the location data for this portal + * + * @return

This portal's location data

+ */ + public PortalLocation getLocation() { + return this.location; + } + + /** + * Gets the structure of this portal + * + *

The structure contains information about the portal's gate, button and real locations of frames and + * entrances. The structure is also responsible for verifying built StarGates to make sure they match the gate.

+ * + * @return

This portal's structure

+ */ + public PortalStructure getStructure() { + return this.structure; + } + + /** + * Gets this portal's activator + * + *

The activator is responsible for activating/de-activating the portal and contains information about + * available destinations and which player activated the portal.

+ * + * @return

This portal's activator

+ */ + public PortalActivator getPortalActivator() { + return this.portalActivator; } /** @@ -103,7 +108,7 @@ public class Portal { * @return

Whether this portal is open

*/ public boolean isOpen() { - return isOpen || options.isAlwaysOn(); + return portalOpener.isOpen(); } /** @@ -112,35 +117,28 @@ public class Portal { * @return

The player currently using this portal

*/ public Player getActivePlayer() { - return activePlayer; + return portalActivator.getActivePlayer(); } /** - * Gets the network this gate belongs to + * Gets the network this portal belongs to * - * @return

The network this gate belongs to

+ * @return

The network this portal belongs to

*/ public String getNetwork() { return network; } - /** - * Sets the network this gate belongs to - * - * @param network

The new network for this gate

- */ - @SuppressWarnings("unused") - public void setNetwork(String network) { - this.network = network; - } - /** * Gets the time this portal opened * + *

The time is given in the equivalent of a Unix timestamp. It's used to decide when a portal times out and + * automatically closes.

+ * * @return

The time this portal opened

*/ public long getOpenTime() { - return openTime; + return portalOpener.getOpenTime(); } /** @@ -153,94 +151,39 @@ public class Portal { } /** - * Sets the name of this portal + * Gets the portal opener used by this portal * - * @param name

The new name of this portal

+ *

The portal opener is responsible for opening and closing this portal.

+ * + * @return

This portal's portal opener

*/ - @SuppressWarnings("unused") - public void setName(String name) { - this.name = filterName(name); - this.drawSign(); + public PortalOpener getPortalOpener() { + return portalOpener; } /** - * Gets the destinations of this portal + * Gets the name of this portal's destination portal * - * @return

The destinations of this portal

- */ - public List getDestinations() { - return new ArrayList<>(this.destinations); - } - - /** - * Gets the portal destination given a player - * - * @param player

Used for random gates to determine which destinations are available

- * @return

The destination portal the player should teleport to

- */ - public Portal getDestination(Player player) { - if (options.isRandom()) { - destinations = PortalHandler.getDestinations(this, player, getNetwork()); - if (destinations.size() == 0) { - return null; - } - String destination = destinations.get((new Random()).nextInt(destinations.size())); - destinations.clear(); - return PortalHandler.getByName(destination, getNetwork()); - } - return PortalHandler.getByName(destination, getNetwork()); - } - - /** - * Gets the portal destination - * - *

If this portal is random, a player should be given to get correct destinations.

- * - * @return

The portal destination

- */ - public Portal getDestination() { - return getDestination(null); - } - - /** - * Sets the destination of this portal - * - * @param destination

The new destination of this portal

- */ - public void setDestination(Portal destination) { - setDestination(destination.getName()); - } - - /** - * Sets the destination of this portal - * - * @param destination

The new destination of this portal

- */ - public void setDestination(String destination) { - this.destination = destination; - } - - /** - * Gets the name of the destination of this portal - * - * @return

The name of this portal's destination

+ * @return

The name of this portal's destination portal

*/ public String getDestinationName() { - return destination; + return portalOpener.getPortalOpener().getDestinationName(); } /** - * Gets the gate used by this portal + * Gets the gate type used by this portal * - * @return

The gate used by this portal

+ * @return

The gate type used by this portal

*/ public Gate getGate() { - return gate; + return structure.getGate(); } /** * Gets the name of this portal's owner * + *

The owner is the player which created the portal.

+ * * @return

The name of this portal's owner

*/ public String getOwnerName() { @@ -250,22 +193,14 @@ public class Portal { /** * Gets the UUID of this portal's owner * + *

The owner is the player which created the portal.

+ * * @return

The UUID of this portal's owner

*/ public UUID getOwnerUUID() { return ownerUUID; } - /** - * Sets the UUId of this portal's owner - * - * @param owner

The new UUID of this portal's owner

- */ - @SuppressWarnings("unused") - public void setOwner(UUID owner) { - this.ownerUUID = owner; - } - /** * Checks whether a given player is the owner of this portal * @@ -280,30 +215,6 @@ public class Portal { } } - /** - * Gets the locations of this portal's entrances - * - * @return

The locations of this portal's entrances

- */ - public BlockLocation[] getEntrances() { - if (entrances == null) { - entrances = relativeBlockVectorsToBlockLocations(gate.getLayout().getEntrances()); - } - return entrances; - } - - /** - * Gets the locations of this portal's frame - * - * @return

The locations of this portal's frame

- */ - public BlockLocation[] getFrame() { - if (frame == null) { - frame = relativeBlockVectorsToBlockLocations(gate.getLayout().getBorder()); - } - return frame; - } - /** * Gets the world this portal belongs to * @@ -314,167 +225,21 @@ public class Portal { } /** - * Gets the location of this portal's button + * Gets the location of this portal's sign * - * @return

The location of this portal's button

- */ - public BlockLocation getButton() { - return button; - } - - /** - * Sets the location of this portal's button - * - * @param button

The location of this portal's button

- */ - public void setButton(BlockLocation button) { - this.button = button; - } - - /** - * Open this portal - * - * @param force

Whether to force this portal open, even if it's already open for some player

- */ - public void open(boolean force) { - open(null, force); - } - - /** - * Open this portal - * - * @param force

Whether to force this portal open, even if it's already open for some player

- */ - public void open(Player openFor, boolean force) { - //Call the StargateOpenEvent - StargateOpenEvent event = new StargateOpenEvent(openFor, this, force); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled() || (isOpen() && !event.getForce())) { - return; - } - - //Change the opening blocks to the correct type - Material openType = gate.getPortalOpenBlock(); - Axis axis = (openType.createBlockData() instanceof Orientable) ? location.getRotationAxis() : null; - for (BlockLocation inside : getEntrances()) { - Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, openType, axis)); - } - - updatePortalOpenState(openFor); - } - - /** - * Updates this portal to be recognized as open and opens its destination portal - * - * @param openFor

The player to open this portal for

- */ - private void updatePortalOpenState(Player openFor) { - //Update the open state of this portal - isOpen = true; - openTime = System.currentTimeMillis() / 1000; - Stargate.openPortalsQueue.add(this); - Stargate.activePortalsQueue.remove(this); - - //Open remote portal - if (!options.isAlwaysOn()) { - player = openFor; - - Portal destination = getDestination(); - //Only open destination if it's not-fixed or points at this portal - if (!options.isRandom() && destination != null && (!destination.options.isFixed() || - destination.getDestinationName().equalsIgnoreCase(getName())) && !destination.isOpen()) { - destination.open(openFor, false); - destination.setDestination(this); - if (destination.isVerified()) { - destination.drawSign(); - } - } - } - } - - /** - * Closes this portal - * - * @param force

Whether to force this portal closed, even if it's set as always on

- */ - public void close(boolean force) { - if (!isOpen) { - return; - } - //Call the StargateCloseEvent - StargateCloseEvent event = new StargateCloseEvent(this, force); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - force = event.getForce(); - - //Only close always-open if forced to - if (options.isAlwaysOn() && !force) { - return; - } - - //Close this gate, then the dest gate. - Material closedType = gate.getPortalClosedBlock(); - for (BlockLocation inside : getEntrances()) { - Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, closedType, null)); - } - - updatePortalClosedState(); - deactivate(); - } - - /** - * Updates this portal to be recognized as closed and closes its destination portal - */ - private void updatePortalClosedState() { - //Update the closed state of this portal - player = null; - isOpen = false; - Stargate.openPortalsQueue.remove(this); - Stargate.activePortalsQueue.remove(this); - - //Close remote portal - if (!options.isAlwaysOn()) { - Portal end = getDestination(); - - if (end != null && end.isOpen()) { - //Clear its destination first - end.deactivate(); - end.close(false); - } - } - } - - /** - * Gets whether this portal is open for the given player - * - * @param player

The player to check portal state for

- * @return

True if this portal is open to the given player

- */ - public boolean isOpenFor(Player player) { - if (!isOpen) { - return false; - } - if (options.isAlwaysOn() || this.player == null) { - return true; - } - return player != null && player.getName().equalsIgnoreCase(this.player.getName()); - } - - /** - * Gets the identity (sign) location of the portal - * - * @return

The identity location of the portal

+ * @return

The location of this portal's sign

*/ public BlockLocation getSignLocation() { return this.location.getSignLocation(); } /** - * Gets the rotation of this portal + * Gets the rotation (yaw) of this portal * - * @return

The rotation of this portal

+ *

The yaw is used to calculate all kinds of directions. See DirectionHelper to see how the yaw is used to + * calculate to/from other direction types.

+ * + * @return

The rotation (yaw) of this portal

*/ public float getYaw() { return this.location.getYaw(); @@ -490,213 +255,19 @@ public class Portal { } /** - * Verifies that all control blocks in this portal follows its gate template + * Gets the block at the given location relative to this portal's top-left block * - * @return

True if all control blocks were verified

- */ - public boolean isVerified() { - verified = true; - if (!Stargate.verifyPortals) { - return true; - } - for (RelativeBlockVector control : gate.getLayout().getControls()) { - verified = verified && getBlockAt(control).getBlock().getType().equals(gate.getControlBlock()); - } - 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; - } - 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; - } - return gate.matches(getTopLeft(), getYaw()); - } - - /** - * Activates this portal for the given player - * - * @param player

The player to activate the portal for

- * @return

True if the portal was activated

- */ - private boolean activate(Player player) { - destinations.clear(); - destination = ""; - Stargate.activePortalsQueue.add(this); - activePlayer = player; - String network = getNetwork(); - destinations = PortalHandler.getDestinations(this, player, network); - if (Stargate.sortNetworkDestinations) { - Collections.sort(destinations); - } - if (Stargate.rememberDestination && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { - destination = lastDestination; - } - - StargateActivateEvent event = new StargateActivateEvent(this, player, destinations, destination); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) { - Stargate.activePortalsQueue.remove(this); - return false; - } - destination = event.getDestination(); - destinations = event.getDestinations(); - this.drawSign(); - return true; - } - - /** - * Deactivates this portal - */ - public void deactivate() { - StargateDeactivateEvent event = new StargateDeactivateEvent(this); - Stargate.server.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - - Stargate.activePortalsQueue.remove(this); - if (options.isFixed()) { - return; - } - destinations.clear(); - destination = ""; - activePlayer = null; - this.drawSign(); - } - - /** - * Gets whether this portal is active - * - * @return

Whether this portal is active

- */ - public boolean isActive() { - return options.isFixed() || (destinations.size() > 0); - } - - /** - * Cycles destination for a network gate forwards - * - * @param player

The player to cycle the gate for

- */ - public void cycleDestination(Player player) { - cycleDestination(player, 1); - } - - /** - * Cycles destination for a network gate - * - * @param player

The player cycling destinations

- * @param direction

The direction of the cycle (+1 for next, -1 for previous)

- */ - public void cycleDestination(Player player, int direction) { - if (direction != 1 && direction != -1) { - throw new IllegalArgumentException("The destination direction must be 1 or -1."); - } - - boolean activate = false; - if (!isActive() || getActivePlayer() != player) { - //If the stargate activate event is cancelled, return - if (!activate(player)) { - return; - } - Stargate.debug("cycleDestination", "Network Size: " + PortalHandler.getNetwork(network).size()); - Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); - activate = true; - } - - if (destinations.size() == 0) { - Stargate.sendErrorMessage(player, Stargate.getString("destEmpty")); - return; - } - - if (!Stargate.rememberDestination || !activate || lastDestination.isEmpty()) { - cycleDestination(direction); - } - openTime = System.currentTimeMillis() / 1000; - this.drawSign(); - } - - /** - * Performs the actual destination cycling with no input checks - * - * @param direction

The direction of the cycle (+1 for next, -1 for previous)

- */ - private void cycleDestination(int direction) { - int index = destinations.indexOf(destination); - index += direction; - - //Wrap around if the last destination has been reached - if (index >= destinations.size()) { - index = 0; - } else if (index < 0) { - index = destinations.size() - 1; - } - //Store selected destination - destination = destinations.get(index); - lastDestination = destination; - } - - /** - * Gets the block at the given location relative to this portal's location - * - * @param vector

The relative block vector

+ * @param vector

The relative block vector explaining the position of the block

* @return

The block at the given relative position

*/ public BlockLocation getBlockAt(RelativeBlockVector vector) { return getTopLeft().getRelativeLocation(vector, getYaw()); } - /** - * Removes the special characters |, : and # from a portal name - * - * @param input

The name to filter

- * @return

The filtered name

- */ - private static String filterName(String input) { - if (input == null) { - return ""; - } - return input.replaceAll("[|:#]", "").trim(); - } - - /** - * Gets a list of block locations from a list of relative block vectors - * - *

The block locations will be calculated by using this portal's top-left block as the origin for the relative - * vectors..

- * - * @param vectors

The relative block vectors to convert

- * @return

A list of block locations

- */ - private BlockLocation[] relativeBlockVectorsToBlockLocations(RelativeBlockVector[] vectors) { - BlockLocation[] locations = new BlockLocation[vectors.length]; - for (int i = 0; i < vectors.length; i++) { - locations[i] = getBlockAt(vectors[i]); - } - return locations; - } - @Override public String toString() { return String.format("Portal [id=%s, network=%s name=%s, type=%s]", getSignLocation(), network, name, - gate.getFilename()); + structure.getGate().getFilename()); } @Override diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java new file mode 100644 index 0000000..c8ca84e --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -0,0 +1,241 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.event.StargateActivateEvent; +import net.knarcraft.stargate.event.StargateDeactivateEvent; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +/** + * The portal destinations contain information about a portal's destinations, and is responsible for cycling destinations + * + *

The activator is responsible for activating/de-activating the portal and contains information about + * available destinations and which player activated the portal.

+ */ +public class PortalActivator { + + private String destination; + private String lastDestination = ""; + private List destinations = new ArrayList<>(); + private final Portal portal; + private final PortalOpener activator; + private Player activePlayer; + + /** + * Instantiates a new portal destinations object + * + * @param portal

The portal which this this object stores destinations for

+ * @param activator

The activator to use when a player activates a portal

+ * @param destination

+ */ + public PortalActivator(Portal portal, PortalOpener activator, String destination) { + this.portal = portal; + this.activator = activator; + this.destination = destination; + } + + /** + * Gets the player currently using this portal activator's portal + * + * @return

The player currently using this portal activator's portal

+ */ + public Player getActivePlayer() { + return activePlayer; + } + + /** + * Gets the destinations of this portal + * + * @return

The destinations of this portal

+ */ + public List getDestinations() { + return new ArrayList<>(this.destinations); + } + + /** + * Gets the portal destination given a player + * + * @param player

Used for random gates to determine which destinations are available

+ * @return

The destination portal the player should teleport to

+ */ + public Portal getDestination(Player player) { + if (portal.getOptions().isRandom()) { + destinations = PortalHandler.getDestinations(portal, player, portal.getNetwork()); + if (destinations.size() == 0) { + return null; + } + String destination = destinations.get((new Random()).nextInt(destinations.size())); + destinations.clear(); + return PortalHandler.getByName(destination, portal.getNetwork()); + } + return PortalHandler.getByName(destination, portal.getNetwork()); + } + + /** + * Activates this portal for the given player + * + * @param player

The player to activate the portal for

+ * @return

True if the portal was activated

+ */ + boolean activate(Player player) { + this.destination = ""; + this.destinations.clear(); + Stargate.activePortalsQueue.add(portal); + activePlayer = player; + String network = portal.getNetwork(); + destinations = PortalHandler.getDestinations(portal, player, network); + if (Stargate.sortNetworkDestinations) { + Collections.sort(destinations); + } + if (Stargate.rememberDestination && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { + destination = lastDestination; + } + + StargateActivateEvent event = new StargateActivateEvent(portal, player, destinations, destination); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + Stargate.activePortalsQueue.remove(portal); + return false; + } + destination = event.getDestination(); + destinations = event.getDestinations(); + portal.drawSign(); + return true; + } + + /** + * Deactivates this portal + */ + public void deactivate() { + StargateDeactivateEvent event = new StargateDeactivateEvent(portal); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + + Stargate.activePortalsQueue.remove(portal); + if (portal.getOptions().isFixed()) { + return; + } + destinations.clear(); + destination = ""; + activePlayer = null; + portal.drawSign(); + } + + /** + * Gets whether this portal is active + * + * @return

Whether this portal is active

+ */ + public boolean isActive() { + return portal.getOptions().isFixed() || (destinations.size() > 0); + } + + /** + * Gets the portal destination + * + *

If this portal is random, a player should be given to get correct destinations.

+ * + * @return

The portal destination

+ */ + public Portal getDestination() { + return getDestination(null); + } + + /** + * Sets the destination of this portal + * + * @param destination

The new destination of this portal

+ */ + public void setDestination(Portal destination) { + setDestination(destination.getName()); + } + + /** + * Sets the destination of this portal + * + * @param destination

The new destination of this portal

+ */ + public void setDestination(String destination) { + this.destination = destination; + } + + /** + * Gets the name of the destination of this portal + * + * @return

The name of this portal's destination

+ */ + public String getDestinationName() { + return destination; + } + + /** + * Cycles destination for a network gate forwards + * + * @param player

The player to cycle the gate for

+ */ + public void cycleDestination(Player player) { + cycleDestination(player, 1); + } + + /** + * Cycles destination for a network gate + * + * @param player

The player cycling destinations

+ * @param direction

The direction of the cycle (+1 for next, -1 for previous)

+ */ + public void cycleDestination(Player player, int direction) { + if (direction != 1 && direction != -1) { + throw new IllegalArgumentException("The destination direction must be 1 or -1."); + } + + boolean activate = false; + if (!isActive() || getActivePlayer() != player) { + //If the stargate activate event is cancelled, return + if (!activate(player)) { + return; + } + Stargate.debug("cycleDestination", "Network Size: " + + PortalHandler.getNetwork(portal.getNetwork()).size()); + Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); + activate = true; + } + + if (destinations.size() == 0) { + Stargate.sendErrorMessage(player, Stargate.getString("destEmpty")); + return; + } + + if (!Stargate.rememberDestination || !activate || lastDestination.isEmpty()) { + cycleDestination(direction); + } + activator.setOpenTime(System.currentTimeMillis() / 1000); + portal.drawSign(); + } + + /** + * Performs the actual destination cycling with no input checks + * + * @param direction

The direction of the cycle (+1 for next, -1 for previous)

+ */ + private void cycleDestination(int direction) { + int index = destinations.indexOf(destination); + index += direction; + + //Wrap around if the last destination has been reached + if (index >= destinations.size()) { + index = 0; + } else if (index < 0) { + index = destinations.size() - 1; + } + //Store selected destination + destination = destinations.get(index); + lastDestination = destination; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 1ff3bb6..71740d5 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -119,26 +119,28 @@ public class PortalHandler { */ public static void unregisterPortal(Portal portal, boolean removeAll) { Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); - portal.close(true); + portal.getPortalOpener().closePortal(true); String portalName = portal.getName().toLowerCase(); String networkName = portal.getNetwork().toLowerCase(); //Remove portal from lookup blocks - for (BlockLocation block : portal.getFrame()) { + for (BlockLocation block : portal.getStructure().getFrame()) { lookupBlocks.remove(block); } //Remove registered info about the lookup controls and blocks lookupBlocks.remove(portal.getSignLocation()); lookupControls.remove(portal.getSignLocation()); - if (portal.getButton() != null) { - lookupBlocks.remove(portal.getButton()); - lookupControls.remove(portal.getButton()); + + BlockLocation button = portal.getStructure().getButton(); + if (button != null) { + lookupBlocks.remove(button); + lookupControls.remove(button); } //Remove entrances - for (BlockLocation entrance : portal.getEntrances()) { + for (BlockLocation entrance : portal.getStructure().getEntrances()) { lookupEntrances.remove(entrance); } @@ -158,7 +160,8 @@ public class PortalHandler { //Update all portals in the same network with this portal as its destination for (String originName : allPortalNetworks.get(networkName)) { Portal origin = getByName(originName, portal.getNetwork()); - if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || !origin.isVerified()) { + if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || + !origin.getStructure().isVerified()) { continue; } //Update the portal's sign @@ -167,7 +170,7 @@ public class PortalHandler { } //Close portal without destination if (origin.getOptions().isAlwaysOn()) { - origin.close(true); + origin.getPortalOpener().closePortal(true); } } } @@ -218,19 +221,21 @@ public class PortalHandler { } //Register all frame blocks to the lookup list - for (BlockLocation block : portal.getFrame()) { + for (BlockLocation block : portal.getStructure().getFrame()) { lookupBlocks.put(block, portal); } //Register the sign and button to the lookup lists lookupBlocks.put(portal.getSignLocation(), portal); lookupControls.put(portal.getSignLocation(), portal); - if (portal.getButton() != null) { - lookupBlocks.put(portal.getButton(), portal); - lookupControls.put(portal.getButton(), portal); + + BlockLocation button = portal.getStructure().getButton(); + if (button != null) { + lookupBlocks.put(button, portal); + lookupControls.put(button, portal); } //Register entrances to the lookup list - for (BlockLocation entrance : portal.getEntrances()) { + for (BlockLocation entrance : portal.getStructure().getEntrances()) { lookupEntrances.put(entrance, portal); } @@ -574,7 +579,7 @@ public class PortalHandler { Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); buttonData.setFacing(buttonFacing); button.getBlock().setBlockData(buttonData); - portal.setButton(button); + portal.getStructure().setButton(button); } /** @@ -587,16 +592,16 @@ public class PortalHandler { portal.drawSign(); //Open an always on portal if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { - portal.open(true); + portal.getPortalOpener().openPortal(true); } else if (portal.getOptions().isAlwaysOn()) { Portal destinationPortal = getByName(destinationName, portal.getNetwork()); if (destinationPortal != null) { - portal.open(true); + portal.getPortalOpener().openPortal(true); destinationPortal.drawSign(); } } else { //Update the block type for the portal's opening to the closed block - for (BlockLocation entrance : portal.getEntrances()) { + for (BlockLocation entrance : portal.getStructure().getEntrances()) { entrance.setType(portal.getGate().getPortalClosedBlock()); } } @@ -612,7 +617,7 @@ public class PortalHandler { Portal origin = getByName(originName, portal.getNetwork()); if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portal.getName()) || - !origin.isVerified()) { + !origin.getStructure().isVerified()) { continue; } //Update sign of fixed gates pointing at this gate @@ -621,7 +626,7 @@ public class PortalHandler { } //Open any always on portal pointing at this portal if (origin.getOptions().isAlwaysOn()) { - origin.open(true); + origin.getPortalOpener().openPortal(true); } } } @@ -791,7 +796,7 @@ public class PortalHandler { String wName = portal.getWorld().getName(); if (!wName.equalsIgnoreCase(world.getName())) continue; StringBuilder builder = new StringBuilder(); - BlockLocation button = portal.getButton(); + BlockLocation button = portal.getStructure().getButton(); builder.append(portal.getName()).append(':'); builder.append(portal.getSignLocation().toString()).append(':'); @@ -1007,7 +1012,7 @@ public class PortalHandler { network, gate, ownerUUID, ownerName, getPortalOptions(portalData)); registerPortal(portal); - portal.close(true); + portal.getPortalOpener().closePortal(true); } /** @@ -1040,7 +1045,8 @@ public class PortalHandler { } // Verify portal integrity/register portal - if (!portal.wasVerified() && (!portal.isVerified() || !portal.checkIntegrity())) { + PortalStructure structure = portal.getStructure(); + if (!structure.wasVerified() && (!structure.isVerified() || !structure.checkIntegrity())) { destroyInvalidPortal(portal); iterator.remove(); continue; @@ -1049,8 +1055,8 @@ public class PortalHandler { //Open the gate if it's set as always open or if it's a bungee gate if (portal.getOptions().isFixed() && (Stargate.enableBungee && portal.getOptions().isBungee() || - portal.getDestination() != null && portal.getOptions().isAlwaysOn())) { - portal.open(true); + portal.getPortalActivator().getDestination() != null && portal.getOptions().isAlwaysOn())) { + portal.getPortalOpener().openPortal(true); openCount++; } } @@ -1080,7 +1086,7 @@ public class PortalHandler { Stargate.logger.info("Closing all stargates."); for (Portal portal : allPortals) { if (portal != null) { - portal.close(true); + portal.getPortalOpener().closePortal(true); } } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java new file mode 100644 index 0000000..c169c6f --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -0,0 +1,203 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockChangeRequest; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.event.StargateCloseEvent; +import net.knarcraft.stargate.event.StargateOpenEvent; +import org.bukkit.Axis; +import org.bukkit.Material; +import org.bukkit.block.data.Orientable; +import org.bukkit.entity.Player; + +/** + * The portal opener is responsible for opening and closing a portal + */ +public class PortalOpener { + + private boolean isOpen = false; + private final Portal portal; + private long openTime; + private Player player; + private final PortalActivator portalActivator; + + /** + * Instantiates a new portal opener + * + * @param portal

The portal this portal opener should open

+ * @param destination

The fixed destination defined on the portal's sign

+ */ + public PortalOpener(Portal portal, String destination) { + this.portal = portal; + this.portalActivator = new PortalActivator(portal, this, destination); + } + + /** + * Gets whether this portal activator's portal is currently open + * + * @return

Whether this portal activator's portal is open

+ */ + public boolean isOpen() { + return isOpen || portal.getOptions().isAlwaysOn(); + } + + /** + * Sets the time when this portal was activated + * + * @param openTime

Unix timestamp when portal was activated

+ */ + public void setOpenTime(long openTime) { + this.openTime = openTime; + } + + /** + * Gets the destinations this portal activator has available + * + * @return

The available destinations

+ */ + public PortalActivator getPortalOpener() { + return this.portalActivator; + } + + /** + * Open this portal + * + * @param force

Whether to force this portal open, even if it's already open for some player

+ */ + public void openPortal(boolean force) { + openPortal(null, force); + } + + /** + * Open this portal + * + * @param force

Whether to force this portal open, even if it's already open for some player

+ */ + public void openPortal(Player openFor, boolean force) { + //Call the StargateOpenEvent + StargateOpenEvent event = new StargateOpenEvent(openFor, portal, force); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled() || (isOpen() && !event.getForce())) { + return; + } + + //Change the opening blocks to the correct type + Material openType = portal.getGate().getPortalOpenBlock(); + Axis axis = (openType.createBlockData() instanceof Orientable) ? portal.getLocation().getRotationAxis() : null; + for (BlockLocation inside : portal.getStructure().getEntrances()) { + Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, openType, axis)); + } + + updatePortalOpenState(openFor); + } + + /** + * Updates this portal to be recognized as open and opens its destination portal + * + * @param openFor

The player to open this portal for

+ */ + private void updatePortalOpenState(Player openFor) { + //Update the open state of this portal + isOpen = true; + openTime = System.currentTimeMillis() / 1000; + Stargate.openPortalsQueue.add(portal); + Stargate.activePortalsQueue.remove(portal); + PortalOptions options = portal.getOptions(); + + //Open remote portal + if (!options.isAlwaysOn()) { + player = openFor; + + Portal destination = portal.getPortalActivator().getDestination(); + //Only open destination if it's not-fixed or points at this portal + if (!options.isRandom() && destination != null && (!destination.getOptions().isFixed() || + destination.getDestinationName().equalsIgnoreCase(portal.getName())) && !destination.isOpen()) { + destination.getPortalOpener().openPortal(openFor, false); + destination.getPortalActivator().setDestination(portal); + if (destination.getStructure().isVerified()) { + destination.drawSign(); + } + } + } + } + + /** + * Closes this portal + * + * @param force

Whether to force this portal closed, even if it's set as always on

+ */ + public void closePortal(boolean force) { + if (!isOpen) { + return; + } + //Call the StargateCloseEvent + StargateCloseEvent event = new StargateCloseEvent(portal, force); + Stargate.server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + force = event.getForce(); + + //Only close always-open if forced to + if (portal.getOptions().isAlwaysOn() && !force) { + return; + } + + //Close this gate, then the dest gate. + Material closedType = portal.getGate().getPortalClosedBlock(); + for (BlockLocation inside : portal.getStructure().getEntrances()) { + Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, closedType, null)); + } + + updatePortalClosedState(); + portalActivator.deactivate(); + } + + /** + * Updates this portal to be recognized as closed and closes its destination portal + */ + private void updatePortalClosedState() { + //Update the closed state of this portal + player = null; + isOpen = false; + Stargate.openPortalsQueue.remove(portal); + Stargate.activePortalsQueue.remove(portal); + + //Close remote portal + if (!portal.getOptions().isAlwaysOn()) { + Portal end = portal.getPortalActivator().getDestination(); + + if (end != null && end.isOpen()) { + //Clear its destination first + end.getPortalActivator().deactivate(); + end.getPortalOpener().closePortal(false); + } + } + } + + /** + * Gets whether this portal is open for the given player + * + * @param player

The player to check portal state for

+ * @return

True if this portal is open to the given player

+ */ + public boolean isOpenFor(Player player) { + if (!isOpen) { + return false; + } + if (portal.getOptions().isAlwaysOn() || this.player == null) { + return true; + } + return player != null && player.getName().equalsIgnoreCase(this.player.getName()); + } + + /** + * Gets the time this portal activator's portal opened + * + * @return

The time this portal activator's portal opened

+ */ + public long getOpenTime() { + return openTime; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 9b85e0b..0467f4d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -53,7 +53,7 @@ public class PortalSignDrawer { Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.signColor + portal.getName() + ChatColor.WHITE + "-"); - if (!portal.isActive()) { + if (!portal.getPortalActivator().isActive()) { //Default sign text drawInactiveSign(sign); } else { @@ -78,9 +78,10 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawNetworkSign(Sign sign) { - int maxIndex = portal.getDestinations().size() - 1; + PortalActivator destinations = portal.getPortalActivator(); + int maxIndex = destinations.getDestinations().size() - 1; int signLineIndex = 0; - int destinationIndex = portal.getDestinations().indexOf(portal.getDestinationName()); + int destinationIndex = destinations.getDestinations().indexOf(portal.getDestinationName()); boolean freeGatesGreen = EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen; //Last, and not only entry. Draw the entry two back @@ -131,12 +132,15 @@ public class PortalSignDrawer { * @param destinationIndex

The index of the destination to draw

*/ private void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex) { + PortalActivator destinations = portal.getPortalActivator(); if (freeGatesGreen) { - Portal destination = PortalHandler.getByName(portal.getDestinations().get(destinationIndex), portal.getNetwork()); + Portal destination = PortalHandler.getByName(destinations.getDestinations().get(destinationIndex), + portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + portal.getDestinations().get(destinationIndex)); + Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + + destinations.getDestinations().get(destinationIndex)); } else { - Stargate.setLine(sign, signLineIndex, portal.getDestinations().get(destinationIndex)); + Stargate.setLine(sign, signLineIndex, destinations.getDestinations().get(destinationIndex)); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java b/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java new file mode 100644 index 0000000..73509b7 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java @@ -0,0 +1,147 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; + +/** + * The portal structure is responsible for the physical properties of a portal + * + *

The portal structure knows which gate type is used, where the real locations of buttons, frames and entrances are + * and whether the portal is verified.

+ */ +public class PortalStructure { + + private final Portal portal; + private final Gate gate; + private BlockLocation button; + private BlockLocation[] frame; + private BlockLocation[] entrances; + private boolean verified; + + /** + * Instantiates a new portal structure + * + * @param portal

The portal whose structure to store

+ * @param gate

The gate type used by this portal structure

+ * @param button

The real location of the portal's button

+ */ + public PortalStructure(Portal portal, Gate gate, BlockLocation button) { + this.portal = portal; + this.gate = gate; + this.verified = false; + this.button = button; + } + + /** + * Gets the gate used by this portal structure + * + * @return

The gate used by this portal structure

+ */ + public Gate getGate() { + return gate; + } + + /** + * Gets the location of this portal's button + * + * @return

The location of this portal's button

+ */ + public BlockLocation getButton() { + return button; + } + + /** + * Sets the location of this portal's button + * + * @param button

The location of this portal's button

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

True if all control blocks were verified

+ */ + public boolean isVerified() { + boolean verified = true; + if (!Stargate.verifyPortals) { + return true; + } + for (RelativeBlockVector control : gate.getLayout().getControls()) { + verified = verified && portal.getBlockAt(control).getBlock().getType().equals(gate.getControlBlock()); + } + this.verified = verified; + 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; + } + 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; + } + return gate.matches(portal.getTopLeft(), portal.getYaw()); + } + + /** + * Gets a list of block locations from a list of relative block vectors + * + *

The block locations will be calculated by using this portal's top-left block as the origin for the relative + * vectors..

+ * + * @param vectors

The relative block vectors to convert

+ * @return

A list of block locations

+ */ + private BlockLocation[] relativeBlockVectorsToBlockLocations(RelativeBlockVector[] vectors) { + BlockLocation[] locations = new BlockLocation[vectors.length]; + for (int i = 0; i < vectors.length; i++) { + locations[i] = portal.getBlockAt(vectors[i]); + } + return locations; + } + + /** + * Gets the locations of this portal's entrances + * + * @return

The locations of this portal's entrances

+ */ + public BlockLocation[] getEntrances() { + if (entrances == null) { + //Get the locations of the entrances once, and only if necessary as it's an expensive operation + entrances = relativeBlockVectorsToBlockLocations(gate.getLayout().getEntrances()); + } + return entrances; + } + + /** + * Gets the locations of this portal's frame + * + * @return

The locations of this portal's frame

+ */ + public BlockLocation[] getFrame() { + if (frame == null) { + //Get the locations of the frame blocks once, and only if necessary as it's an expensive operation + frame = relativeBlockVectorsToBlockLocations(gate.getLayout().getBorder()); + } + return frame; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index b869971..6ddd63e 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -21,18 +21,18 @@ public class StarGateThread implements Runnable { continue; } if (time > portal.getOpenTime() + Stargate.getOpenTime()) { - portal.close(false); + portal.getPortalOpener().closePortal(false); iterator.remove(); } } //Deactivate active portals for (Iterator iterator = Stargate.activePortalsQueue.iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); - if (!portal.isActive()) { + if (!portal.getPortalActivator().isActive()) { continue; } if (time > portal.getOpenTime() + Stargate.getActiveTime()) { - portal.deactivate(); + portal.getPortalActivator().deactivate(); iterator.remove(); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 68ffcff..1481970 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -35,7 +35,7 @@ public final class EconomyHelper { // Insufficient Funds if (!success) { sendInsufficientFundsMessage(entrancePortal.getName(), player, cost); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); return true; } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index b0b5c38..454787f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -24,7 +24,7 @@ public final class PermissionHelper { * @param portal

The portal to open

*/ public static void openPortal(Player player, Portal portal) { - Portal destination = portal.getDestination(); + Portal destination = portal.getPortalActivator().getDestination(); //Always-open gate -- Do nothing if (portal.getOptions().isAlwaysOn()) { @@ -46,13 +46,14 @@ public final class PermissionHelper { if (portal.isOpen()) { // Close if this player opened the gate if (portal.getActivePlayer() == player) { - portal.close(false); + portal.getPortalOpener().closePortal(false); } return; } //Gate that someone else is using -- Deny access - if ((!portal.getOptions().isFixed()) && portal.isActive() && (portal.getActivePlayer() != player)) { + if ((!portal.getOptions().isFixed()) && portal.getPortalActivator().isActive() && + (portal.getActivePlayer() != player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } @@ -70,7 +71,7 @@ public final class PermissionHelper { } //Open gate - portal.open(player, false); + portal.getPortalOpener().openPortal(player, false); } /** @@ -388,7 +389,7 @@ public final class PermissionHelper { } // Not open for this player - if (!entrancePortal.isOpenFor(player)) { + if (!entrancePortal.getPortalOpener().isOpenFor(player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); return true; @@ -403,7 +404,7 @@ public final class PermissionHelper { if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); - entrancePortal.close(false); + entrancePortal.getPortalOpener().closePortal(false); return true; } From 2650e31d97c70af650ba34629b74c03162b96d7b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 20 Oct 2021 20:55:51 +0200 Subject: [PATCH 171/378] Fixes comments for the portal activator --- .../stargate/portal/PortalActivator.java | 174 +++++++++++------- 1 file changed, 110 insertions(+), 64 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index c8ca84e..9ef75b1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -11,46 +11,47 @@ import java.util.List; import java.util.Random; /** - * The portal destinations contain information about a portal's destinations, and is responsible for cycling destinations + * The portal activator activates/de-activates portals and keeps track of a portal's destinations * - *

The activator is responsible for activating/de-activating the portal and contains information about + *

The portal activator is responsible for activating/de-activating the portal and contains information about * available destinations and which player activated the portal.

*/ public class PortalActivator { + private final Portal portal; + private final PortalOpener opener; + + private List destinations = new ArrayList<>(); private String destination; private String lastDestination = ""; - private List destinations = new ArrayList<>(); - private final Portal portal; - private final PortalOpener activator; private Player activePlayer; /** * Instantiates a new portal destinations object * - * @param portal

The portal which this this object stores destinations for

- * @param activator

The activator to use when a player activates a portal

- * @param destination

+ * @param portal

The portal which this this object stores destinations for

+ * @param portalOpener

The portal opener to trigger when the activation causes the portal to open

+ * @param destination

The fixed destination specified on the portal's sign

*/ - public PortalActivator(Portal portal, PortalOpener activator, String destination) { + public PortalActivator(Portal portal, PortalOpener portalOpener, String destination) { this.portal = portal; - this.activator = activator; + this.opener = portalOpener; this.destination = destination; } /** - * Gets the player currently using this portal activator's portal + * Gets the player which this activator's portal is currently activated for * - * @return

The player currently using this portal activator's portal

+ * @return

The player this activator's portal is currently activated for

*/ public Player getActivePlayer() { return activePlayer; } /** - * Gets the destinations of this portal + * Gets the available portal destinations * - * @return

The destinations of this portal

+ * @return

The available portal destinations

*/ public List getDestinations() { return new ArrayList<>(this.destinations); @@ -63,44 +64,112 @@ public class PortalActivator { * @return

The destination portal the player should teleport to

*/ public Portal getDestination(Player player) { + String portalNetwork = portal.getNetwork(); if (portal.getOptions().isRandom()) { - destinations = PortalHandler.getDestinations(portal, player, portal.getNetwork()); + //Find possible destinations + List destinations = PortalHandler.getDestinations(portal, player, portalNetwork); if (destinations.size() == 0) { return null; } + //Get one random destination String destination = destinations.get((new Random()).nextInt(destinations.size())); - destinations.clear(); - return PortalHandler.getByName(destination, portal.getNetwork()); + return PortalHandler.getByName(destination, portalNetwork); + } else { + //Just return the normal fixed destination + return PortalHandler.getByName(destination, portalNetwork); } - return PortalHandler.getByName(destination, portal.getNetwork()); } /** - * Activates this portal for the given player + * Gets the portal's destination + * + *

For random portals, getDestination must be given a player to decide which destinations are valid. Without a + * player, or with a null player, behavior is only defined for a non-random gate.

+ * + * @return

The portal destination

+ */ + public Portal getDestination() { + return getDestination(null); + } + + /** + * Sets the destination of this portal activator's portal + * + * @param destination

The new destination of this portal activator's portal

+ */ + public void setDestination(Portal destination) { + setDestination(destination.getName()); + } + + /** + * Sets the destination of this portal activator's portal + * + * @param destination

The new destination of this portal activator's portal

+ */ + public void setDestination(String destination) { + this.destination = destination; + } + + /** + * Gets the name of the selected destination + * + * @return

The name of the selected destination

+ */ + public String getDestinationName() { + return destination; + } + + /** + * Activates this activator's portal for the given player * * @param player

The player to activate the portal for

* @return

True if the portal was activated

*/ boolean activate(Player player) { + //Clear previous destination data this.destination = ""; this.destinations.clear(); + + //Adds the active gate to the active queue to allow it to be remotely deactivated Stargate.activePortalsQueue.add(portal); + + //Set the given player as the active player activePlayer = player; + String network = portal.getNetwork(); destinations = PortalHandler.getDestinations(portal, player, network); + + //Sort destinations if enabled if (Stargate.sortNetworkDestinations) { Collections.sort(destinations); } + + //Select last used destination if remember destination is enabled if (Stargate.rememberDestination && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { destination = lastDestination; } + //Trigger an activation event to allow the cancellation to be cancelled + return triggerStargateActivationEvent(player); + } + + /** + * Triggers a stargate activation event to allow other plugins to cancel the activation + * + *

The event may also end up changing destinations.

+ * + * @param player

The player trying to activate this activator's portal

+ * @return

True if the portal was activated. False otherwise

+ */ + private boolean triggerStargateActivationEvent(Player player) { StargateActivateEvent event = new StargateActivateEvent(portal, player, destinations, destination); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { Stargate.activePortalsQueue.remove(portal); return false; } + + //Update destinations in case they changed, and update the sign destination = event.getDestination(); destinations = event.getDestinations(); portal.drawSign(); @@ -111,16 +180,24 @@ public class PortalActivator { * Deactivates this portal */ public void deactivate() { + //Trigger a stargate deactivate event to allow other plugins to cancel the event StargateDeactivateEvent event = new StargateDeactivateEvent(portal); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { return; } + //Un-mark the portal as activated Stargate.activePortalsQueue.remove(portal); + + //For a fixed gate, the destinations and the sign never really change, but at the same time, fixed gates are + // never really activated, so in theory, this check should be redundant. + //TODO: Decide if this check is really useless if (portal.getOptions().isFixed()) { return; } + + //Clear destinations and the active player before re-drawing the sign to show that it's deactivated destinations.clear(); destination = ""; activePlayer = null; @@ -128,54 +205,16 @@ public class PortalActivator { } /** - * Gets whether this portal is active + * Gets whether this portal activator's portal is active * - * @return

Whether this portal is active

+ * @return

Whether this portal activator's portal is active

*/ public boolean isActive() { return portal.getOptions().isFixed() || (destinations.size() > 0); } /** - * Gets the portal destination - * - *

If this portal is random, a player should be given to get correct destinations.

- * - * @return

The portal destination

- */ - public Portal getDestination() { - return getDestination(null); - } - - /** - * Sets the destination of this portal - * - * @param destination

The new destination of this portal

- */ - public void setDestination(Portal destination) { - setDestination(destination.getName()); - } - - /** - * Sets the destination of this portal - * - * @param destination

The new destination of this portal

- */ - public void setDestination(String destination) { - this.destination = destination; - } - - /** - * Gets the name of the destination of this portal - * - * @return

The name of this portal's destination

- */ - public String getDestinationName() { - return destination; - } - - /** - * Cycles destination for a network gate forwards + * Cycles destination for a non-fixed gate by one forwards step * * @param player

The player to cycle the gate for

*/ @@ -184,37 +223,44 @@ public class PortalActivator { } /** - * Cycles destination for a network gate + * Cycles destination for a non-fixed gate * * @param player

The player cycling destinations

* @param direction

The direction of the cycle (+1 for next, -1 for previous)

*/ public void cycleDestination(Player player, int direction) { + //Only allow going exactly one step in either direction if (direction != 1 && direction != -1) { throw new IllegalArgumentException("The destination direction must be 1 or -1."); } boolean activate = false; if (!isActive() || getActivePlayer() != player) { - //If the stargate activate event is cancelled, return + //If not active or not active for the given player, and the activation is denied, just abort if (!activate(player)) { return; } + activate = true; + Stargate.debug("cycleDestination", "Network Size: " + PortalHandler.getNetwork(portal.getNetwork()).size()); Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); - activate = true; } + //If no destinations are available, just tell the player and quit if (destinations.size() == 0) { Stargate.sendErrorMessage(player, Stargate.getString("destEmpty")); return; } + //Cycle if destination remembering is disabled, if the portal was already active, or it has no last destination if (!Stargate.rememberDestination || !activate || lastDestination.isEmpty()) { cycleDestination(direction); } - activator.setOpenTime(System.currentTimeMillis() / 1000); + + //Update the activated time to allow it to be deactivated after a timeout, and re-draw the sign to show the + // selected destination + opener.setActivatedTime(System.currentTimeMillis() / 1000); portal.drawSign(); } From 4b42d4914a1e0975d515cba49b985a16f8aede3c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 20 Oct 2021 20:57:00 +0200 Subject: [PATCH 172/378] Renames openTime to activatedTime, though it's kind of used for both opening and activation --- .../java/net/knarcraft/stargate/portal/Portal.java | 8 ++++---- .../knarcraft/stargate/portal/PortalOpener.java | 14 +++++++------- .../knarcraft/stargate/thread/StarGateThread.java | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 2ea0332..3ff1259 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -130,15 +130,15 @@ public class Portal { } /** - * Gets the time this portal opened + * Gets the time this portal was activated/opened * *

The time is given in the equivalent of a Unix timestamp. It's used to decide when a portal times out and * automatically closes.

* - * @return

The time this portal opened

+ * @return

The time this portal was activated/opened

*/ - public long getOpenTime() { - return portalOpener.getOpenTime(); + public long getActivatedTime() { + return portalOpener.getActivatedTime(); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index c169c6f..3a26834 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -17,7 +17,7 @@ public class PortalOpener { private boolean isOpen = false; private final Portal portal; - private long openTime; + private long activatedTime; private Player player; private final PortalActivator portalActivator; @@ -44,10 +44,10 @@ public class PortalOpener { /** * Sets the time when this portal was activated * - * @param openTime

Unix timestamp when portal was activated

+ * @param activatedTime

Unix timestamp when portal was activated

*/ - public void setOpenTime(long openTime) { - this.openTime = openTime; + public void setActivatedTime(long activatedTime) { + this.activatedTime = activatedTime; } /** @@ -99,7 +99,7 @@ public class PortalOpener { private void updatePortalOpenState(Player openFor) { //Update the open state of this portal isOpen = true; - openTime = System.currentTimeMillis() / 1000; + activatedTime = System.currentTimeMillis() / 1000; Stargate.openPortalsQueue.add(portal); Stargate.activePortalsQueue.remove(portal); PortalOptions options = portal.getOptions(); @@ -196,8 +196,8 @@ public class PortalOpener { * * @return

The time this portal activator's portal opened

*/ - public long getOpenTime() { - return openTime; + public long getActivatedTime() { + return activatedTime; } } diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index 6ddd63e..c2ad0a4 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -20,7 +20,7 @@ public class StarGateThread implements Runnable { if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) { continue; } - if (time > portal.getOpenTime() + Stargate.getOpenTime()) { + if (time > portal.getActivatedTime() + Stargate.getOpenTime()) { portal.getPortalOpener().closePortal(false); iterator.remove(); } @@ -31,7 +31,7 @@ public class StarGateThread implements Runnable { if (!portal.getPortalActivator().isActive()) { continue; } - if (time > portal.getOpenTime() + Stargate.getActiveTime()) { + if (time > portal.getActivatedTime() + Stargate.getActiveTime()) { portal.getPortalActivator().deactivate(); iterator.remove(); } From 8eff9ae5e6839f37a90ea209648460d3a9b1b184 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 21 Oct 2021 00:27:42 +0200 Subject: [PATCH 173/378] Fixes comments for the PortalOpener class --- .../net/knarcraft/stargate/portal/Portal.java | 4 +- .../stargate/portal/PortalOpener.java | 121 +++++++++++------- 2 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 3ff1259..681fdc0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -50,7 +50,7 @@ public class Portal { this.signDrawer = new PortalSignDrawer(this); this.portalOpener = new PortalOpener(this, destination); this.structure = new PortalStructure(this, gate, button); - this.portalActivator = portalOpener.getPortalOpener(); + this.portalActivator = portalOpener.getPortalActivator(); } /** @@ -167,7 +167,7 @@ public class Portal { * @return

The name of this portal's destination portal

*/ public String getDestinationName() { - return portalOpener.getPortalOpener().getDestinationName(); + return portalOpener.getPortalActivator().getDestinationName(); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 3a26834..995479a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -33,123 +33,145 @@ public class PortalOpener { } /** - * Gets whether this portal activator's portal is currently open + * Gets whether this portal opener's portal is currently open * - * @return

Whether this portal activator's portal is open

+ * @return

Whether this portal opener's portal is open

*/ public boolean isOpen() { return isOpen || portal.getOptions().isAlwaysOn(); } /** - * Sets the time when this portal was activated + * Sets the time when this portal was activated/opened * - * @param activatedTime

Unix timestamp when portal was activated

+ * @param activatedTime

Unix timestamp when portal was activated/opened

*/ public void setActivatedTime(long activatedTime) { this.activatedTime = activatedTime; } /** - * Gets the destinations this portal activator has available + * Gets the portal activator belonging to this portal opener * - * @return

The available destinations

+ * @return

The portal activator belonging to this portal opener

*/ - public PortalActivator getPortalOpener() { + public PortalActivator getPortalActivator() { return this.portalActivator; } /** - * Open this portal + * Open this portal opener's portal * - * @param force

Whether to force this portal open, even if it's already open for some player

+ * @param force

Whether to force the portal open, even if it's already open for some player

*/ public void openPortal(boolean force) { openPortal(null, force); } /** - * Open this portal + * Open this portal opener's portal * - * @param force

Whether to force this portal open, even if it's already open for some player

+ * @param force

Whether to force the portal open, even if it's already open for some player

*/ public void openPortal(Player openFor, boolean force) { - //Call the StargateOpenEvent + //Call the StargateOpenEvent to allow the opening to be cancelled StargateOpenEvent event = new StargateOpenEvent(openFor, portal, force); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled() || (isOpen() && !event.getForce())) { return; } - //Change the opening blocks to the correct type + //Get the material to change the opening to Material openType = portal.getGate().getPortalOpenBlock(); + //Adjust orientation if applicable Axis axis = (openType.createBlockData() instanceof Orientable) ? portal.getLocation().getRotationAxis() : null; + + //Change the entrance blocks to the correct type for (BlockLocation inside : portal.getStructure().getEntrances()) { Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, openType, axis)); } + //Update the portal state to make is actually open updatePortalOpenState(openFor); } /** - * Updates this portal to be recognized as open and opens its destination portal + * Updates this portal opener's portal to be recognized as open and opens its destination portal * - * @param openFor

The player to open this portal for

+ * @param openFor

The player to open this portal opener's portal for

*/ private void updatePortalOpenState(Player openFor) { //Update the open state of this portal isOpen = true; activatedTime = System.currentTimeMillis() / 1000; + + //Change state from active to open Stargate.openPortalsQueue.add(portal); Stargate.activePortalsQueue.remove(portal); + PortalOptions options = portal.getOptions(); - //Open remote portal - if (!options.isAlwaysOn()) { - player = openFor; + //If this portal is always open, opening the destination is not necessary + if (options.isAlwaysOn()) { + return; + } - Portal destination = portal.getPortalActivator().getDestination(); - //Only open destination if it's not-fixed or points at this portal - if (!options.isRandom() && destination != null && (!destination.getOptions().isFixed() || - destination.getDestinationName().equalsIgnoreCase(portal.getName())) && !destination.isOpen()) { - destination.getPortalOpener().openPortal(openFor, false); - destination.getPortalActivator().setDestination(portal); - if (destination.getStructure().isVerified()) { - destination.drawSign(); - } + //Update the player the portal is open for + this.player = openFor; + + Portal destination = portal.getPortalActivator().getDestination(); + if (destination == null) { + return; + } + + boolean thisIsDestination = destination.getDestinationName().equalsIgnoreCase(portal.getName()); + //Only open destination if it's not-fixed or points at this portal, and is not already open + if (!options.isRandom() && (!destination.getOptions().isFixed() || thisIsDestination) && !destination.isOpen()) { + //Open the destination portal + destination.getPortalOpener().openPortal(openFor, false); + //Set the destination portal to this opener's portal + destination.getPortalActivator().setDestination(portal); + + //Update the destination's sign if it's verified + if (destination.getStructure().isVerified()) { + destination.drawSign(); } } } /** - * Closes this portal + * Closes this portal opener's portal * - * @param force

Whether to force this portal closed, even if it's set as always on

+ * @param force

Whether to force the portal closed, even if it's set as always on

*/ public void closePortal(boolean force) { + //No need to close a portal which is already closed if (!isOpen) { return; } - //Call the StargateCloseEvent + + //Call the StargateCloseEvent to allow other plugins to cancel the closing, or change whether to force it closed StargateCloseEvent event = new StargateCloseEvent(portal, force); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { return; } - force = event.getForce(); - //Only close always-open if forced to - if (portal.getOptions().isAlwaysOn() && !force) { + //Only close an always-open portal if forced to + if (portal.getOptions().isAlwaysOn() && !event.getForce()) { return; } - //Close this gate, then the dest gate. + //Close the portal by requesting the opening blocks to change Material closedType = portal.getGate().getPortalClosedBlock(); - for (BlockLocation inside : portal.getStructure().getEntrances()) { - Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, closedType, null)); + for (BlockLocation entrance : portal.getStructure().getEntrances()) { + Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(entrance, closedType, null)); } + //Update the portal state to make it actually closed updatePortalClosedState(); + + //Finally, deactivate the portal portalActivator.deactivate(); } @@ -157,44 +179,49 @@ public class PortalOpener { * Updates this portal to be recognized as closed and closes its destination portal */ private void updatePortalClosedState() { - //Update the closed state of this portal + //Unset the stored player and set the portal to closed player = null; isOpen = false; + + //Un-mark the portal as active and open Stargate.openPortalsQueue.remove(portal); Stargate.activePortalsQueue.remove(portal); - //Close remote portal + //Close the destination portal if not always open if (!portal.getOptions().isAlwaysOn()) { - Portal end = portal.getPortalActivator().getDestination(); + Portal destination = portal.getPortalActivator().getDestination(); - if (end != null && end.isOpen()) { - //Clear its destination first - end.getPortalActivator().deactivate(); - end.getPortalOpener().closePortal(false); + if (destination != null && destination.isOpen()) { + //De-activate and close the destination portal + destination.getPortalActivator().deactivate(); + destination.getPortalOpener().closePortal(false); } } } /** - * Gets whether this portal is open for the given player + * Gets whether this portal opener's portal is open for the given player * * @param player

The player to check portal state for

- * @return

True if this portal is open to the given player

+ * @return

True if this portal opener's portal is open to the given player

*/ public boolean isOpenFor(Player player) { + //If closed, it's closed for everyone if (!isOpen) { return false; } + //If always on, or player is null which only happens with an always on portal, allow the player to pass if (portal.getOptions().isAlwaysOn() || this.player == null) { return true; } + //If the player is the player which the portal opened for, allow it to pass return player != null && player.getName().equalsIgnoreCase(this.player.getName()); } /** - * Gets the time this portal activator's portal opened + * Gets the time this portal opener's portal was activated/opened * - * @return

The time this portal activator's portal opened

+ * @return

The time this portal opener's portal was activated/opened

*/ public long getActivatedTime() { return activatedTime; From cb2f7443f57b2e4e3ee8f8e2dd54b7a6e27e7b36 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 21 Oct 2021 16:39:35 +0200 Subject: [PATCH 174/378] Improves comments for PortalOptions --- .../stargate/portal/PortalOptions.java | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java index d2335e8..221fed7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java @@ -5,7 +5,7 @@ import net.knarcraft.stargate.Stargate; import java.util.Map; /** - * Keeps track of all options for a given portal + * Keeps track of all options for one portal */ public class PortalOptions { @@ -37,10 +37,11 @@ public class PortalOptions { /** * Gets whether this portal is fixed * - *

A fixed portal has only one destination which never changes. A fixed portal has a fixed destination, is a - * random portal or is a bungee portal. A fixed portal is always open.

+ *

A fixed portal is a portal for which the player cannot choose destination. A portal with a set destination, a + * random portal and bungee portals are fixed. While the player has no choice regarding destinations, a fixed gate + * may still need to be activated if not set to always on.

* - * @return

Whether this gate is fixed

+ * @return

Whether this portal is fixed

*/ public boolean isFixed() { return this.isFixed; @@ -58,6 +59,9 @@ public class PortalOptions { /** * Gets whether this portal is always on * + *

An always on portal is always open for everyone, and always uses the open-block. It never needs to be + * activated or opened manually.

+ * * @return

Whether this portal is always on

*/ public boolean isAlwaysOn() { @@ -67,6 +71,10 @@ public class PortalOptions { /** * Gets whether this portal is hidden * + *

A hidden portal will be hidden on a network for everyone but admins and the portal owner. In other words, + * when selecting a destination using a portal's sign, hidden gates will only be available in the list for the + * owner and players with the appropriate permission.

+ * * @return

Whether this portal is hidden

*/ public boolean isHidden() { @@ -76,6 +84,9 @@ public class PortalOptions { /** * Gets whether this portal is private * + *

A private portal can only be opened by the owner and players with the appropriate permission. A private gate + * is not hidden unless the hidden option is also enabled.

+ * * @return

Whether this portal is private

*/ public boolean isPrivate() { @@ -85,6 +96,9 @@ public class PortalOptions { /** * Gets whether this portal is free * + *

A free portal is exempt from any fees which would normally occur from using the portal. It does nothing if + * economy is disabled.

+ * * @return

Whether this portal is free

*/ public boolean isFree() { @@ -94,7 +108,8 @@ public class PortalOptions { /** * Gets whether this portal is backwards * - *

A backwards portal is one where players exit through the back.

+ *

A backwards portal is one where players exit through the back. It's important to note that the exit is + * mirrored, not rotated, when exiting backwards.

* * @return

Whether this portal is backwards

*/ @@ -105,6 +120,9 @@ public class PortalOptions { /** * Gets whether this portal is shown on the network even if it's always on * + *

Normally, always-on portals are not selectable on a network, but enabling this option allows the portal to be + * shown.

+ * * @return

Whether portal gate is shown

*/ public boolean isShown() { @@ -114,6 +132,10 @@ public class PortalOptions { /** * Gets whether this portal shows no network * + *

Enabling the no network option allows the portal's network to be hidden for whatever reason. If allowing + * normal players to create portals, this can be used to prevent random users from connecting gates to + * "protected networks".

+ * * @return

Whether this portal shows no network/p> */ public boolean isNoNetwork() { @@ -123,6 +145,8 @@ public class PortalOptions { /** * Gets whether this portal goes to a random location on the network * + *

A random portal is always on and will teleport to a random destination within the same network.

+ * * @return

Whether this portal goes to a random location

*/ public boolean isRandom() { @@ -132,6 +156,9 @@ public class PortalOptions { /** * Gets whether this portal is a bungee portal * + *

A bungee portal is able to teleport to a portal on another server. It works differently from other portals as + * it does not have a network, but instead the network line specifies the same of the server it connects to.

+ * * @return

Whether this portal is a bungee portal

*/ public boolean isBungee() { From 79a43b82e5823e05092c5455b7820ea87fcd9a23 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 21 Oct 2021 20:13:34 +0200 Subject: [PATCH 175/378] Fixes the readme's max sign character limits as the real limit is 11, not 12 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 45a62b0..2f69f1a 100644 --- a/README.md +++ b/README.md @@ -85,9 +85,9 @@ This is the default gate configuration. See the Custom Gate Layout section on ho ### Sign Layout: -- Line 1: Gate Name (Max 12 characters) -- Line 2: Destination Name \[Optional] (Max 12 characters, used for fixed-gates only) -- Line 3: Network name \[Optional] (Max 12 characters) +- Line 1: Gate Name (Max 11 characters) +- Line 2: Destination Name \[Optional] (Max 11 characters, used for fixed-gates only) +- Line 3: Network name \[Optional] (Max 11 characters) - Line 4: Options \[Optional] : - 'A' for always-on fixed gate - 'H' for hidden networked gate From 593d528bcda6498591898cfa286359b7ca061e21 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 21 Oct 2021 20:15:29 +0200 Subject: [PATCH 176/378] Extracts the portal creation and validation part of the PortalHandler into the PortalCreator --- .../stargate/listener/BlockEventListener.java | 3 +- .../stargate/portal/PortalCreator.java | 311 +++++++++++++++++ .../stargate/portal/PortalHandler.java | 323 ++---------------- 3 files changed, 340 insertions(+), 297 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalCreator.java diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 26da8b1..a1ca05d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateDestroyEvent; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalCreator; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; @@ -73,7 +74,7 @@ public class BlockEventListener implements Listener { return; } - final Portal portal = PortalHandler.createPortal(event, player); + final Portal portal = new PortalCreator(event, player).createPortal(); //Not creating a gate, just placing a sign if (portal == null) { return; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java new file mode 100644 index 0000000..8f90732 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -0,0 +1,311 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.event.StargateCreateEvent; +import net.knarcraft.stargate.utility.DirectionHelper; +import net.knarcraft.stargate.utility.EconomyHandler; +import net.knarcraft.stargate.utility.EconomyHelper; +import net.knarcraft.stargate.utility.PermissionHelper; +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Directional; +import org.bukkit.entity.Player; +import org.bukkit.event.block.SignChangeEvent; + +import java.util.List; +import java.util.Map; + +/** + * The portal creator can create and validate a new portal + */ +public class PortalCreator { + + private Portal portal; + private final SignChangeEvent event; + private final Player player; + + /** + * Instantiates a new portal creator + * + * @param event

The sign change event which initialized the creation

+ * @param player

The player creating the portal

+ */ + public PortalCreator(SignChangeEvent event, Player player) { + this.event = event; + this.player = player; + } + + /** + * Creates a new portal + * + * @return

The created portal

+ */ + public Portal createPortal() { + BlockLocation signLocation = new BlockLocation(event.getBlock()); + Block idParent = signLocation.getParent(); + + //Return early if the sign is not placed on a block, or the block is not a control block + if (idParent == null || GateHandler.getGatesByControlBlock(idParent).length == 0) { + Stargate.debug("createPortal", "Control block not registered"); + return null; + } + + //The control block is already part of another portal + if (PortalHandler.getByBlock(idParent) != null) { + Stargate.debug("createPortal", "idParent belongs to existing stargate"); + return null; + } + + //Get necessary information from the gate's sign + String portalName = PortalHandler.filterName(event.getLine(0)); + String destinationName = PortalHandler.filterName(event.getLine(1)); + String network = PortalHandler.filterName(event.getLine(2)); + String options = PortalHandler.filterName(event.getLine(3)).toLowerCase(); + + //Get portal options available to the player creating the portal + Map portalOptions = PortalHandler.getPortalOptions(player, destinationName, options); + + //Get the yaw + float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), signLocation.getLocation()); + + //Get the direction the button should be facing + BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw); + + PortalLocation portalLocation = new PortalLocation(); + portalLocation.setButtonFacing(buttonFacing).setYaw(yaw).setSignLocation(signLocation); + + Stargate.debug("createPortal", "Finished getting all portal info"); + + //Try and find a gate matching the new portal + Gate gate = PortalHandler.findMatchingGate(portalLocation, player); + if ((gate == null) || (portalLocation.getButtonVector() == null)) { + Stargate.debug("createPortal", "Could not find matching gate layout"); + return null; + } + + //If the portal is a bungee portal and invalid, abort here + if (!PortalHandler.isValidBungeePortal(portalOptions, player, destinationName, network)) { + Stargate.debug("createPortal", "Portal is an invalid bungee portal"); + return null; + } + + //Debug + StringBuilder builder = new StringBuilder(); + for (PortalOption option : portalOptions.keySet()) { + builder.append(option.getCharacterRepresentation()).append(" = ").append(portalOptions.get(option)).append(" "); + } + Stargate.debug("createPortal", builder.toString()); + + //Use default network if a proper alternative is not set + if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > 11)) { + network = Stargate.getDefaultNetwork(); + } + + boolean deny = false; + String denyMessage = ""; + + //Check if the player can create portals on this network. If not, create a personal portal + if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { + Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); + if (PermissionHelper.canCreatePersonalGate(player)) { + network = player.getName(); + if (network.length() > 11) { + network = network.substring(0, 11); + } + Stargate.debug("createPortal", "Creating personal portal"); + Stargate.sendErrorMessage(player, Stargate.getString("createPersonal")); + } else { + Stargate.debug("createPortal", "Player does not have access to network"); + deny = true; + denyMessage = Stargate.getString("createNetDeny"); + } + } + + //Check if the player can create this gate layout + String gateName = gate.getFilename(); + gateName = gateName.substring(0, gateName.indexOf('.')); + if (!deny && !PermissionHelper.canCreateGate(player, gateName)) { + Stargate.debug("createPortal", "Player does not have access to gate layout"); + deny = true; + denyMessage = Stargate.getString("createGateDeny"); + } + + //Check if the user can create portals to this world. + if (!portalOptions.get(PortalOption.BUNGEE) && !deny && destinationName.length() > 0) { + Portal portal = PortalHandler.getByName(destinationName, network); + if (portal != null) { + String world = portal.getWorld().getName(); + if (PermissionHelper.cannotAccessWorld(player, world)) { + Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); + deny = true; + denyMessage = Stargate.getString("createWorldDeny"); + } + } + } + + //Check if a conflict exists + if (PortalHandler.conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), yaw, player)) { + return null; + } + + this.portal = new Portal(portalLocation, null, destinationName, portalName, + network, gate, player.getUniqueId(), player.getName(), portalOptions); + return validatePortal(denyMessage, event.getLines(), deny); + } + + /** + * Validates the newly created portal assigned to this portal validator + * + * @param denyMessage

The deny message to displayed if the creation has already been denied

+ * @param lines

The lines on the sign causing the portal to be created

+ * @param deny

Whether the portal creation has already been denied

+ * @return

The portal or null if its creation was denied

+ */ + public Portal validatePortal(String denyMessage, String[] lines, boolean deny) { + PortalLocation portalLocation = portal.getLocation(); + Gate gate = portal.getStructure().getGate(); + PortalOptions portalOptions = portal.getOptions(); + String portalName = portal.getName(); + String destinationName = portal.getDestinationName(); + + int createCost = EconomyHandler.getCreateCost(player, gate); + + //Call StargateCreateEvent to let other plugins cancel or overwrite denial + StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, lines, deny, + denyMessage, createCost); + Stargate.server.getPluginManager().callEvent(stargateCreateEvent); + if (stargateCreateEvent.isCancelled()) { + return null; + } + + //Tell the user why it was denied from creating the portal + if (stargateCreateEvent.getDeny()) { + Stargate.sendErrorMessage(player, stargateCreateEvent.getDenyReason()); + return null; + } + + createCost = stargateCreateEvent.getCost(); + + //Check if the new portal is valid + if (!checkIfNewPortalIsValid(createCost, portalName)) { + return null; + } + + //Add button if the portal is not always on + if (!portalOptions.isAlwaysOn()) { + generatePortalButton(portalLocation.getTopLeft(), portalLocation.getButtonVector(), + portalLocation.getButtonFacing()); + } + + //Register the new portal + PortalHandler.registerPortal(portal); + updateNewPortalOpenState(destinationName); + + //Update portals pointing at this one if it's not a bungee portal + if (!portal.getOptions().isBungee()) { + PortalHandler.updatePortalsPointingAtNewPortal(portal); + } + + PortalHandler.saveAllPortals(portal.getWorld()); + + return portal; + } + + /** + * Checks whether the newly created, but unregistered portal is valid + * + * @param cost

The cost of creating the portal

+ * @param portalName

The name of the newly created portal

+ * @return

True if the portal is completely valid

+ */ + private boolean checkIfNewPortalIsValid(int cost, String portalName) { + // Name & Network can be changed in the event, so do these checks here. + if (portal.getName().length() < 1 || portal.getName().length() > 11) { + Stargate.debug("createPortal", "Name length error"); + Stargate.sendErrorMessage(player, Stargate.getString("createNameLength")); + return false; + } + + //Don't do network checks for bungee portals + if (portal.getOptions().isBungee()) { + if (PortalHandler.getBungeePortals().get(portal.getName().toLowerCase()) != null) { + Stargate.debug("createPortal::Bungee", "Gate name duplicate"); + Stargate.sendErrorMessage(player, Stargate.getString("createExists")); + return false; + } + } else { + if (PortalHandler.getByName(portal.getName(), portal.getNetwork()) != null) { + Stargate.debug("createPortal", "Gate name duplicate"); + Stargate.sendErrorMessage(player, Stargate.getString("createExists")); + return false; + } + + //Check if there are too many gates in this network + List networkList = PortalHandler.getAllPortalNetworks().get(portal.getNetwork().toLowerCase()); + if (Stargate.maxGatesEachNetwork > 0 && networkList != null && networkList.size() >= Stargate.maxGatesEachNetwork) { + Stargate.sendErrorMessage(player, Stargate.getString("createFull")); + return false; + } + } + + if (cost > 0) { + if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { + EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); + Stargate.debug("createPortal", "Insufficient Funds"); + return false; + } else { + EconomyHelper.sendDeductMessage(portalName, player, cost); + } + } + return true; + } + + /** + * Generates a button for a portal + * + * @param topLeft

The top-left block of the portal

+ * @param buttonVector

A relative vector pointing at the button

+ * @param buttonFacing

The direction the button should be facing

+ */ + private void generatePortalButton(BlockLocation topLeft, RelativeBlockVector buttonVector, + BlockFace buttonFacing) { + //Go one block outwards to find the button's location rather than the control block's location + BlockLocation button = topLeft.getRelativeLocation(buttonVector.addToVector( + RelativeBlockVector.Property.DISTANCE, 1), portal.getYaw()); + + Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); + buttonData.setFacing(buttonFacing); + button.getBlock().setBlockData(buttonData); + portal.getStructure().setButton(button); + } + + /** + * Updates the open state of the newly created portal + * + * @param destinationName

The name of the destination portal. Only used if set as always on

+ */ + private void updateNewPortalOpenState(String destinationName) { + portal.drawSign(); + if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { + //Open the implicitly always on portal + portal.getPortalOpener().openPortal(true); + } else if (portal.getOptions().isAlwaysOn()) { + //For a normal always-on portal, open both the portal and the destination + Portal destinationPortal = PortalHandler.getByName(destinationName, portal.getNetwork()); + if (destinationPortal != null) { + portal.getPortalOpener().openPortal(true); + destinationPortal.drawSign(); + } + } else { + //Update the block type for the portal's opening to the closed block as the closed block can be anything, + // not just air or water + for (BlockLocation entrance : portal.getStructure().getEntrances()) { + entrance.setType(portal.getGate().getPortalClosedBlock()); + } + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 71740d5..bfaa576 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -4,22 +4,15 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.container.TwoTuple; -import net.knarcraft.stargate.event.StargateCreateEvent; -import net.knarcraft.stargate.utility.DirectionHelper; -import net.knarcraft.stargate.utility.EconomyHandler; -import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; -import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Player; -import org.bukkit.event.block.SignChangeEvent; import java.io.BufferedWriter; import java.io.File; @@ -42,16 +35,32 @@ public class PortalHandler { private static final Map lookupEntrances = new HashMap<>(); private static final Map lookupControls = new HashMap<>(); private static final List allPortals = new ArrayList<>(); - private static final HashMap> allPortalNetworks = new HashMap<>(); - private static final HashMap> portalLookupByNetwork = new HashMap<>(); - - // A list of Bungee gates + private static final Map> allPortalNetworks = new HashMap<>(); + private static final Map> portalLookupByNetwork = new HashMap<>(); private static final Map bungeePortals = new HashMap<>(); private PortalHandler() { } + /** + * Gets a copy of all portal networks + * + * @return

A copy of all portal networks

+ */ + public static Map> getAllPortalNetworks() { + return new HashMap<>(allPortalNetworks); + } + + /** + * Gets a copy of all bungee portals + * + * @return

A copy of all bungee portals

+ */ + public static Map getBungeePortals() { + return new HashMap<>(bungeePortals); + } + /** * Gets names of all portals within a network * @@ -193,7 +202,7 @@ public class PortalHandler { * * @param portal

The portal to register

*/ - private static void registerPortal(Portal portal) { + static void registerPortal(Portal portal) { portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || portal.getOptions().isBungee()); @@ -242,124 +251,6 @@ public class PortalHandler { allPortals.add(portal); } - /** - * Creates a new portal - * - * @param event

The sign change event which initialized the creation

- * @param player

The player who's creating the portal

- * @return

The created portal

- */ - public static Portal createPortal(SignChangeEvent event, Player player) { - BlockLocation signLocation = new BlockLocation(event.getBlock()); - Block idParent = signLocation.getParent(); - - //Return early if the sign is not placed on a block, or the block is not a control block - if (idParent == null || GateHandler.getGatesByControlBlock(idParent).length == 0) { - Stargate.debug("createPortal", "Control block not registered"); - return null; - } - - //The control block is already part of another portal - if (getByBlock(idParent) != null) { - Stargate.debug("createPortal", "idParent belongs to existing stargate"); - return null; - } - - //Get necessary information from the gate's sign - String portalName = filterName(event.getLine(0)); - String destinationName = filterName(event.getLine(1)); - String network = filterName(event.getLine(2)); - String options = filterName(event.getLine(3)).toLowerCase(); - - //Get portal options available to the player creating the portal - Map portalOptions = getPortalOptions(player, destinationName, options); - - //Get the yaw - float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), signLocation.getLocation()); - - //Get the direction the button should be facing - BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw); - - PortalLocation portalLocation = new PortalLocation(); - portalLocation.setButtonFacing(buttonFacing).setYaw(yaw).setSignLocation(signLocation); - - Stargate.debug("createPortal", "Finished getting all portal info"); - - //Try and find a gate matching the new portal - Gate gate = findMatchingGate(portalLocation, player); - if ((gate == null) || (portalLocation.getButtonVector() == null)) { - Stargate.debug("createPortal", "Could not find matching gate layout"); - return null; - } - - //If the portal is a bungee portal and invalid, abort here - if (!isValidBungeePortal(portalOptions, player, destinationName, network)) { - Stargate.debug("createPortal", "Portal is an invalid bungee portal"); - return null; - } - - //Debug - StringBuilder builder = new StringBuilder(); - for (PortalOption option : portalOptions.keySet()) { - builder.append(option.getCharacterRepresentation()).append(" = ").append(portalOptions.get(option)).append(" "); - } - Stargate.debug("createPortal", builder.toString()); - - //Use default network if a proper alternative is not set - if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > 11)) { - network = Stargate.getDefaultNetwork(); - } - - boolean deny = false; - String denyMessage = ""; - - //Check if the player can create portals on this network - if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { - Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); - if (PermissionHelper.canCreatePersonalGate(player)) { - network = player.getName(); - if (network.length() > 11) network = network.substring(0, 11); - Stargate.debug("createPortal", "Creating personal portal"); - Stargate.sendErrorMessage(player, Stargate.getString("createPersonal")); - } else { - Stargate.debug("createPortal", "Player does not have access to network"); - deny = true; - denyMessage = Stargate.getString("createNetDeny"); - //return null; - } - } - - //Check if the player can create this gate layout - String gateName = gate.getFilename(); - gateName = gateName.substring(0, gateName.indexOf('.')); - if (!deny && !PermissionHelper.canCreateGate(player, gateName)) { - Stargate.debug("createPortal", "Player does not have access to gate layout"); - deny = true; - denyMessage = Stargate.getString("createGateDeny"); - } - - //Check if the user can create portals to this world. - if (!portalOptions.get(PortalOption.BUNGEE) && !deny && destinationName.length() > 0) { - Portal portal = getByName(destinationName, network); - if (portal != null) { - String world = portal.getWorld().getName(); - if (PermissionHelper.cannotAccessWorld(player, world)) { - Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); - deny = true; - denyMessage = Stargate.getString("createWorldDeny"); - } - } - } - - //Check if a conflict exists - if (conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), yaw, player)) { - return null; - } - - return createAndValidateNewPortal(portalLocation, destinationName, portalName, network, gate, - player, portalOptions, denyMessage, event.getLines(), deny); - } - /** * Checks if the new portal is a valid bungee portal * @@ -369,8 +260,8 @@ public class PortalHandler { * @param network

The name of the portal's network

* @return

False if the portal is an invalid bungee portal. True otherwise

*/ - private static boolean isValidBungeePortal(Map portalOptions, Player player, - String destinationName, String network) { + static boolean isValidBungeePortal(Map portalOptions, Player player, + String destinationName, String network) { if (portalOptions.get(PortalOption.BUNGEE)) { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); @@ -393,7 +284,7 @@ public class PortalHandler { * @param player

The player trying to create the new portal

* @return

The matching gate type, or null if no such gate could be found

*/ - private static Gate findMatchingGate(PortalLocation portalLocation, Player player) { + static Gate findMatchingGate(PortalLocation portalLocation, Player player) { Block signParent = portalLocation.getSignLocation().getParent(); BlockLocation parent = new BlockLocation(player.getWorld(), signParent.getX(), signParent.getY(), signParent.getZ()); @@ -432,7 +323,7 @@ public class PortalHandler { * @param player

The player creating the new portal

* @return

True if a conflict was found. False otherwise

*/ - private static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, double yaw, Player player) { + static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, double yaw, Player player) { //TODO: Make a quicker check. Could just check for control block conflicts if all code is changed to account for // getting several hits at a single location when checking for the existence of a portal. May make // everything slower overall? Would make for cooler gates though. @@ -447,172 +338,12 @@ public class PortalHandler { return false; } - /** - * Creates and validates a new portal - * - * @param destinationName

The name of the portal's destination

- * @param portalName

The name of the new portal

- * @param network

The name of the new portal's network

- * @param gate

The gate type used in the physical construction of the new portal

- * @param player

The player creating the new portal

- * @param portalOptions

A map of enabled and disabled portal options

- * @param denyMessage

The deny message to display if the portal creation was denied

- * @param lines

All the lines of the sign which initiated the portal creation

- * @param deny

Whether to deny the creation of the new portal

- * @return

A new portal, or null if the input cases the creation to be denied

- */ - private static Portal createAndValidateNewPortal(PortalLocation portalLocation, String destinationName, - String portalName, String network, Gate gate, Player player, - Map portalOptions, String denyMessage, - String[] lines, boolean deny) { - Portal portal = new Portal(portalLocation, null, destinationName, portalName, - network, gate, player.getUniqueId(), player.getName(), portalOptions); - - int createCost = EconomyHandler.getCreateCost(player, gate); - - //Call StargateCreateEvent to let other plugins cancel or overwrite denial - StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, lines, deny, - denyMessage, createCost); - Stargate.server.getPluginManager().callEvent(stargateCreateEvent); - if (stargateCreateEvent.isCancelled()) { - return null; - } - - //Tell the user why it was denied from creating the portal - if (stargateCreateEvent.getDeny()) { - Stargate.sendErrorMessage(player, stargateCreateEvent.getDenyReason()); - return null; - } - - createCost = stargateCreateEvent.getCost(); - - //Check if the new portal is valid - if (!checkIfNewPortalIsValid(portal, player, createCost, portalName)) { - return null; - } - - //Add button if the portal is not always on - if (!portalOptions.get(PortalOption.ALWAYS_ON)) { - generatePortalButton(portal, portalLocation.getTopLeft(), portalLocation.getButtonVector(), - portalLocation.getButtonFacing()); - } - - //Register the new portal - registerPortal(portal); - updateNewPortal(portal, destinationName); - - //Update portals pointing at this one if it's not a bungee portal - if (!portal.getOptions().isBungee()) { - updatePortalsPointingAtNewPortal(portal); - } - - saveAllPortals(portal.getWorld()); - - return portal; - } - - /** - * Checks whether the newly created, but unregistered portal is valid - * - * @param portal

The portal to validate

- * @param player

The player creating the portal

- * @param cost

The cost of creating the portal

- * @param portalName

The name of the newly created portal

- * @return

True if the portal is completely valid

- */ - private static boolean checkIfNewPortalIsValid(Portal portal, Player player, int cost, String portalName) { - // Name & Network can be changed in the event, so do these checks here. - if (portal.getName().length() < 1 || portal.getName().length() > 11) { - Stargate.debug("createPortal", "Name length error"); - Stargate.sendErrorMessage(player, Stargate.getString("createNameLength")); - return false; - } - - //Don't do network checks for bungee portals - if (portal.getOptions().isBungee()) { - if (bungeePortals.get(portal.getName().toLowerCase()) != null) { - Stargate.debug("createPortal::Bungee", "Gate name duplicate"); - Stargate.sendErrorMessage(player, Stargate.getString("createExists")); - return false; - } - } else { - if (getByName(portal.getName(), portal.getNetwork()) != null) { - Stargate.debug("createPortal", "Gate name duplicate"); - Stargate.sendErrorMessage(player, Stargate.getString("createExists")); - return false; - } - - //Check if there are too many gates in this network - List networkList = allPortalNetworks.get(portal.getNetwork().toLowerCase()); - if (Stargate.maxGatesEachNetwork > 0 && networkList != null && networkList.size() >= Stargate.maxGatesEachNetwork) { - Stargate.sendErrorMessage(player, Stargate.getString("createFull")); - return false; - } - } - - if (cost > 0) { - if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { - EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); - Stargate.debug("createPortal", "Insufficient Funds"); - return false; - } else { - EconomyHelper.sendDeductMessage(portalName, player, cost); - } - } - return true; - } - - /** - * Generates a button for a portal - * - * @param portal

The portal to generate a button for

- * @param topLeft

The top-left block of the portal

- * @param buttonVector

A relative vector pointing at the button

- * @param buttonFacing

The direction the button should be facing

- */ - private static void generatePortalButton(Portal portal, BlockLocation topLeft, RelativeBlockVector buttonVector, - BlockFace buttonFacing) { - //Go one block outwards to find the button's location rather than the control block's location - BlockLocation button = topLeft.getRelativeLocation(buttonVector.addToVector( - RelativeBlockVector.Property.DISTANCE, 1), portal.getYaw()); - - Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); - buttonData.setFacing(buttonFacing); - button.getBlock().setBlockData(buttonData); - portal.getStructure().setButton(button); - } - - /** - * Updates the open state of the newly created portal - * - * @param portal

The portal newly created

- * @param destinationName

The name of the destination portal

- */ - private static void updateNewPortal(Portal portal, String destinationName) { - portal.drawSign(); - //Open an always on portal - if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { - portal.getPortalOpener().openPortal(true); - } else if (portal.getOptions().isAlwaysOn()) { - Portal destinationPortal = getByName(destinationName, portal.getNetwork()); - if (destinationPortal != null) { - portal.getPortalOpener().openPortal(true); - destinationPortal.drawSign(); - } - } else { - //Update the block type for the portal's opening to the closed block - for (BlockLocation entrance : portal.getStructure().getEntrances()) { - entrance.setType(portal.getGate().getPortalClosedBlock()); - } - } - } - /** * Updates the sign and open state of portals pointing at the newly created portal * * @param portal

The newly created portal

*/ - private static void updatePortalsPointingAtNewPortal(Portal portal) { + static void updatePortalsPointingAtNewPortal(Portal portal) { for (String originName : allPortalNetworks.get(portal.getNetwork().toLowerCase())) { Portal origin = getByName(originName, portal.getNetwork()); if (origin == null || @@ -639,7 +370,7 @@ public class PortalHandler { * @param options

The string on the option line of the sign

* @return

A map containing all portal options and their values

*/ - private static Map getPortalOptions(Player player, String destinationName, String options) { + static Map getPortalOptions(Player player, String destinationName, String options) { Map portalOptions = new HashMap<>(); for (PortalOption option : PortalOption.values()) { portalOptions.put(option, options.indexOf(option.getCharacterRepresentation()) != -1 && From 4e09b44c7c8e1e9ecf1c1aabb0c003bfac7e4449 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 21 Oct 2021 23:59:16 +0200 Subject: [PATCH 177/378] Extracts portal registration and all portal lookup to the PortalRegistry class --- .../java/net/knarcraft/stargate/Stargate.java | 5 +- .../stargate/listener/WorldEventListener.java | 3 +- .../stargate/portal/PortalHandler.java | 212 ++----------- .../stargate/portal/PortalRegistry.java | 290 ++++++++++++++++++ 4 files changed, 316 insertions(+), 194 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 547cdd3..b8f9dd9 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -16,6 +16,7 @@ import net.knarcraft.stargate.listener.WorldEventListener; import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; @@ -292,7 +293,7 @@ public class Stargate extends JavaPlugin { @Override public void onDisable() { PortalHandler.closeAllPortals(); - PortalHandler.clearPortals(); + PortalRegistry.clearPortals(); managedWorlds.clear(); getServer().getScheduler().cancelTasks(this); } @@ -571,7 +572,7 @@ public class Stargate extends JavaPlugin { activePortalsQueue.clear(); openPortalsQueue.clear(); managedWorlds.clear(); - PortalHandler.clearPortals(); + PortalRegistry.clearPortals(); GateHandler.clearGates(); // Store the old Bungee enabled value diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index f934418..0fa3ed9 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalRegistry; import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -39,7 +40,7 @@ public class WorldEventListener implements Listener { String worldName = world.getName(); if (Stargate.managedWorlds.contains(worldName)) { Stargate.managedWorlds.remove(worldName); - PortalHandler.clearPortals(world); + PortalRegistry.clearPortals(world); } } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index bfaa576..f4a9708 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -11,7 +11,6 @@ import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; -import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Player; import java.io.BufferedWriter; @@ -30,14 +29,6 @@ import java.util.logging.Level; * Keeps track of all loaded portals, and handles portal creation */ public class PortalHandler { - // Static variables used to store portal lists - private static final Map lookupBlocks = new HashMap<>(); - private static final Map lookupEntrances = new HashMap<>(); - private static final Map lookupControls = new HashMap<>(); - private static final List allPortals = new ArrayList<>(); - private static final Map> allPortalNetworks = new HashMap<>(); - private static final Map> portalLookupByNetwork = new HashMap<>(); - private static final Map bungeePortals = new HashMap<>(); private PortalHandler() { @@ -49,7 +40,7 @@ public class PortalHandler { * @return

A copy of all portal networks

*/ public static Map> getAllPortalNetworks() { - return new HashMap<>(allPortalNetworks); + return PortalRegistry.getAllPortalNetworks(); } /** @@ -58,7 +49,7 @@ public class PortalHandler { * @return

A copy of all bungee portals

*/ public static Map getBungeePortals() { - return new HashMap<>(bungeePortals); + return PortalRegistry.getBungeePortals(); } /** @@ -68,7 +59,7 @@ public class PortalHandler { * @return

A list of portal names

*/ public static List getNetwork(String network) { - return allPortalNetworks.get(network.toLowerCase()); + return PortalRegistry.getNetwork(network); } /** @@ -81,7 +72,7 @@ public class PortalHandler { */ public static List getDestinations(Portal entrancePortal, Player player, String network) { List destinations = new ArrayList<>(); - for (String destination : allPortalNetworks.get(network.toLowerCase())) { + for (String destination : PortalRegistry.getAllPortalNetworks().get(network.toLowerCase())) { Portal portal = getByName(destination, network); if (portal == null) { continue; @@ -127,74 +118,7 @@ public class PortalHandler { * @param removeAll

Whether to remove the portal from the list of all portals

*/ public static void unregisterPortal(Portal portal, boolean removeAll) { - Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); - portal.getPortalOpener().closePortal(true); - - String portalName = portal.getName().toLowerCase(); - String networkName = portal.getNetwork().toLowerCase(); - - //Remove portal from lookup blocks - for (BlockLocation block : portal.getStructure().getFrame()) { - lookupBlocks.remove(block); - } - - //Remove registered info about the lookup controls and blocks - lookupBlocks.remove(portal.getSignLocation()); - lookupControls.remove(portal.getSignLocation()); - - BlockLocation button = portal.getStructure().getButton(); - if (button != null) { - lookupBlocks.remove(button); - lookupControls.remove(button); - } - - //Remove entrances - for (BlockLocation entrance : portal.getStructure().getEntrances()) { - lookupEntrances.remove(entrance); - } - - //Remove the portal from the list of all portals - if (removeAll) { - allPortals.remove(portal); - } - - if (portal.getOptions().isBungee()) { - //Remove the bungee listing - bungeePortals.remove(portalName); - } else { - //Remove from network lists - portalLookupByNetwork.get(networkName).remove(portalName); - allPortalNetworks.get(networkName).remove(portalName); - - //Update all portals in the same network with this portal as its destination - for (String originName : allPortalNetworks.get(networkName)) { - Portal origin = getByName(originName, portal.getNetwork()); - if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || - !origin.getStructure().isVerified()) { - continue; - } - //Update the portal's sign - if (origin.getOptions().isFixed()) { - origin.drawSign(); - } - //Close portal without destination - if (origin.getOptions().isAlwaysOn()) { - origin.getPortalOpener().closePortal(true); - } - } - } - - //Clear sign data - if (portal.getSignLocation().getBlock().getBlockData() instanceof WallSign) { - Sign sign = (Sign) portal.getSignLocation().getBlock().getState(); - sign.setLine(0, portal.getName()); - sign.setLine(1, ""); - sign.setLine(2, ""); - sign.setLine(3, ""); - sign.update(); - } - - saveAllPortals(portal.getWorld()); + PortalRegistry.unregisterPortal(portal, removeAll); } /** @@ -203,52 +127,7 @@ public class PortalHandler { * @param portal

The portal to register

*/ static void registerPortal(Portal portal) { - portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || - portal.getOptions().isBungee()); - - String portalName = portal.getName().toLowerCase(); - String networkName = portal.getNetwork().toLowerCase(); - - //Bungee portals are stored in their own list - if (portal.getOptions().isBungee()) { - bungeePortals.put(portalName, portal); - } else { - //Check if network exists in the lookup list. If not, register the new network - if (!portalLookupByNetwork.containsKey(networkName)) { - Stargate.debug("register", "Network " + portal.getNetwork() + " not in lookupNamesNet, adding"); - portalLookupByNetwork.put(networkName, new HashMap<>()); - } - //Check if this network exists in the network list. If not, register the network - if (!allPortalNetworks.containsKey(networkName)) { - Stargate.debug("register", "Network " + portal.getNetwork() + " not in allPortalsNet, adding"); - allPortalNetworks.put(networkName, new ArrayList<>()); - } - - //Register the portal - portalLookupByNetwork.get(networkName).put(portalName, portal); - allPortalNetworks.get(networkName).add(portalName); - } - - //Register all frame blocks to the lookup list - for (BlockLocation block : portal.getStructure().getFrame()) { - lookupBlocks.put(block, portal); - } - //Register the sign and button to the lookup lists - lookupBlocks.put(portal.getSignLocation(), portal); - lookupControls.put(portal.getSignLocation(), portal); - - BlockLocation button = portal.getStructure().getButton(); - if (button != null) { - lookupBlocks.put(button, portal); - lookupControls.put(button, portal); - } - - //Register entrances to the lookup list - for (BlockLocation entrance : portal.getStructure().getEntrances()) { - lookupEntrances.put(entrance, portal); - } - - allPortals.add(portal); + PortalRegistry.registerPortal(portal); } /** @@ -344,7 +223,7 @@ public class PortalHandler { * @param portal

The newly created portal

*/ static void updatePortalsPointingAtNewPortal(Portal portal) { - for (String originName : allPortalNetworks.get(portal.getNetwork().toLowerCase())) { + for (String originName : PortalRegistry.getAllPortalNetworks().get(portal.getNetwork().toLowerCase())) { Portal origin = getByName(originName, portal.getNetwork()); if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portal.getName()) || @@ -409,10 +288,11 @@ public class PortalHandler { * @return

The portal with the given name or null

*/ public static Portal getByName(String name, String network) { - if (!portalLookupByNetwork.containsKey(network.toLowerCase())) { + Map> lookupMap = PortalRegistry.getPortalLookupByNetwork(); + if (!lookupMap.containsKey(network.toLowerCase())) { return null; } - return portalLookupByNetwork.get(network.toLowerCase()).get(name.toLowerCase()); + return lookupMap.get(network.toLowerCase()).get(name.toLowerCase()); } @@ -423,8 +303,8 @@ public class PortalHandler { * @return

The portal at the given location

*/ public static Portal getByEntrance(Location location) { - return lookupEntrances.get(new BlockLocation(location.getWorld(), location.getBlockX(), location.getBlockY(), - location.getBlockZ())); + return PortalRegistry.getLookupEntrances().get(new BlockLocation(location.getWorld(), location.getBlockX(), + location.getBlockY(), location.getBlockZ())); } /** @@ -434,7 +314,7 @@ public class PortalHandler { * @return

The portal at the given block's location

*/ public static Portal getByEntrance(Block block) { - return lookupEntrances.get(new BlockLocation(block)); + return PortalRegistry.getLookupEntrances().get(new BlockLocation(block)); } /** @@ -473,7 +353,7 @@ public class PortalHandler { } for (BlockLocation adjacentPosition : adjacentPositions) { - Portal portal = lookupEntrances.get(adjacentPosition); + Portal portal = PortalRegistry.getLookupEntrances().get(adjacentPosition); if (portal != null) { return portal; } @@ -488,7 +368,7 @@ public class PortalHandler { * @return

The portal with the given control block

*/ public static Portal getByControl(Block block) { - return lookupControls.get(new BlockLocation(block)); + return PortalRegistry.getLookupControls().get(new BlockLocation(block)); } /** @@ -498,7 +378,7 @@ public class PortalHandler { * @return

The portal corresponding to the block

*/ public static Portal getByBlock(Block block) { - return lookupBlocks.get(new BlockLocation(block)); + return PortalRegistry.getLookupBlocks().get(new BlockLocation(block)); } /** @@ -508,7 +388,7 @@ public class PortalHandler { * @return

A bungee portal

*/ public static Portal getBungeePortal(String name) { - return bungeePortals.get(name.toLowerCase()); + return PortalRegistry.getBungeePortals().get(name.toLowerCase()); } /** @@ -523,7 +403,7 @@ public class PortalHandler { try { BufferedWriter bw = new BufferedWriter(new FileWriter(loc, false)); - for (Portal portal : allPortals) { + for (Portal portal : PortalRegistry.getAllPortals()) { String wName = portal.getWorld().getName(); if (!wName.equalsIgnoreCase(world.getName())) continue; StringBuilder builder = new StringBuilder(); @@ -567,56 +447,6 @@ public class PortalHandler { } } - /** - * Clears all loaded portals and portal data from all worlds - */ - public static void clearPortals() { - lookupBlocks.clear(); - portalLookupByNetwork.clear(); - lookupEntrances.clear(); - lookupControls.clear(); - allPortals.clear(); - allPortalNetworks.clear(); - } - - /** - * Clears all portals loaded in a given world - * - * @param world

The world containing the portals to clear

- */ - public static void clearPortals(World world) { - //This is necessary - List portalsToRemove = new ArrayList<>(); - allPortals.forEach((portal) -> { - if (portal.getWorld().equals(world)) { - portalsToRemove.add(portal); - } - }); - - clearPortals(portalsToRemove); - } - - /** - * Clears a given list of portals from all relevant variables - * - * @param portalsToRemove

A list of portals to remove

- */ - private static void clearPortals(List portalsToRemove) { - List portalNames = new ArrayList<>(); - portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); - lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); - portalLookupByNetwork.keySet().forEach((network) -> portalLookupByNetwork.get(network).keySet().removeIf((key) -> - portalsToRemove.contains(portalLookupByNetwork.get(network).get(key)))); - //Remove any networks with no portals - portalLookupByNetwork.keySet().removeIf((key) -> portalLookupByNetwork.get(key).isEmpty()); - lookupEntrances.keySet().removeIf((key) -> portalsToRemove.contains(lookupEntrances.get(key))); - lookupControls.keySet().removeIf((key) -> portalsToRemove.contains(lookupControls.get(key))); - allPortals.removeIf(portalsToRemove::contains); - allPortalNetworks.keySet().forEach((network) -> allPortalNetworks.get(network).removeIf(portalNames::contains)); - //Remove any networks with no portals - allPortalNetworks.keySet().removeIf((network) -> allPortalNetworks.get(network).isEmpty()); - } - /** * Loads all portals for the given world * @@ -675,7 +505,7 @@ public class PortalHandler { portalCounts.getFirstValue())); //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since - for (Portal portal : allPortals) { + for (Portal portal : PortalRegistry.getAllPortals()) { portal.drawSign(); } return true; @@ -769,7 +599,7 @@ public class PortalHandler { private static TwoTuple openAlwaysOpenPortals() { int portalCount = 0; int openCount = 0; - for (Iterator iterator = allPortals.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = PortalRegistry.getAllPortals().iterator(); iterator.hasNext(); ) { Portal portal = iterator.next(); if (portal == null) { continue; @@ -815,7 +645,7 @@ public class PortalHandler { */ public static void closeAllPortals() { Stargate.logger.info("Closing all stargates."); - for (Portal portal : allPortals) { + for (Portal portal : PortalRegistry.getAllPortals()) { if (portal != null) { portal.getPortalOpener().closePortal(true); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java new file mode 100644 index 0000000..165e680 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -0,0 +1,290 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockLocation; +import org.bukkit.World; +import org.bukkit.block.Sign; +import org.bukkit.block.data.type.WallSign; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * The portal registry keeps track of all registered portals and all their lookup blocks + */ +public class PortalRegistry { + + private static final Map lookupBlocks = new HashMap<>(); + private static final Map lookupEntrances = new HashMap<>(); + private static final Map lookupControls = new HashMap<>(); + + private static final Map> portalLookupByNetwork = new HashMap<>(); + private static final Map> allPortalNetworks = new HashMap<>(); + private static final Map bungeePortals = new HashMap<>(); + + private static final List allPortals = new ArrayList<>(); + + /** + * Clears all portals and all data held by the portal registry + */ + public static void clearPortals() { + lookupBlocks.clear(); + portalLookupByNetwork.clear(); + lookupEntrances.clear(); + lookupControls.clear(); + allPortals.clear(); + allPortalNetworks.clear(); + } + + /** + * Clears all portals loaded in a given world + * + * @param world

The world containing the portals to clear

+ */ + public static void clearPortals(World world) { + //Storing the portals to clear is necessary to avoid a concurrent modification exception + List portalsToRemove = new ArrayList<>(); + allPortals.forEach((portal) -> { + if (portal.getWorld().equals(world)) { + portalsToRemove.add(portal); + } + }); + + clearPortals(portalsToRemove); + } + + /** + * Clears a given list of portals from all relevant variables + * + * @param portalsToRemove

A list of portals to remove

+ */ + private static void clearPortals(List portalsToRemove) { + //Store the names of the portals to remove as some maps require the name, not the object + List portalNames = new ArrayList<>(); + portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); + + //Clear all the lookup locations for the portals + lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); + lookupEntrances.keySet().removeIf((key) -> portalsToRemove.contains(lookupEntrances.get(key))); + lookupControls.keySet().removeIf((key) -> portalsToRemove.contains(lookupControls.get(key))); + + //Remove the portals from all networks, and then remove any empty networks. This is done for both network maps + portalLookupByNetwork.keySet().forEach((network) -> portalLookupByNetwork.get(network).keySet().removeIf((key) -> + portalsToRemove.contains(portalLookupByNetwork.get(network).get(key)))); + portalLookupByNetwork.keySet().removeIf((key) -> portalLookupByNetwork.get(key).isEmpty()); + allPortalNetworks.keySet().forEach((network) -> allPortalNetworks.get(network).removeIf(portalNames::contains)); + allPortalNetworks.keySet().removeIf((network) -> allPortalNetworks.get(network).isEmpty()); + + //Finally, remove the portals from the portal list + allPortals.removeIf(portalsToRemove::contains); + } + + /** + * Gets a copy of the list of all portals + * + * @return

A copy of the list of all portals

+ */ + public static List getAllPortals() { + return new ArrayList<>(allPortals); + } + + /** + * Gets a copy of the lookup map for finding a portal by its frame + * + * @return

A copy of the frame block lookup map

+ */ + public static Map getLookupBlocks() { + return new HashMap<>(lookupBlocks); + } + + /** + * Gets a copy of the lookup map for finding a portal by its control block + * + * @return

A copy of the control block lookup map

+ */ + public static Map getLookupControls() { + return new HashMap<>(lookupControls); + } + + /** + * Gets a copy of the lookup map for finding all portals in a network + * + * @return

A copy of the network portal lookup map

+ */ + public static Map> getPortalLookupByNetwork() { + return new HashMap<>(portalLookupByNetwork); + } + + /** + * Gets a copy of all portal entrances available for lookup + * + * @return

A copy of all entrances to portal mappings

+ */ + public static Map getLookupEntrances() { + return new HashMap<>(lookupEntrances); + } + + /** + * Gets a copy of all portal networks + * + * @return

A copy of all portal networks

+ */ + public static Map> getAllPortalNetworks() { + return new HashMap<>(allPortalNetworks); + } + + /** + * Gets a copy of all bungee portals + * + * @return

A copy of all bungee portals

+ */ + public static Map getBungeePortals() { + return new HashMap<>(bungeePortals); + } + + /** + * Gets names of all portals within a network + * + * @param network

The network to get portals from

+ * @return

A list of portal names

+ */ + public static List getNetwork(String network) { + return allPortalNetworks.get(network.toLowerCase()); + } + + /** + * Un-registers the given portal + * + * @param portal

The portal to un-register

+ * @param removeAll

Whether to remove the portal from the list of all portals

+ */ + public static void unregisterPortal(Portal portal, boolean removeAll) { + Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); + portal.getPortalOpener().closePortal(true); + + String portalName = portal.getName().toLowerCase(); + String networkName = portal.getNetwork().toLowerCase(); + + //Remove portal from lookup blocks + for (BlockLocation block : portal.getStructure().getFrame()) { + lookupBlocks.remove(block); + } + + //Remove registered info about the lookup controls and blocks + lookupBlocks.remove(portal.getSignLocation()); + lookupControls.remove(portal.getSignLocation()); + + BlockLocation button = portal.getStructure().getButton(); + if (button != null) { + lookupBlocks.remove(button); + lookupControls.remove(button); + } + + //Remove entrances + for (BlockLocation entrance : portal.getStructure().getEntrances()) { + lookupEntrances.remove(entrance); + } + + //Remove the portal from the list of all portals + if (removeAll) { + allPortals.remove(portal); + } + + if (portal.getOptions().isBungee()) { + //Remove the bungee listing + bungeePortals.remove(portalName); + } else { + //Remove from network lists + portalLookupByNetwork.get(networkName).remove(portalName); + allPortalNetworks.get(networkName).remove(portalName); + + //Update all portals in the same network with this portal as its destination + for (String originName : allPortalNetworks.get(networkName)) { + Portal origin = PortalHandler.getByName(originName, portal.getNetwork()); + if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || + !origin.getStructure().isVerified()) { + continue; + } + //Update the portal's sign + if (origin.getOptions().isFixed()) { + origin.drawSign(); + } + //Close portal without destination + if (origin.getOptions().isAlwaysOn()) { + origin.getPortalOpener().closePortal(true); + } + } + } + + //Clear sign data + if (portal.getSignLocation().getBlock().getBlockData() instanceof WallSign) { + Sign sign = (Sign) portal.getSignLocation().getBlock().getState(); + sign.setLine(0, portal.getName()); + sign.setLine(1, ""); + sign.setLine(2, ""); + sign.setLine(3, ""); + sign.update(); + } + + PortalHandler.saveAllPortals(portal.getWorld()); + } + + /** + * Registers a portal + * + * @param portal

The portal to register

+ */ + static void registerPortal(Portal portal) { + portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || + portal.getOptions().isBungee()); + + String portalName = portal.getName().toLowerCase(); + String networkName = portal.getNetwork().toLowerCase(); + + //Bungee portals are stored in their own list + if (portal.getOptions().isBungee()) { + bungeePortals.put(portalName, portal); + } else { + //Check if network exists in the lookup list. If not, register the new network + if (!portalLookupByNetwork.containsKey(networkName)) { + Stargate.debug("register", "Network " + portal.getNetwork() + + " not in lookupNamesNet, adding"); + portalLookupByNetwork.put(networkName, new HashMap<>()); + } + //Check if this network exists in the network list. If not, register the network + if (!allPortalNetworks.containsKey(networkName)) { + Stargate.debug("register", "Network " + portal.getNetwork() + + " not in allPortalsNet, adding"); + allPortalNetworks.put(networkName, new ArrayList<>()); + } + + //Register the portal + portalLookupByNetwork.get(networkName).put(portalName, portal); + allPortalNetworks.get(networkName).add(portalName); + } + + //Register all frame blocks to the lookup list + for (BlockLocation block : portal.getStructure().getFrame()) { + lookupBlocks.put(block, portal); + } + //Register the sign and button to the lookup lists + lookupBlocks.put(portal.getSignLocation(), portal); + lookupControls.put(portal.getSignLocation(), portal); + + BlockLocation button = portal.getStructure().getButton(); + if (button != null) { + lookupBlocks.put(button, portal); + lookupControls.put(button, portal); + } + + //Register entrances to the lookup list + for (BlockLocation entrance : portal.getStructure().getEntrances()) { + lookupEntrances.put(entrance, portal); + } + + allPortals.add(portal); + } + +} From 485ca284b0d1790e95bc6372b25500135241b76d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 22 Oct 2021 16:18:35 +0200 Subject: [PATCH 178/378] Extracts portal saving and loading to the PortalFileHelper class --- .../java/net/knarcraft/stargate/Stargate.java | 3 +- .../stargate/listener/WorldEventListener.java | 4 +- .../stargate/portal/PortalCreator.java | 3 +- .../stargate/portal/PortalHandler.java | 201 +---------- .../stargate/portal/PortalRegistry.java | 3 +- .../stargate/utility/PortalFileHelper.java | 315 ++++++++++++++++++ 6 files changed, 326 insertions(+), 203 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index b8f9dd9..2bc73e3 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -22,6 +22,7 @@ import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.FileHelper; +import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; @@ -532,7 +533,7 @@ public class Stargate extends JavaPlugin { public void loadAllPortals() { for (World world : getServer().getWorlds()) { if (!managedWorlds.contains(world.getName())) { - PortalHandler.loadAllPortals(world); + PortalFileHelper.loadAllPortals(world); managedWorlds.add(world.getName()); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 0fa3ed9..6ee5ba8 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -23,7 +23,7 @@ public class WorldEventListener implements Listener { @EventHandler public void onWorldLoad(WorldLoadEvent event) { if (!Stargate.managedWorlds.contains(event.getWorld().getName()) && - PortalHandler.loadAllPortals(event.getWorld())) { + PortalFileHelper.loadAllPortals(event.getWorld())) { Stargate.managedWorlds.add(event.getWorld().getName()); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 8f90732..b044a37 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -8,6 +8,7 @@ import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -209,7 +210,7 @@ public class PortalCreator { PortalHandler.updatePortalsPointingAtNewPortal(portal); } - PortalHandler.saveAllPortals(portal.getWorld()); + PortalFileHelper.saveAllPortals(portal.getWorld()); return portal; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index f4a9708..80cb5f4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -5,25 +5,15 @@ import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.utility.PermissionHelper; -import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.OfflinePlayer; -import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Scanner; -import java.util.UUID; -import java.util.logging.Level; /** * Keeps track of all loaded portals, and handles portal creation @@ -126,7 +116,7 @@ public class PortalHandler { * * @param portal

The portal to register

*/ - static void registerPortal(Portal portal) { + public static void registerPortal(Portal portal) { PortalRegistry.registerPortal(portal); } @@ -391,198 +381,13 @@ public class PortalHandler { return PortalRegistry.getBungeePortals().get(name.toLowerCase()); } - /** - * Saves all portals for the given world - * - * @param world

The world to save portals for

- */ - public static void saveAllPortals(World world) { - Stargate.managedWorlds.add(world.getName()); - String loc = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; - - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(loc, false)); - - for (Portal portal : PortalRegistry.getAllPortals()) { - String wName = portal.getWorld().getName(); - if (!wName.equalsIgnoreCase(world.getName())) continue; - StringBuilder builder = new StringBuilder(); - BlockLocation button = portal.getStructure().getButton(); - - builder.append(portal.getName()).append(':'); - builder.append(portal.getSignLocation().toString()).append(':'); - builder.append((button != null) ? button.toString() : "").append(':'); - builder.append(0).append(':'); - builder.append(0).append(':'); - builder.append(portal.getYaw()).append(':'); - builder.append(portal.getTopLeft().toString()).append(':'); - builder.append(portal.getGate().getFilename()).append(':'); - builder.append(portal.getOptions().isFixed() ? portal.getDestinationName() : "").append(':'); - builder.append(portal.getNetwork()).append(':'); - UUID owner = portal.getOwnerUUID(); - if (owner != null) { - builder.append(portal.getOwnerUUID().toString()); - } else { - builder.append(portal.getOwnerName()); - } - builder.append(':'); - builder.append(portal.getOptions().isHidden()).append(':'); - builder.append(portal.getOptions().isAlwaysOn()).append(':'); - builder.append(portal.getOptions().isPrivate()).append(':'); - builder.append(portal.getWorld().getName()).append(':'); - builder.append(portal.getOptions().isFree()).append(':'); - builder.append(portal.getOptions().isBackwards()).append(':'); - builder.append(portal.getOptions().isShown()).append(':'); - builder.append(portal.getOptions().isNoNetwork()).append(':'); - builder.append(portal.getOptions().isRandom()).append(':'); - builder.append(portal.getOptions().isBungee()); - - bw.append(builder.toString()); - bw.newLine(); - } - - bw.close(); - } catch (Exception e) { - Stargate.logger.log(Level.SEVERE, "Exception while writing stargates to " + loc + ": " + e); - } - } - - /** - * Loads all portals for the given world - * - * @param world

The world to load portals for

- * @return

True if portals could be loaded

- */ - public static boolean loadAllPortals(World world) { - String location = Stargate.getSaveLocation(); - - File database = new File(location, world.getName() + ".db"); - - if (database.exists()) { - return loadPortals(world, database); - } else { - Stargate.logger.info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); - } - return false; - } - - /** - * Loads all the given portals - * - * @param world

The world to load portals for

- * @param database

The database file containing the portals

- * @return

True if the portals were loaded successfully

- */ - private static boolean loadPortals(World world, File database) { - int lineIndex = 0; - try { - Scanner scanner = new Scanner(database); - while (scanner.hasNextLine()) { - lineIndex++; - String line = scanner.nextLine().trim(); - - //Ignore empty and comment lines - if (line.startsWith("#") || line.isEmpty()) { - continue; - } - - //Check if the min. required portal data is present - String[] portalData = line.split(":"); - if (portalData.length < 8) { - Stargate.logger.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); - continue; - } - - loadPortal(portalData, world, lineIndex); - } - scanner.close(); - - // Open any always-on gates. Do this here as it should be more efficient than in the loop. - TwoTuple portalCounts = openAlwaysOpenPortals(); - - Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", - Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), - portalCounts.getFirstValue())); - - //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since - for (Portal portal : PortalRegistry.getAllPortals()) { - portal.drawSign(); - } - return true; - } catch (Exception e) { - Stargate.logger.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + ": " + lineIndex); - e.printStackTrace(); - } - return false; - } - - /** - * Loads one portal from a data array - * - * @param portalData

The array describing the portal

- * @param world

The world to create the portal in

- * @param lineIndex

The line index to report in case the user needs to fix an error

- */ - private static void loadPortal(String[] portalData, World world, int lineIndex) { - //Load min. required portal data - String name = portalData[0]; - PortalLocation portalLocation = new PortalLocation(); - portalLocation.setSignLocation(new BlockLocation(world, portalData[1])); - BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; - portalLocation.setYaw(Float.parseFloat(portalData[5])); - portalLocation.setTopLeft(new BlockLocation(world, portalData[6])); - Gate gate = GateHandler.getGateByName(portalData[7]); - if (gate == null) { - //Mark the sign as invalid to reduce some player confusion - Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); - Stargate.setLine(sign, 3, Stargate.getString("signInvalidGate")); - sign.update(); - - Stargate.logger.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + - " does not exist [" + portalData[7] + "]"); - return; - } - - //Load extra portal data - String destination = (portalData.length > 8) ? portalData[8] : ""; - String network = (portalData.length > 9) ? portalData[9] : Stargate.getDefaultNetwork(); - if (network.isEmpty()) { - network = Stargate.getDefaultNetwork(); - } - String ownerString = (portalData.length > 10) ? portalData[10] : ""; - - // Attempt to get owner as UUID - UUID ownerUUID = null; - String ownerName; - if (ownerString.length() > 16) { - try { - ownerUUID = UUID.fromString(ownerString); - OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); - ownerName = offlineOwner.getName(); - } catch (IllegalArgumentException ex) { - // neither name nor UUID, so keep it as-is - ownerName = ownerString; - Stargate.debug("loadAllPortals", "Invalid stargate owner string: " + ownerString); - } - } else { - ownerName = ownerString; - } - - //Creates the new portal - Portal portal = new Portal(portalLocation, button, destination, name, - network, gate, ownerUUID, ownerName, getPortalOptions(portalData)); - - registerPortal(portal); - portal.getPortalOpener().closePortal(true); - } - /** * Gets all portal options stored in the portal data * * @param portalData

The string list containing all information about a portal

* @return

A map between portal options and booleans

*/ - private static Map getPortalOptions(String[] portalData) { + public static Map getPortalOptions(String[] portalData) { Map portalOptions = new HashMap<>(); for (PortalOption option : PortalOption.values()) { int saveIndex = option.getSaveIndex(); @@ -596,7 +401,7 @@ public class PortalHandler { * * @return

A TwoTuple where the first value is the number of always open portals and the second value is the total number of portals

*/ - private static TwoTuple openAlwaysOpenPortals() { + public static TwoTuple openAlwaysOpenPortals() { int portalCount = 0; int openCount = 0; for (Iterator iterator = PortalRegistry.getAllPortals().iterator(); iterator.hasNext(); ) { diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 165e680..a12b69e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.World; import org.bukkit.block.Sign; import org.bukkit.block.data.type.WallSign; @@ -228,7 +229,7 @@ public class PortalRegistry { sign.update(); } - PortalHandler.saveAllPortals(portal.getWorld()); + PortalFileHelper.saveAllPortals(portal.getWorld()); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java new file mode 100644 index 0000000..f38fe41 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -0,0 +1,315 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.TwoTuple; +import net.knarcraft.stargate.portal.Gate; +import net.knarcraft.stargate.portal.GateHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalLocation; +import net.knarcraft.stargate.portal.PortalOptions; +import net.knarcraft.stargate.portal.PortalRegistry; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.bukkit.block.Sign; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; +import java.util.UUID; +import java.util.logging.Level; + +/** + * Helper class for saving and loading portal save files + */ +public final class PortalFileHelper { + + private PortalFileHelper() { + + } + + /** + * Saves all portals for the given world + * + * @param world

The world to save portals for

+ */ + public static void saveAllPortals(World world) { + Stargate.managedWorlds.add(world.getName()); + String saveFileLocation = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; + + try { + BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(saveFileLocation, false)); + + for (Portal portal : PortalRegistry.getAllPortals()) { + //Skip portals in other worlds + String worldName = portal.getWorld().getName(); + if (!worldName.equalsIgnoreCase(world.getName())) { + continue; + } + //Save the portal + savePortal(bufferedWriter, portal); + } + + bufferedWriter.close(); + } catch (Exception e) { + Stargate.logger.log(Level.SEVERE, "Exception while writing stargates to " + saveFileLocation + ": " + e); + } + } + + /** + * Saves one portal + * + * @param bufferedWriter

The buffered writer to write to

+ * @param portal

The portal to save

+ * @throws IOException

If unable to write to the buffered writer

+ */ + private static void savePortal(BufferedWriter bufferedWriter, Portal portal) throws IOException { + StringBuilder builder = new StringBuilder(); + BlockLocation button = portal.getStructure().getButton(); + + //WARNING: Because of the primitive save format, any change in order will break everything! + builder.append(portal.getName()).append(':'); + builder.append(portal.getSignLocation().toString()).append(':'); + builder.append((button != null) ? button.toString() : "").append(':'); + + //Add removes config values to keep indices consistent + builder.append(0).append(':'); + builder.append(0).append(':'); + + builder.append(portal.getYaw()).append(':'); + builder.append(portal.getTopLeft().toString()).append(':'); + builder.append(portal.getGate().getFilename()).append(':'); + + //Only save the destination name if the gate is fixed as it doesn't matter otherwise + builder.append(portal.getOptions().isFixed() ? portal.getDestinationName() : "").append(':'); + + builder.append(portal.getNetwork()).append(':'); + + //Name is saved as a fallback if the UUID is unavailable + UUID owner = portal.getOwnerUUID(); + if (owner != null) { + builder.append(portal.getOwnerUUID().toString()); + } else { + builder.append(portal.getOwnerName()); + } + + //Save all the portal options + savePortalOptions(portal, builder); + + bufferedWriter.append(builder.toString()); + bufferedWriter.newLine(); + } + + /** + * Saves all portal options for the given portal + * + * @param portal

The portal to save

+ * @param builder

The string builder to append to

+ */ + private static void savePortalOptions(Portal portal, StringBuilder builder) { + PortalOptions options = portal.getOptions(); + builder.append(':'); + builder.append(options.isHidden()).append(':'); + builder.append(options.isAlwaysOn()).append(':'); + builder.append(options.isPrivate()).append(':'); + builder.append(portal.getWorld().getName()).append(':'); + builder.append(options.isFree()).append(':'); + builder.append(options.isBackwards()).append(':'); + builder.append(options.isShown()).append(':'); + builder.append(options.isNoNetwork()).append(':'); + builder.append(options.isRandom()).append(':'); + builder.append(options.isBungee()); + } + + /** + * Loads all portals for the given world + * + * @param world

The world to load portals for

+ * @return

True if portals could be loaded

+ */ + public static boolean loadAllPortals(World world) { + String location = Stargate.getSaveLocation(); + + File database = new File(location, world.getName() + ".db"); + + if (database.exists()) { + return loadPortals(world, database); + } else { + Stargate.logger.info(Stargate.getString("prefix") + "{" + world.getName() + + "} No stargates for world "); + } + return false; + } + + /** + * Loads all the given portals + * + * @param world

The world to load portals for

+ * @param database

The database file containing the portals

+ * @return

True if the portals were loaded successfully

+ */ + private static boolean loadPortals(World world, File database) { + int lineIndex = 0; + try { + Scanner scanner = new Scanner(database); + while (scanner.hasNextLine()) { + //Read the line and do whatever needs to be done + readPortalLine(scanner, ++lineIndex, world); + } + scanner.close(); + + //Do necessary tasks after all portals have loaded + doPostLoadTasks(world); + return true; + } catch (Exception e) { + Stargate.logger.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + + ": " + lineIndex); + e.printStackTrace(); + } + return false; + } + + /** + * Reads one file line containing information about one portal + * + * @param scanner

The scanner to read

+ * @param lineIndex

The index of the read line

+ * @param world

The world for which portals are currently being read

+ */ + private static void readPortalLine(Scanner scanner, int lineIndex, World world) { + String line = scanner.nextLine().trim(); + + //Ignore empty and comment lines + if (line.startsWith("#") || line.isEmpty()) { + return; + } + + //Check if the min. required portal data is present + String[] portalData = line.split(":"); + if (portalData.length < 8) { + Stargate.logger.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); + return; + } + + //Load the portal defined in the current line + loadPortal(portalData, world, lineIndex); + } + + /** + * Performs tasks which must be run after portals have loaded + * + *

This will open always on portals, print info about loaded stargates and re-draw portal signs for loaded + * portals.

+ * + * @param world

The world portals have been loaded for

+ */ + private static void doPostLoadTasks(World world) { + //Open any always-on portals. Do this here as it should be more efficient than in the loop. + TwoTuple portalCounts = PortalHandler.openAlwaysOpenPortals(); + + //Print info about loaded stargates so that admins can see if all stargates loaded + Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", + Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), + portalCounts.getFirstValue())); + + //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since + for (Portal portal : PortalRegistry.getAllPortals()) { + String worldName = portal.getWorld().getName(); + if (!worldName.equalsIgnoreCase(world.getName())) { + continue; + } + portal.drawSign(); + } + } + + /** + * Loads one portal from a data array + * + * @param portalData

The array describing the portal

+ * @param world

The world to create the portal in

+ * @param lineIndex

The line index to report in case the user needs to fix an error

+ */ + private static void loadPortal(String[] portalData, World world, int lineIndex) { + //Load min. required portal data + String name = portalData[0]; + BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; + + //Load the portal's location + PortalLocation portalLocation = new PortalLocation(); + portalLocation.setSignLocation(new BlockLocation(world, portalData[1])); + portalLocation.setYaw(Float.parseFloat(portalData[5])); + portalLocation.setTopLeft(new BlockLocation(world, portalData[6])); + + //Check if the portal's gate type exists and is loaded + Gate gate = GateHandler.getGateByName(portalData[7]); + if (gate == null) { + //Mark the sign as invalid to reduce some player confusion + markPortalWithInvalidGate(portalLocation, portalData[7], lineIndex); + return; + } + + //Load extra portal data + String destination = (portalData.length > 8) ? portalData[8] : ""; + String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : Stargate.getDefaultNetwork(); + String ownerString = (portalData.length > 10) ? portalData[10] : ""; + + //Try to get owner as UUID + TwoTuple nameAndUUID = getPortalOwnerUUIDAndName(ownerString); + + //Create the new portal + Portal portal = new Portal(portalLocation, button, destination, name, network, gate, + nameAndUUID.getFirstValue(), nameAndUUID.getSecondValue(), PortalHandler.getPortalOptions(portalData)); + + //Register the portal, and close it in case it wasn't properly closed when the server stopped + PortalHandler.registerPortal(portal); + portal.getPortalOpener().closePortal(true); + } + + /** + * Gets the portal UUID and name from the saved owner string + * + * @param ownerString

The saved owner string. Should be a UUID, or a player name if legacy

+ * @return

A two-tuple containing the UUID and owner name. The UUID might be null if the ownerString was not a UUID

+ */ + private static TwoTuple getPortalOwnerUUIDAndName(String ownerString) { + UUID ownerUUID = null; + String ownerName; + if (ownerString.length() > 16) { + //If more than 16 characters, the string cannot be a username, so it's probably a UUID + try { + ownerUUID = UUID.fromString(ownerString); + OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); + ownerName = offlineOwner.getName(); + } catch (IllegalArgumentException ex) { + //Invalid as UUID and username, so just keep it as owner name and hope the server owner fixes it + ownerName = ownerString; + Stargate.debug("loadAllPortals", "Invalid stargate owner string: " + ownerString); + } + } else { + //Old username from the pre-UUID times. Just keep it as the owner name + ownerName = ownerString; + } + return new TwoTuple<>(ownerUUID, ownerName); + } + + /** + * Marks a portal with an invalid gate by changing its sign and writing to the console + * + * @param portalLocation

The location of the portal with an invalid gate

+ * @param gateName

The name of the invalid gate type

+ * @param lineIndex

The index of the line the invalid portal was found at

+ */ + private static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) { + Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); + Stargate.setLine(sign, 3, Stargate.getString("signInvalidGate")); + sign.update(); + + Stargate.logger.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + + " does not exist [" + gateName + "]"); + } + +} From 9a0f16e558093ad7f1fd5e7a5cea8953e68f3ac0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 22 Oct 2021 19:51:46 +0200 Subject: [PATCH 179/378] Moves the portal owner name and owner UUID to the PortalOwner class which makes the TwoTuple unnecessary --- .../stargate/container/TwoTuple.java | 43 -------- .../stargate/listener/BlockEventListener.java | 3 +- .../listener/EntityEventListener.java | 3 +- .../net/knarcraft/stargate/portal/Portal.java | 38 ++----- .../stargate/portal/PortalCreator.java | 5 +- .../stargate/portal/PortalHandler.java | 74 ++++++------- .../stargate/portal/PortalOwner.java | 102 ++++++++++++++++++ .../stargate/utility/EconomyHelper.java | 24 +++-- .../stargate/utility/PortalFileHelper.java | 54 ++-------- 9 files changed, 179 insertions(+), 167 deletions(-) delete mode 100644 src/main/java/net/knarcraft/stargate/container/TwoTuple.java create mode 100644 src/main/java/net/knarcraft/stargate/portal/PortalOwner.java diff --git a/src/main/java/net/knarcraft/stargate/container/TwoTuple.java b/src/main/java/net/knarcraft/stargate/container/TwoTuple.java deleted file mode 100644 index 89c4d23..0000000 --- a/src/main/java/net/knarcraft/stargate/container/TwoTuple.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.knarcraft.stargate.container; - -/** - * This class allows storing two values of any type - * - * @param

The first type

- * @param

The second type

- */ -public class TwoTuple { - - private final K firstValue; - private final L secondValue; - - /** - * Instantiate a new TwoTuple - * - * @param firstValue

The first value

- * @param secondValue

The second value

- */ - public TwoTuple(K firstValue, L secondValue) { - this.firstValue = firstValue; - this.secondValue = secondValue; - } - - /** - * Gets the first value - * - * @return

The first value

- */ - public K getFirstValue() { - return firstValue; - } - - /** - * Gets the second value - * - * @return

The second value

- */ - public L getSecondValue() { - return secondValue; - } - -} diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index a1ca05d..0ca0b91 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.event.StargateDestroyEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalCreator; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; @@ -139,7 +140,7 @@ public class BlockEventListener implements Listener { return; } - PortalHandler.unregisterPortal(portal, true); + PortalRegistry.unregisterPortal(portal, true); Stargate.sendSuccessMessage(player, Stargate.getString("destroyMsg")); } diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index f50c7e6..82728de 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.block.Block; import org.bukkit.entity.Entity; @@ -55,7 +56,7 @@ public class EntityEventListener implements Listener { continue; } if (Stargate.destroyedByExplosion()) { - PortalHandler.unregisterPortal(portal, true); + PortalRegistry.unregisterPortal(portal, true); } else { event.setCancelled(true); break; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 681fdc0..3299240 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -6,18 +6,15 @@ import org.bukkit.World; import org.bukkit.entity.Player; import java.util.Map; -import java.util.UUID; /** * This class represents a portal in space which points to one or several portals */ public class Portal { - // Gate information private final String name; private final String network; - private final String ownerName; - private final UUID ownerUUID; + private final PortalOwner portalOwner; private final PortalOptions options; private final PortalOpener portalOpener; @@ -35,17 +32,15 @@ public class Portal { * @param name

The name of the portal defined on the sign's first line

* @param network

The network the portal belongs to, defined on the sign's third

* @param gate

The gate type to use for this portal

- * @param ownerUUID

The UUID of the gate's owner

- * @param ownerName

The name of the gate's owner

+ * @param portalOwner

The portal's owner

* @param options

A map containing all possible portal options, with true for the ones enabled

*/ public Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, String network, - Gate gate, UUID ownerUUID, String ownerName, Map options) { + Gate gate, PortalOwner portalOwner, Map options) { this.location = portalLocation; this.network = network; this.name = name; - this.ownerUUID = ownerUUID; - this.ownerName = ownerName; + this.portalOwner = portalOwner; this.options = new PortalOptions(options, destination.length() > 0); this.signDrawer = new PortalSignDrawer(this); this.portalOpener = new PortalOpener(this, destination); @@ -180,25 +175,14 @@ public class Portal { } /** - * Gets the name of this portal's owner + * Gets this portal's owner * *

The owner is the player which created the portal.

* - * @return

The name of this portal's owner

+ * @return

This portal's owner

*/ - public String getOwnerName() { - return ownerName; - } - - /** - * Gets the UUID of this portal's owner - * - *

The owner is the player which created the portal.

- * - * @return

The UUID of this portal's owner

- */ - public UUID getOwnerUUID() { - return ownerUUID; + public PortalOwner getOwner() { + return portalOwner; } /** @@ -208,10 +192,10 @@ public class Portal { * @return

True if the player is the owner of this portal

*/ public boolean isOwner(Player player) { - if (this.ownerUUID != null) { - return player.getUniqueId().compareTo(this.ownerUUID) == 0; + if (this.portalOwner.getUUID() != null) { + return player.getUniqueId().compareTo(this.portalOwner.getUUID()) == 0; } else { - return player.getName().equalsIgnoreCase(this.ownerName); + return player.getName().equalsIgnoreCase(this.portalOwner.getName()); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index b044a37..28efd04 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -152,8 +152,9 @@ public class PortalCreator { return null; } - this.portal = new Portal(portalLocation, null, destinationName, portalName, - network, gate, player.getUniqueId(), player.getName(), portalOptions); + PortalOwner owner = new PortalOwner(player); + this.portal = new Portal(portalLocation, null, destinationName, portalName, network, gate, owner, + portalOptions); return validatePortal(denyMessage, event.getLines(), deny); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 80cb5f4..f090b6f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -3,7 +3,6 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.block.Block; @@ -11,7 +10,6 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -101,16 +99,6 @@ public class PortalHandler { return destinations; } - /** - * Un-registers the given portal - * - * @param portal

The portal to un-register

- * @param removeAll

Whether to remove the portal from the list of all portals

- */ - public static void unregisterPortal(Portal portal, boolean removeAll) { - PortalRegistry.unregisterPortal(portal, removeAll); - } - /** * Registers a portal * @@ -397,51 +385,59 @@ public class PortalHandler { } /** - * Opens all always open portals + * Opens all always-on portals * - * @return

A TwoTuple where the first value is the number of always open portals and the second value is the total number of portals

+ * @return

The number of always open portals enabled

*/ - public static TwoTuple openAlwaysOpenPortals() { - int portalCount = 0; - int openCount = 0; - for (Iterator iterator = PortalRegistry.getAllPortals().iterator(); iterator.hasNext(); ) { - Portal portal = iterator.next(); - if (portal == null) { - continue; - } - - // Verify portal integrity/register portal - PortalStructure structure = portal.getStructure(); - if (!structure.wasVerified() && (!structure.isVerified() || !structure.checkIntegrity())) { - destroyInvalidPortal(portal); - iterator.remove(); - continue; - } - portalCount++; + public static int openAlwaysOpenPortals() { + int alwaysOpenCount = 0; + for (Portal portal : PortalRegistry.getAllPortals()) { //Open the gate if it's set as always open or if it's a bungee gate if (portal.getOptions().isFixed() && (Stargate.enableBungee && portal.getOptions().isBungee() || portal.getPortalActivator().getDestination() != null && portal.getOptions().isAlwaysOn())) { portal.getPortalOpener().openPortal(true); - openCount++; + alwaysOpenCount++; } } - return new TwoTuple<>(openCount, portalCount); + return alwaysOpenCount; } /** - * Destroys a portal which has failed its integrity test + * Tries to verify all portals and un-registers non-verifiable portals + */ + public static void verifyAllPortals() { + List invalidPortals = new ArrayList<>(); + for (Portal portal : PortalRegistry.getAllPortals()) { + //Try and verify the portal. Invalidate it if it cannot be validated + PortalStructure structure = portal.getStructure(); + if (!structure.wasVerified() && (!structure.isVerified() || !structure.checkIntegrity())) { + invalidPortals.add(portal); + } + } + + //Un-register any invalid portals found + for (Portal portal : invalidPortals) { + unregisterInvalidPortal(portal); + } + } + + /** + * Un-registers a portal which has failed its integrity tests * * @param portal

The portal of the star portal

*/ - private static void destroyInvalidPortal(Portal portal) { - // DEBUG + private static void unregisterInvalidPortal(Portal portal) { + //Show debug information for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { - if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { - Stargate.debug("loadAllPortals", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); + Block block = portal.getBlockAt(control).getBlock(); + //Log control blocks not matching the gate layout + if (!block.getType().equals(portal.getGate().getControlBlock())) { + Stargate.debug("PortalHandler::destroyInvalidPortal", "Control Block Type == " + + block.getType().name()); } } - PortalHandler.unregisterPortal(portal, false); + PortalRegistry.unregisterPortal(portal, false); Stargate.logger.info(Stargate.getString("prefix") + "Destroying stargate at " + portal); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java b/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java new file mode 100644 index 0000000..019f57d --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java @@ -0,0 +1,102 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.UUID; + +/** + * The portal owner represents the owner of a portal + */ +public class PortalOwner { + + private UUID ownerUUID; + private String ownerName; + + /** + * Instantiates a new portal owner + * + * @param ownerIdentifier

A UUID, or a username for legacy support

+ */ + public PortalOwner(String ownerIdentifier) { + parseIdentifier(ownerIdentifier); + } + + /** + * Instantiates a new portal owner + * + * @param player

The player which is the owner of the portal

+ */ + public PortalOwner(Player player) { + this.ownerUUID = player.getUniqueId(); + this.ownerName = player.getName(); + } + + /** + * Gets the UUID of this owner + * + * @return

The UUID of this owner, or null if a UUID is not available

+ */ + public UUID getUUID() { + return ownerUUID; + } + + /** + * Gets the name of this owner + * + * @return

The name of this owner

+ */ + public String getName() { + return ownerName; + } + + /** + * Gets the one identifier used for saving the owner + * + *

If the UUID is available, a string representation of the UUID will be returned. If not, the owner's name will + * be returned.

+ * + * @return

The owner's identifier

+ */ + public String getIdentifier() { + if (ownerUUID != null) { + return ownerUUID.toString(); + } else { + return ownerName; + } + } + + /** + * Parses the identifier of a portal's owner + * + *

The identifier should be a valid UUID, but can be a username of max 16 characters for legacy support. Strings + * longer than 16 characters not parse-able as a UUID will silently fail by setting the owner name to the + * identifier.

+ * + * @param ownerIdentifier

The identifier for a portal's owner

+ */ + private void parseIdentifier(String ownerIdentifier) { + UUID ownerUUID = null; + String ownerName; + if (ownerIdentifier.length() > 16) { + //If more than 16 characters, the string cannot be a username, so it's probably a UUID + try { + ownerUUID = UUID.fromString(ownerIdentifier); + OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); + ownerName = offlineOwner.getName(); + } catch (IllegalArgumentException ex) { + //Invalid as UUID and username, so just keep it as owner name and hope the server owner fixes it + ownerName = ownerIdentifier; + Stargate.debug("loadAllPortals", "Invalid stargate owner string: " + ownerIdentifier); + } + } else { + //Old username from the pre-UUID times. Just keep it as the owner name + ownerName = ownerIdentifier; + } + this.ownerName = ownerName; + this.ownerUUID = ownerUUID; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 1481970..189320c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -2,8 +2,11 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalOwner; import org.bukkit.entity.Player; +import java.util.UUID; + /** * The economy helper class has helper functions for player payment */ @@ -24,15 +27,15 @@ public final class EconomyHelper { public static boolean cannotPayTeleportFee(Portal entrancePortal, Player player, int cost) { boolean success; - //Try to charge the player + //Try to charge the player. Paying the portal owner is only possible if a UUID is available if (entrancePortal.getGate().getToOwner()) { - success = entrancePortal.getOwnerUUID() != null && EconomyHandler.chargePlayerIfNecessary(player, - entrancePortal.getOwnerUUID(), cost); + UUID ownerUUID = entrancePortal.getOwner().getUUID(); + success = ownerUUID != null && EconomyHandler.chargePlayerIfNecessary(player, ownerUUID, cost); } else { success = EconomyHandler.chargePlayerIfNecessary(player, cost); } - // Insufficient Funds + //Send the insufficient funds message if (!success) { sendInsufficientFundsMessage(entrancePortal.getName(), player, cost); entrancePortal.getPortalOpener().closePortal(false); @@ -43,16 +46,17 @@ public final class EconomyHelper { sendDeductMessage(entrancePortal.getName(), player, cost); if (entrancePortal.getGate().getToOwner()) { - Player gateOwner; - if (entrancePortal.getOwnerUUID() != null) { - gateOwner = Stargate.server.getPlayer(entrancePortal.getOwnerUUID()); + PortalOwner owner = entrancePortal.getOwner(); + Player portalOwner; + if (owner.getUUID() != null) { + portalOwner = Stargate.server.getPlayer(owner.getUUID()); } else { - gateOwner = Stargate.server.getPlayer(entrancePortal.getOwnerName()); + portalOwner = Stargate.server.getPlayer(owner.getName()); } //Notify the gate owner of received payment - if (gateOwner != null) { - sendObtainMessage(entrancePortal.getName(), gateOwner, cost); + if (portalOwner != null) { + sendObtainMessage(entrancePortal.getName(), portalOwner, cost); } } return false; diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index f38fe41..c15a6ce 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -2,16 +2,14 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.container.TwoTuple; import net.knarcraft.stargate.portal.Gate; import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalLocation; import net.knarcraft.stargate.portal.PortalOptions; +import net.knarcraft.stargate.portal.PortalOwner; import net.knarcraft.stargate.portal.PortalRegistry; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.block.Sign; @@ -20,7 +18,6 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; -import java.util.UUID; import java.util.logging.Level; /** @@ -90,12 +87,7 @@ public final class PortalFileHelper { builder.append(portal.getNetwork()).append(':'); //Name is saved as a fallback if the UUID is unavailable - UUID owner = portal.getOwnerUUID(); - if (owner != null) { - builder.append(portal.getOwnerUUID().toString()); - } else { - builder.append(portal.getOwnerName()); - } + builder.append(portal.getOwner().getIdentifier()); //Save all the portal options savePortalOptions(portal, builder); @@ -209,12 +201,13 @@ public final class PortalFileHelper { */ private static void doPostLoadTasks(World world) { //Open any always-on portals. Do this here as it should be more efficient than in the loop. - TwoTuple portalCounts = PortalHandler.openAlwaysOpenPortals(); + PortalHandler.verifyAllPortals(); + int portalCount = PortalRegistry.getAllPortals().size(); + int openCount = PortalHandler.openAlwaysOpenPortals(); //Print info about loaded stargates so that admins can see if all stargates loaded Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", - Stargate.getString("prefix"), world.getName(), portalCounts.getSecondValue(), - portalCounts.getFirstValue())); + Stargate.getString("prefix"), world.getName(), portalCount, openCount)); //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since for (Portal portal : PortalRegistry.getAllPortals()) { @@ -257,45 +250,18 @@ public final class PortalFileHelper { String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : Stargate.getDefaultNetwork(); String ownerString = (portalData.length > 10) ? portalData[10] : ""; - //Try to get owner as UUID - TwoTuple nameAndUUID = getPortalOwnerUUIDAndName(ownerString); + //Get the owner from the owner string + PortalOwner owner = new PortalOwner(ownerString); //Create the new portal - Portal portal = new Portal(portalLocation, button, destination, name, network, gate, - nameAndUUID.getFirstValue(), nameAndUUID.getSecondValue(), PortalHandler.getPortalOptions(portalData)); + Portal portal = new Portal(portalLocation, button, destination, name, network, gate, owner, + PortalHandler.getPortalOptions(portalData)); //Register the portal, and close it in case it wasn't properly closed when the server stopped PortalHandler.registerPortal(portal); portal.getPortalOpener().closePortal(true); } - /** - * Gets the portal UUID and name from the saved owner string - * - * @param ownerString

The saved owner string. Should be a UUID, or a player name if legacy

- * @return

A two-tuple containing the UUID and owner name. The UUID might be null if the ownerString was not a UUID

- */ - private static TwoTuple getPortalOwnerUUIDAndName(String ownerString) { - UUID ownerUUID = null; - String ownerName; - if (ownerString.length() > 16) { - //If more than 16 characters, the string cannot be a username, so it's probably a UUID - try { - ownerUUID = UUID.fromString(ownerString); - OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); - ownerName = offlineOwner.getName(); - } catch (IllegalArgumentException ex) { - //Invalid as UUID and username, so just keep it as owner name and hope the server owner fixes it - ownerName = ownerString; - Stargate.debug("loadAllPortals", "Invalid stargate owner string: " + ownerString); - } - } else { - //Old username from the pre-UUID times. Just keep it as the owner name - ownerName = ownerString; - } - return new TwoTuple<>(ownerUUID, ownerName); - } - /** * Marks a portal with an invalid gate by changing its sign and writing to the console * From 070e7250dff25f30fb4426f589edd9d5736822f3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 22 Oct 2021 21:56:35 +0200 Subject: [PATCH 180/378] Re-draws every portal sign each time a new world is loaded to prevent weird states --- .../java/net/knarcraft/stargate/utility/PortalFileHelper.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index c15a6ce..502110a 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -211,10 +211,6 @@ public final class PortalFileHelper { //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since for (Portal portal : PortalRegistry.getAllPortals()) { - String worldName = portal.getWorld().getName(); - if (!worldName.equalsIgnoreCase(world.getName())) { - continue; - } portal.drawSign(); } } From 2196d5b99e8d44e9a9ab5fb055f40b4e0a627d92 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 03:56:59 +0200 Subject: [PATCH 181/378] Moves some config values from StarGate and into the StarGateConfig class Renames EconomyHandler to EconomyConfig and puts it in the new config package Moves the LanguageLoader to the config package Fixes the explanation of chargeFreeDestination in the README --- README.md | 2 +- .../java/net/knarcraft/stargate/Stargate.java | 118 ++++-------- .../EconomyConfig.java} | 178 +++++++++++++----- .../stargate/{ => config}/LanguageLoader.java | 5 +- .../stargate/config/StargateGateConfig.java | 169 +++++++++++++++++ .../stargate/listener/BlockEventListener.java | 10 +- .../listener/PlayerEventListener.java | 25 ++- .../listener/PluginEventListener.java | 7 +- .../listener/VehicleEventListener.java | 9 +- .../net/knarcraft/stargate/portal/Gate.java | 7 +- .../stargate/portal/GateHandler.java | 3 +- .../stargate/portal/PortalActivator.java | 7 +- .../stargate/portal/PortalCreator.java | 8 +- .../stargate/portal/PortalHandler.java | 7 +- .../stargate/portal/PortalSignDrawer.java | 12 +- .../stargate/portal/PortalStructure.java | 9 +- .../stargate/utility/EconomyHelper.java | 6 +- .../stargate/utility/PermissionHelper.java | 4 +- 18 files changed, 412 insertions(+), 174 deletions(-) rename src/main/java/net/knarcraft/stargate/{utility/EconomyHandler.java => config/EconomyConfig.java} (59%) rename src/main/java/net/knarcraft/stargate/{ => config}/LanguageLoader.java (98%) create mode 100644 src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java diff --git a/README.md b/README.md index 2f69f1a..dacb2c0 100644 --- a/README.md +++ b/README.md @@ -277,7 +277,7 @@ economy: destroyCost - The cost to destroy a stargate (Can be negative for a "refund" useCost - The cost to use a stargate toOwner - Whether the money from gate-use goes to the owner or nobody - chargeFreeDestination - Enable to allow free travel from any gate to a free gate + chargeFreeDestination - Enable to make players pay for teleportation even if the destination is free freeGatesGreen - Enable to make gates that won't cost the player money show up as green debugging: debug - Whether to show massive debug output diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2bc73e3..d56c04e 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -2,6 +2,9 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; +import net.knarcraft.stargate.config.EconomyConfig; +import net.knarcraft.stargate.config.LanguageLoader; +import net.knarcraft.stargate.config.StargateGateConfig; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.listener.BlockEventListener; @@ -20,7 +23,6 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.FileHelper; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; @@ -68,17 +70,10 @@ public class Stargate extends JavaPlugin { public static Stargate stargate; public static LanguageLoader languageLoader; - public static int maxGatesEachNetwork = 0; - public static boolean rememberDestination = false; - public static boolean handleVehicles = true; - public static boolean sortNetworkDestinations = false; - public static boolean protectEntrance = false; - public static boolean enableBungee = true; - public static boolean verifyPortals = true; - private static boolean destroyExplosion = false; private String dataFolderPath; + private static StargateGateConfig stargateGateConfig; + private static EconomyConfig economyConfig; - public static ChatColor signColor; //Used for debug public static boolean debuggingEnabled = false; public static boolean permissionDebuggingEnabled = false; @@ -92,7 +87,6 @@ public class Stargate extends JavaPlugin { private static String portalFolder; private static String gateFolder; - private static String defaultGateNetwork = "central"; private static String languageName = "en"; private FileConfiguration newConfig; @@ -117,6 +111,24 @@ public class Stargate extends JavaPlugin { super(loader, descriptionFile, dataFolder, file); } + /** + * Gets the object containing gate configuration values + * + * @return

The object containing gate configuration values

+ */ + public static StargateGateConfig getGateConfig() { + return stargateGateConfig; + } + + /** + * Gets the object containing economy config values + * + * @return

The object containing economy config values

+ */ + public static EconomyConfig getEconomyConfig() { + return economyConfig; + } + /** * Gets the version of this plugin * @@ -132,7 +144,7 @@ public class Stargate extends JavaPlugin { * @return

True if portals should be destroyed

*/ public static boolean destroyedByExplosion() { - return destroyExplosion; + return stargateGateConfig.destroyedByExplosion(); } /** @@ -215,7 +227,7 @@ public class Stargate extends JavaPlugin { * @param text

The new text on the sign

*/ public static void setLine(Sign sign, int index, String text) { - sign.setLine(index, Stargate.signColor + text); + sign.setLine(index, stargateGateConfig.getSignColor() + text); } /** @@ -246,7 +258,7 @@ public class Stargate extends JavaPlugin { * @return

The default network

*/ public static String getDefaultNetwork() { - return defaultGateNetwork; + return stargateGateConfig.getDefaultPortalNetwork(); } /** @@ -324,7 +336,7 @@ public class Stargate extends JavaPlugin { this.loadConfig(); //Enable the required channels for Bungee support - if (enableBungee) { + if (stargateGateConfig.enableBungee()) { startStopBungeeListener(true); } @@ -411,10 +423,10 @@ public class Stargate extends JavaPlugin { } //Gates - loadGateConfig(); + stargateGateConfig = new StargateGateConfig(newConfig); //Economy - loadEconomyConfig(); + economyConfig = new EconomyConfig(newConfig); this.saveConfig(); } @@ -456,59 +468,6 @@ public class Stargate extends JavaPlugin { } } - /** - * Loads all config values related to gates - */ - private void loadGateConfig() { - String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); - defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; - maxGatesEachNetwork = newConfig.getInt("gates.maxGatesEachNetwork"); - - //Functionality - handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); - enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); - - //Integrity - protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); - verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); - destroyExplosion = newConfig.getBoolean("gates.integrity.destroyedByExplosion"); - - //Cosmetic - sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); - rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); - loadSignColor(newConfig.getString("gates.cosmetic.signColor")); - } - - /** - * Loads all config values related to economy - */ - private void loadEconomyConfig() { - EconomyHandler.economyEnabled = newConfig.getBoolean("economy.useEconomy"); - EconomyHandler.setDefaultCreateCost(newConfig.getInt("economy.createCost")); - EconomyHandler.setDefaultDestroyCost(newConfig.getInt("economy.destroyCost")); - EconomyHandler.setDefaultUseCost(newConfig.getInt("economy.useCost")); - EconomyHandler.toOwner = newConfig.getBoolean("economy.toOwner"); - EconomyHandler.chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination"); - EconomyHandler.freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen"); - } - - /** - * Loads the correct sign color given a sign color string - * - * @param signColor

A string representing a sign color

- */ - private void loadSignColor(String signColor) { - if (signColor != null) { - try { - Stargate.signColor = ChatColor.valueOf(signColor.toUpperCase()); - return; - } catch (IllegalArgumentException | NullPointerException ignored) { - } - } - logger.warning(getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); - Stargate.signColor = ChatColor.BLACK; - } - /** * Forces all open portals to close */ @@ -577,7 +536,7 @@ public class Stargate extends JavaPlugin { GateHandler.clearGates(); // Store the old Bungee enabled value - boolean oldEnableBungee = enableBungee; + boolean oldEnableBungee = stargateGateConfig.enableBungee(); // Reload data loadConfig(); loadGates(); @@ -589,8 +548,8 @@ public class Stargate extends JavaPlugin { reloadEconomy(); //Enable or disable the required channels for Bungee support - if (oldEnableBungee != enableBungee) { - startStopBungeeListener(enableBungee); + if (oldEnableBungee != stargateGateConfig.enableBungee()) { + startStopBungeeListener(stargateGateConfig.enableBungee()); } sendErrorMessage(sender, "stargate reloaded"); @@ -600,11 +559,11 @@ public class Stargate extends JavaPlugin { * Reloads economy by enabling or disabling it as necessary */ private void reloadEconomy() { - if (EconomyHandler.economyEnabled && EconomyHandler.economy == null) { + EconomyConfig economyConfig = Stargate.getEconomyConfig(); + if (economyConfig.isEconomyEnabled() && economyConfig.getEconomy() == null) { setupVaultEconomy(); - } else if (!EconomyHandler.economyEnabled) { - EconomyHandler.vault = null; - EconomyHandler.economy = null; + } else if (!economyConfig.isEconomyEnabled()) { + economyConfig.disableEconomy(); } } @@ -612,8 +571,9 @@ public class Stargate extends JavaPlugin { * Loads economy from Vault */ private void setupVaultEconomy() { - if (EconomyHandler.setupEconomy(pluginManager) && EconomyHandler.economy != null) { - String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + EconomyConfig economyConfig = Stargate.getEconomyConfig(); + if (economyConfig.setupEconomy(pluginManager) && economyConfig.getEconomy() != null) { + String vaultVersion = economyConfig.getVault().getDescription().getVersion(); logger.info(Stargate.getString("prefix") + Stargate.replaceVars( Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java similarity index 59% rename from src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java rename to src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 73f2bdc..57aa347 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHandler.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -1,41 +1,119 @@ -package net.knarcraft.stargate.utility; +package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Gate; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.utility.PermissionHelper; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicesManager; import java.util.UUID; /** - * This handler handles economy actions such as payment for using a gate + * The economy config keeps track of economy config values and performs economy actions such as payment for using a gate */ -public final class EconomyHandler { +public final class EconomyConfig { - public static boolean economyEnabled = false; - public static Economy economy = null; - public static Plugin vault = null; - private static int useCost = 0; - private static int createCost = 0; - private static int destroyCost = 0; - public static boolean toOwner = false; - public static boolean chargeFreeDestination = true; - public static boolean freeGatesGreen = false; + private boolean economyEnabled = false; + private Economy economy = null; + private Plugin vault = null; + private int useCost = 0; + private int createCost = 0; + private int destroyCost = 0; + private boolean toOwner = false; + private boolean chargeFreeDestination = true; + private boolean freeGatesGreen = false; + + /** + * Instantiates a new economy config + * + * @param newConfig

The file configuration to read values from

+ */ + public EconomyConfig(FileConfiguration newConfig) { + loadEconomyConfig(newConfig); + } /** * Gets the cost of using a gate without a specified cost * * @return

The gate use cost

*/ - public static int getDefaultUseCost() { + public int getDefaultUseCost() { return useCost; } + /** + * Gets whether economy is enabled + * + * @return

Whether economy is enabled

+ */ + public boolean isEconomyEnabled() { + return economyEnabled; + } + + /** + * Gets the economy object to use for transactions + * + * @return

An economy object, or null if economy is disabled or not initialized

+ */ + public Economy getEconomy() { + return economy; + } + + /** + * Gets an instance of the Vault plugin + * + * @return

An instance of the Vault plugin, or null if Vault is not loaded

+ */ + public Plugin getVault() { + return vault; + } + + /** + * Disables economy support by clearing relevant values + */ + public void disableEconomy() { + this.economy = null; + this.vault = null; + } + + /** + * Gets whether free portals should be marked with green coloring + * + * @return

Whether free portals should be green

+ */ + public boolean drawFreePortalsGreen() { + return freeGatesGreen; + } + + /** + * Whether a gate whose destination is a free gate is still charged + * + *

If teleporting from a free portal, it's free regardless of destination. If chargeFreeDestination is disabled, + * it's also free to teleport back to the free portal. If chargeFreeDestination is enabled, it's only free to + * teleport back if teleporting from another free portal.

+ * + * @return

Whether to charge for free destinations

+ */ + public boolean chargeFreeDestination() { + return chargeFreeDestination; + } + + /** + * Gets whether payments should be sent to the owner of the used portal + * + * @return

Whether to send payments to the portal owner

+ */ + public boolean sendPaymentToOwner() { + return toOwner; + } + /** * Sets the cost of using a gate without a specified cost * @@ -43,11 +121,11 @@ public final class EconomyHandler { * * @param useCost

The gate use cost

*/ - public static void setDefaultUseCost(int useCost) { + public void setDefaultUseCost(int useCost) { if (useCost < 0) { throw new IllegalArgumentException("Using a gate cannot cost a negative amount"); } - EconomyHandler.useCost = useCost; + this.useCost = useCost; } /** @@ -55,7 +133,7 @@ public final class EconomyHandler { * * @return

The gate creation cost

*/ - public static int getDefaultCreateCost() { + public int getDefaultCreateCost() { return createCost; } @@ -66,8 +144,8 @@ public final class EconomyHandler { * * @param createCost

The gate creation cost

*/ - public static void setDefaultCreateCost(int createCost) { - EconomyHandler.createCost = createCost; + public void setDefaultCreateCost(int createCost) { + this.createCost = createCost; } /** @@ -75,7 +153,7 @@ public final class EconomyHandler { * * @return

The gate destruction cost

*/ - public static int getDefaultDestroyCost() { + public int getDefaultDestroyCost() { return destroyCost; } @@ -84,8 +162,8 @@ public final class EconomyHandler { * * @param destroyCost

The gate destruction cost

*/ - public static void setDefaultDestroyCost(int destroyCost) { - EconomyHandler.destroyCost = destroyCost; + public void setDefaultDestroyCost(int destroyCost) { + this.destroyCost = destroyCost; } /** @@ -95,12 +173,12 @@ public final class EconomyHandler { * @param cost

The cost of the transaction

* @return

True if the player was charged successfully

*/ - public static boolean chargePlayerIfNecessary(Player player, int cost) { + public boolean chargePlayerIfNecessary(Player player, int cost) { if (skipPayment(cost)) { return true; } //Charge player - return EconomyHandler.chargePlayer(player, cost); + return chargePlayer(player, cost); } /** @@ -110,7 +188,7 @@ public final class EconomyHandler { * @param cost

The fee to pay

* @return

True if the player can afford to pay the fee

*/ - public static boolean canAffordFee(Player player, int cost) { + public boolean canAffordFee(Player player, int cost) { return economy.getBalance(player) > cost; } @@ -122,12 +200,12 @@ public final class EconomyHandler { * @param cost

The cost of the transaction

* @return

True if the player was charged successfully

*/ - public static boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { + public boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { if (skipPayment(cost)) { return true; } //Charge player - return EconomyHandler.chargePlayer(player, target, cost); + return chargePlayer(player, target, cost); } /** @@ -136,7 +214,7 @@ public final class EconomyHandler { * @param amount

The amount to display

* @return

A formatted text string describing the amount

*/ - public static String format(int amount) { + public String format(int amount) { if (economyEnabled) { return economy.format(amount); } else { @@ -150,17 +228,18 @@ public final class EconomyHandler { * @param pluginManager

The plugin manager to get plugins from

* @return

True if economy was enabled

*/ - public static boolean setupEconomy(PluginManager pluginManager) { + public boolean setupEconomy(PluginManager pluginManager) { if (!economyEnabled) { return false; } //Check if vault is loaded Plugin vault = pluginManager.getPlugin("Vault"); if (vault != null && vault.isEnabled()) { - RegisteredServiceProvider economyProvider = Stargate.server.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); + ServicesManager servicesManager = Stargate.server.getServicesManager(); + RegisteredServiceProvider economyProvider = servicesManager.getRegistration(Economy.class); if (economyProvider != null) { economy = economyProvider.getProvider(); - EconomyHandler.vault = vault; + this.vault = vault; return true; } else { Stargate.logger.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); @@ -177,7 +256,7 @@ public final class EconomyHandler { * * @return

True if the user has turned on economy and economy is available

*/ - public static boolean useEconomy() { + public boolean useEconomy() { return economyEnabled && economy != null; } @@ -187,8 +266,8 @@ public final class EconomyHandler { * @param cost

The cost of the transaction

* @return

True if the transaction should be skipped

*/ - private static boolean skipPayment(int cost) { - return cost == 0 || !EconomyHandler.useEconomy(); + private boolean skipPayment(int cost) { + return cost == 0 || !useEconomy(); } /** @@ -199,13 +278,13 @@ public final class EconomyHandler { * @param destination

The destination portal

* @return

The cost of using the portal

*/ - public static int getUseCost(Player player, Portal source, Portal destination) { + public int getUseCost(Player player, Portal source, Portal destination) { //No payment required - if (!EconomyHandler.useEconomy() || source.getOptions().isFree()) { + if (!useEconomy() || source.getOptions().isFree()) { return 0; } //Not charging for free destinations - if (destination != null && !EconomyHandler.chargeFreeDestination && destination.getOptions().isFree()) { + if (destination != null && !chargeFreeDestination && destination.getOptions().isFree()) { return 0; } //Cost is 0 if the player owns this gate and funds go to the owner @@ -228,7 +307,7 @@ public final class EconomyHandler { * @param gate

The gate type used

* @return

The cost of creating the gate

*/ - public static int getCreateCost(Player player, Gate gate) { + public int getCreateCost(Player player, Gate gate) { if (isFree(player, "create")) { return 0; } else { @@ -243,7 +322,7 @@ public final class EconomyHandler { * @param gate

The gate type used

* @return

The cost of destroying the gate

*/ - public static int getDestroyCost(Player player, Gate gate) { + public int getDestroyCost(Player player, Gate gate) { if (isFree(player, "destroy")) { return 0; } else { @@ -251,6 +330,21 @@ public final class EconomyHandler { } } + /** + * Loads all config values related to economy + * + * @param newConfig

The configuration containing the values to read

+ */ + private void loadEconomyConfig(FileConfiguration newConfig) { + economyEnabled = newConfig.getBoolean("economy.useEconomy"); + setDefaultCreateCost(newConfig.getInt("economy.createCost")); + setDefaultDestroyCost(newConfig.getInt("economy.destroyCost")); + setDefaultUseCost(newConfig.getInt("economy.useCost")); + toOwner = newConfig.getBoolean("economy.toOwner"); + chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination"); + freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen"); + } + /** * Determines if a player can do a gate action for free * @@ -258,8 +352,8 @@ public final class EconomyHandler { * @param permissionNode

The free.permissionNode necessary to allow free gate {action}

* @return

*/ - private static boolean isFree(Player player, String permissionNode) { - return !EconomyHandler.useEconomy() || PermissionHelper.hasPermission(player, "stargate.free") || + private boolean isFree(Player player, String permissionNode) { + return !useEconomy() || PermissionHelper.hasPermission(player, "stargate.free") || PermissionHelper.hasPermission(player, "stargate.free." + permissionNode); } @@ -270,7 +364,7 @@ public final class EconomyHandler { * @param amount

The amount to charge

* @return

True if the payment succeeded, or if no payment was necessary

*/ - private static boolean chargePlayer(Player player, double amount) { + private boolean chargePlayer(Player player, double amount) { if (economyEnabled && economy != null) { if (!economy.has(player, amount)) { return false; @@ -288,7 +382,7 @@ public final class EconomyHandler { * @param amount

The amount to charge

* @return

True if the payment succeeded, or if no payment was necessary

*/ - private static boolean chargePlayer(Player player, UUID target, double amount) { + private boolean chargePlayer(Player player, UUID target, double amount) { if (economyEnabled && player.getUniqueId().compareTo(target) != 0 && economy != null) { if (!economy.has(player, amount)) { return false; diff --git a/src/main/java/net/knarcraft/stargate/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/LanguageLoader.java rename to src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index b3b24d9..e238e0a 100644 --- a/src/main/java/net/knarcraft/stargate/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -1,5 +1,6 @@ -package net.knarcraft.stargate; +package net.knarcraft.stargate.config; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.FileHelper; import java.io.BufferedReader; @@ -14,7 +15,7 @@ import java.util.Set; /** * This class is responsible for loading all strings which are translated into several languages */ -public class LanguageLoader { +public final class LanguageLoader { private final String languageFolder; private final Map loadedBackupStrings; diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java new file mode 100644 index 0000000..2b04016 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -0,0 +1,169 @@ +package net.knarcraft.stargate.config; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; + +import static net.knarcraft.stargate.Stargate.getString; + +/** + * The Stargate gate config keeps track of all global config values related to gates + */ +public final class StargateGateConfig { + + private int maxGatesEachNetwork = 0; + private boolean rememberDestination = false; + private boolean handleVehicles = true; + private boolean sortNetworkDestinations = false; + private boolean protectEntrance = false; + private boolean enableBungee = true; + private boolean verifyPortals = true; + private boolean destroyExplosion = false; + private ChatColor signColor; + private String defaultGateNetwork = "central"; + + /** + * Instantiates a new stargate config + * + * @param newConfig

The file configuration to read values from

+ */ + public StargateGateConfig(FileConfiguration newConfig) { + loadGateConfig(newConfig); + } + + /** + * Gets the maximum number of gates allowed on each network + * + * @return

Maximum number of gates for each network

+ */ + public int maxGatesEachNetwork() { + return maxGatesEachNetwork; + } + + /** + * Gets whether a portal's lastly used destination should be remembered + * + * @return

Whether a portal's lastly used destination should be remembered

+ */ + public boolean rememberDestination() { + return rememberDestination; + } + + /** + * Gets whether vehicle teleportation should be handled in addition to player teleportation + * + * @return

Whether vehicle teleportation should be handled

+ */ + public boolean handleVehicles() { + return handleVehicles; + } + + /** + * Gets whether the list of destinations within a network should be sorted + * + * @return

Whether network destinations should be sorted

+ */ + public boolean sortNetworkDestinations() { + return sortNetworkDestinations; + } + + /** + * Gets whether portal entrances should be protected from block breaking + * + * @return

Whether portal entrances should be protected

+ */ + public boolean protectEntrance() { + return protectEntrance; + } + + /** + * Gets whether BungeeCord support is enabled + * + * @return

Whether bungee support is enabled

+ */ + public boolean enableBungee() { + return enableBungee; + } + + /** + * Gets whether all portals' integrity has to be verified on startup and reload + * + * @return

Whether portals need to be verified

+ */ + public boolean verifyPortals() { + return verifyPortals; + } + + /** + * Gets whether portals should be destroyed by nearby explosions + * + * @return

Whether portals should be destroyed by explosions

+ */ + public boolean destroyedByExplosion() { + return destroyExplosion; + } + + /** + * Gets the color to use for drawing signs + * + *

Highlighting may use other colors. This is just the base color for portal names and such.

+ * + * @return

The color to use for drawing signs

+ */ + public ChatColor getSignColor() { + return signColor; + } + + /** + * Gets the default portal network to use if no other network is given + * + * @return

The default portal network

+ */ + public String getDefaultPortalNetwork() { + return defaultGateNetwork; + } + + /** + * Loads all config values related to gates + * + * @param newConfig

The configuration containing the values to read

+ */ + private void loadGateConfig(FileConfiguration newConfig) { + String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); + defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; + maxGatesEachNetwork = newConfig.getInt("gates.maxGatesEachNetwork"); + + //Functionality + handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); + enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); + + //Integrity + protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); + verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); + destroyExplosion = newConfig.getBoolean("gates.integrity.destroyedByExplosion"); + + //Cosmetic + sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); + rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); + loadSignColor(newConfig.getString("gates.cosmetic.signColor")); + } + + /** + * Loads the correct sign color given a sign color string + * + * @param signColor

A string representing a sign color

+ */ + private void loadSignColor(String signColor) { + if (signColor != null) { + try { + this.signColor = ChatColor.valueOf(signColor.toUpperCase()); + return; + } catch (IllegalArgumentException | NullPointerException ignored) { + } + } + Stargate.logger.warning(getString("prefix") + + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); + this.signColor = ChatColor.BLACK; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 0ca0b91..690a340 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -6,7 +6,6 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalCreator; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; @@ -45,7 +44,8 @@ public class BlockEventListener implements Listener { */ @EventHandler public void onBlockFormedByEntity(EntityBlockFormEvent event) { - if (event.isCancelled() || (!Stargate.protectEntrance && !Stargate.verifyPortals)) { + if (event.isCancelled() || (!Stargate.getGateConfig().protectEntrance() && + !Stargate.getGateConfig().verifyPortals())) { return; } //We are only interested in snowman events @@ -101,7 +101,7 @@ public class BlockEventListener implements Listener { //Decide if a portal is broken Portal portal = PortalHandler.getByBlock(block); - if (portal == null && Stargate.protectEntrance) { + if (portal == null && Stargate.getGateConfig().protectEntrance()) { portal = PortalHandler.getByEntrance(block); } if (portal == null) { @@ -118,7 +118,7 @@ public class BlockEventListener implements Listener { Stargate.logger.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); } - int cost = EconomyHandler.getDestroyCost(player, portal.getGate()); + int cost = Stargate.getEconomyConfig().getDestroyCost(player, portal.getGate()); //Create and call a StarGateDestroyEvent StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMessage, cost); @@ -159,7 +159,7 @@ public class BlockEventListener implements Listener { if (cost != 0) { String portalName = portal.getName(); //Cannot pay - if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { + if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) { Stargate.debug("onBlockBreak", "Insufficient Funds"); EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); event.setCancelled(true); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index fef005d..52c3745 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -42,7 +42,7 @@ public class PlayerEventListener implements Listener { */ @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - if (!Stargate.enableBungee) { + if (!Stargate.getGateConfig().enableBungee()) { return; } @@ -84,19 +84,34 @@ public class PlayerEventListener implements Listener { Portal entrancePortal = PortalHandler.getByEntrance(toLocation); Portal destination = entrancePortal.getPortalActivator().getDestination(player); - //Teleport the vehicle to the player Entity playerVehicle = player.getVehicle(); - if (playerVehicle != null && !Stargate.handleVehicles) { - return; + //If the player is in a vehicle, but vehicle handling is disabled, just ignore the player + if (playerVehicle == null || Stargate.getGateConfig().handleVehicles()) { + teleportPlayer(playerVehicle, player, entrancePortal, destination, event); } + } + + /** + * Teleports a player, also teleports the player's vehicle if it's a living entity + * + * @param playerVehicle

The vehicle the player is currently sitting in

+ * @param player

The player which moved

+ * @param entrancePortal

The entrance the player entered

+ * @param destination

The destination of the entrance portal

+ * @param event

The move event causing the teleportation to trigger

+ */ + private void teleportPlayer(Entity playerVehicle, Player player, Portal entrancePortal, Portal destination, + PlayerMoveEvent event) { if (playerVehicle instanceof LivingEntity) { //Make sure any horses are properly tamed if (playerVehicle instanceof AbstractHorse horse && !horse.isTamed()) { horse.setTamed(true); horse.setOwner(player); } + //Teleport the player's vehicle new VehicleTeleporter(destination, (Vehicle) playerVehicle).teleport(entrancePortal); } else { + //Just teleport the player like normal new PlayerTeleporter(destination, player).teleport(entrancePortal, event); } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); @@ -302,7 +317,7 @@ public class PlayerEventListener implements Listener { */ private boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { //Check if bungee is actually enabled - if (!Stargate.enableBungee) { + if (!Stargate.getGateConfig().enableBungee()) { Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); entrancePortal.getPortalOpener().closePortal(false); return false; diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index a65b4e2..1e44b0a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -1,7 +1,6 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; @@ -33,8 +32,8 @@ public class PluginEventListener implements Listener { */ @EventHandler public void onPluginEnable(PluginEnableEvent ignored) { - if (EconomyHandler.setupEconomy(stargate.getServer().getPluginManager())) { - String vaultVersion = EconomyHandler.vault.getDescription().getVersion(); + if (Stargate.getEconomyConfig().setupEconomy(stargate.getServer().getPluginManager())) { + String vaultVersion = Stargate.getEconomyConfig().getVault().getDescription().getVersion(); stargate.getLogger().info(Stargate.getString("prefix") + Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } @@ -47,7 +46,7 @@ public class PluginEventListener implements Listener { */ @EventHandler public void onPluginDisable(PluginDisableEvent event) { - if (event.getPlugin().equals(EconomyHandler.vault)) { + if (event.getPlugin().equals(Stargate.getEconomyConfig().getVault())) { stargate.getLogger().info(Stargate.getString("prefix") + "Vault plugin lost."); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 6d10ec4..765b478 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -4,7 +4,6 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.VehicleTeleporter; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.PermissionHelper; @@ -30,7 +29,7 @@ public class VehicleEventListener implements Listener { */ @EventHandler public void onVehicleMove(VehicleMoveEvent event) { - if (!Stargate.handleVehicles) { + if (!Stargate.getGateConfig().handleVehicles()) { return; } List passengers = event.getVehicle().getPassengers(); @@ -110,7 +109,7 @@ public class VehicleEventListener implements Listener { //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be // run after it has been confirmed that all passengers are able to pay - int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); + int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { if (!takePlayerPayment(passengers, entrancePortal, cost)) { return; @@ -157,8 +156,8 @@ public class VehicleEventListener implements Listener { } //Transfer payment if necessary - int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); - return cost <= 0 || EconomyHandler.canAffordFee(player, cost); + int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal); + return cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 7168d0d..7bb5150 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -3,7 +3,6 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.utility.EconomyHandler; import org.bukkit.Material; import java.io.BufferedWriter; @@ -122,7 +121,7 @@ public class Gate { * @return

The cost of using a portal with this gate

*/ public int getUseCost() { - return useCost < 0 ? EconomyHandler.getDefaultUseCost() : useCost; + return useCost < 0 ? Stargate.getEconomyConfig().getDefaultUseCost() : useCost; } /** @@ -131,7 +130,7 @@ public class Gate { * @return

The cost of creating a portal with this gate

*/ public Integer getCreateCost() { - return createCost < 0 ? EconomyHandler.getDefaultCreateCost() : createCost; + return createCost < 0 ? Stargate.getEconomyConfig().getDefaultCreateCost() : createCost; } /** @@ -140,7 +139,7 @@ public class Gate { * @return

The cost of destroying a portal with this gate

*/ public Integer getDestroyCost() { - return destroyCost < 0 ? EconomyHandler.getDefaultDestroyCost() : destroyCost; + return destroyCost < 0 ? Stargate.getEconomyConfig().getDefaultDestroyCost() : destroyCost; } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index b6f0087..c706240 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -1,7 +1,6 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.GateReader; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; @@ -170,7 +169,7 @@ public class GateHandler { int createCost = GateReader.readGateConfig(config, fileName, "createcost"); int destroyCost = GateReader.readGateConfig(config, fileName, "destroycost"); boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : - EconomyHandler.toOwner); + Stargate.getEconomyConfig().sendPaymentToOwner()); //Create the new gate Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, portalOpenBlock, portalClosedBlock, diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 9ef75b1..16fa5ef 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -140,12 +140,13 @@ public class PortalActivator { destinations = PortalHandler.getDestinations(portal, player, network); //Sort destinations if enabled - if (Stargate.sortNetworkDestinations) { + if (Stargate.getGateConfig().sortNetworkDestinations()) { Collections.sort(destinations); } //Select last used destination if remember destination is enabled - if (Stargate.rememberDestination && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { + if (Stargate.getGateConfig().rememberDestination() && !lastDestination.isEmpty() && + destinations.contains(lastDestination)) { destination = lastDestination; } @@ -254,7 +255,7 @@ public class PortalActivator { } //Cycle if destination remembering is disabled, if the portal was already active, or it has no last destination - if (!Stargate.rememberDestination || !activate || lastDestination.isEmpty()) { + if (!Stargate.getGateConfig().rememberDestination() || !activate || lastDestination.isEmpty()) { cycleDestination(direction); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 28efd04..43379d5 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -5,7 +5,6 @@ import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.utility.DirectionHelper; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.PortalFileHelper; @@ -173,7 +172,7 @@ public class PortalCreator { String portalName = portal.getName(); String destinationName = portal.getDestinationName(); - int createCost = EconomyHandler.getCreateCost(player, gate); + int createCost = Stargate.getEconomyConfig().getCreateCost(player, gate); //Call StargateCreateEvent to let other plugins cancel or overwrite denial StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, lines, deny, @@ -247,14 +246,15 @@ public class PortalCreator { //Check if there are too many gates in this network List networkList = PortalHandler.getAllPortalNetworks().get(portal.getNetwork().toLowerCase()); - if (Stargate.maxGatesEachNetwork > 0 && networkList != null && networkList.size() >= Stargate.maxGatesEachNetwork) { + int maxGates = Stargate.getGateConfig().maxGatesEachNetwork(); + if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) { Stargate.sendErrorMessage(player, Stargate.getString("createFull")); return false; } } if (cost > 0) { - if (!EconomyHandler.chargePlayerIfNecessary(player, cost)) { + if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) { EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); Stargate.debug("createPortal", "Insufficient Funds"); return false; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index f090b6f..53ef384 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -123,7 +123,7 @@ public class PortalHandler { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); return false; - } else if (!Stargate.enableBungee) { + } else if (!Stargate.getGateConfig().enableBungee()) { Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); return false; } else if (destinationName.isEmpty() || network.isEmpty()) { @@ -394,8 +394,9 @@ public class PortalHandler { for (Portal portal : PortalRegistry.getAllPortals()) { //Open the gate if it's set as always open or if it's a bungee gate - if (portal.getOptions().isFixed() && (Stargate.enableBungee && portal.getOptions().isBungee() || - portal.getPortalActivator().getDestination() != null && portal.getOptions().isAlwaysOn())) { + if (portal.getOptions().isFixed() && (Stargate.getGateConfig().enableBungee() && + portal.getOptions().isBungee() || portal.getPortalActivator().getDestination() != null && + portal.getOptions().isAlwaysOn())) { portal.getPortalOpener().openPortal(true); alwaysOpenCount++; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 0467f4d..8ba642b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -1,7 +1,6 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.ChatColor; import org.bukkit.block.Block; @@ -50,8 +49,8 @@ public class PortalSignDrawer { for (int index = 0; index <= 3; index++) { sign.setLine(index, ""); } - Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.signColor + portal.getName() + - ChatColor.WHITE + "-"); + Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.getGateConfig().getSignColor() + + portal.getName() + ChatColor.WHITE + "-"); if (!portal.getPortalActivator().isActive()) { //Default sign text @@ -82,7 +81,8 @@ public class PortalSignDrawer { int maxIndex = destinations.getDestinations().size() - 1; int signLineIndex = 0; int destinationIndex = destinations.getDestinations().indexOf(portal.getDestinationName()); - boolean freeGatesGreen = EconomyHandler.useEconomy() && EconomyHandler.freeGatesGreen; + boolean freeGatesGreen = Stargate.getEconomyConfig().useEconomy() && + Stargate.getEconomyConfig().drawFreePortalsGreen(); //Last, and not only entry. Draw the entry two back if ((destinationIndex == maxIndex) && (maxIndex > 1)) { @@ -118,8 +118,8 @@ public class PortalSignDrawer { Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + portal.getDestinationName() + (green ? ChatColor.DARK_GREEN : "") + "<"); } else { - Stargate.setLine(sign, signLineIndex, Stargate.signColor + " >" + portal.getDestinationName() + - Stargate.signColor + "< "); + Stargate.setLine(sign, signLineIndex, Stargate.getGateConfig().getSignColor() + " >" + + portal.getDestinationName() + Stargate.getGateConfig().getSignColor() + "< "); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java b/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java index 73509b7..bd97be5 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java @@ -67,7 +67,7 @@ public class PortalStructure { */ public boolean isVerified() { boolean verified = true; - if (!Stargate.verifyPortals) { + if (!Stargate.getGateConfig().verifyPortals()) { return true; } for (RelativeBlockVector control : gate.getLayout().getControls()) { @@ -83,7 +83,7 @@ public class PortalStructure { * @return

True if this portal was verified

*/ public boolean wasVerified() { - if (!Stargate.verifyPortals) { + if (!Stargate.getGateConfig().verifyPortals()) { return true; } return verified; @@ -95,10 +95,11 @@ public class PortalStructure { * @return

True if all blocks match the gate template

*/ public boolean checkIntegrity() { - if (!Stargate.verifyPortals) { + if (Stargate.getGateConfig().verifyPortals()) { + return gate.matches(portal.getTopLeft(), portal.getYaw()); + } else { return true; } - return gate.matches(portal.getTopLeft(), portal.getYaw()); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 189320c..b3c8f94 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -30,9 +30,9 @@ public final class EconomyHelper { //Try to charge the player. Paying the portal owner is only possible if a UUID is available if (entrancePortal.getGate().getToOwner()) { UUID ownerUUID = entrancePortal.getOwner().getUUID(); - success = ownerUUID != null && EconomyHandler.chargePlayerIfNecessary(player, ownerUUID, cost); + success = ownerUUID != null && Stargate.getEconomyConfig().chargePlayerIfNecessary(player, ownerUUID, cost); } else { - success = EconomyHandler.chargePlayerIfNecessary(player, cost); + success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost); } //Send the insufficient funds message @@ -124,7 +124,7 @@ public final class EconomyHelper { */ private static String replaceVars(String message, String portalName, int cost) { return Stargate.replaceVars(message, new String[]{"%cost%", "%portal%"}, - new String[]{EconomyHandler.format(cost), portalName}); + new String[]{Stargate.getEconomyConfig().format(cost), portalName}); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 454787f..8dfb1ad 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -232,7 +232,7 @@ public final class PermissionHelper { return true; } // Don't charge for free destination gates - return dest != null && !EconomyHandler.chargeFreeDestination && dest.getOptions().isFree(); + return dest != null && !Stargate.getEconomyConfig().chargeFreeDestination() && dest.getOptions().isFree(); } /** @@ -409,7 +409,7 @@ public final class PermissionHelper { } //Player cannot pay for teleportation - int cost = EconomyHandler.getUseCost(player, entrancePortal, destination); + int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destination); if (cost > 0) { return EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost); } From 50084c40f99589019b79e0880e870e1e16517bd4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 12:58:31 +0200 Subject: [PATCH 182/378] Moves the Bungee Queue to BungeeHelper --- .../java/net/knarcraft/stargate/Stargate.java | 3 --- .../listener/PlayerEventListener.java | 2 +- .../stargate/utility/BungeeHelper.java | 19 ++++++++++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index d56c04e..e050e80 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -42,7 +42,6 @@ import org.bukkit.scheduler.BukkitScheduler; import java.io.File; import java.io.IOException; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; @@ -78,8 +77,6 @@ public class Stargate extends JavaPlugin { public static boolean debuggingEnabled = false; public static boolean permissionDebuggingEnabled = false; - //HashMap of player names for Bungee support - public static final Map bungeeQueue = new HashMap<>(); //World names that contain stargates public static final HashSet managedWorlds = new HashSet<>(); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 52c3745..c7b960f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -48,7 +48,7 @@ public class PlayerEventListener implements Listener { Player player = event.getPlayer(); //Check if the player is waiting to be teleported to a stargate - String destination = Stargate.bungeeQueue.remove(player.getName().toLowerCase()); + String destination = BungeeHelper.removeFromQueue(player.getName()); if (destination == null) { return; } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 266fde6..4aee35c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -11,6 +11,8 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** * This class contains helpful functions to help with sending and receiving BungeeCord plugin messages @@ -20,11 +22,26 @@ public final class BungeeHelper { private final static String bungeeSubChannel = "SGBungee"; private final static String bungeeChannel = "BungeeCord"; private final static String teleportMessageDelimiter = "#@#"; + private final static Map bungeeQueue = new HashMap<>(); private BungeeHelper() { } + /** + * Removes a player from the queue of players teleporting through BungeeCord + * + *

Whenever a BungeeCord teleportation message is received and the player is not currently connected to this + * server, it'll be added to this queue. Once the player joins this server, the player should be removed from the + * queue and teleported to the destination.

+ * + * @param playerName

The name of the player to remove

+ * @return

The name of the destination portal the player should be teleported to

+ */ + public static String removeFromQueue(String playerName) { + return bungeeQueue.remove(playerName.toLowerCase()); + } + /** * Sends a plugin message to BungeeCord allowing the target server to catch it * @@ -123,7 +140,7 @@ public final class BungeeHelper { // Check if the player is online, if so, teleport, otherwise, queue Player player = Stargate.server.getPlayer(playerName); if (player == null) { - Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); + bungeeQueue.put(playerName.toLowerCase(), destination); } else { Portal destinationPortal = PortalHandler.getBungeePortal(destination); // Specified an invalid gate. For now, we'll just let them connect at their current location From 7cc8685e2632e0d9ec7cbe74416f5e5339affe4f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 14:10:33 +0200 Subject: [PATCH 183/378] Moves all methods for sending messages to players to the MessageSender class --- .../java/net/knarcraft/stargate/Stargate.java | 55 ++++------------ .../stargate/command/CommandReload.java | 2 +- .../stargate/config/MessageSender.java | 63 +++++++++++++++++++ .../stargate/listener/BlockEventListener.java | 6 +- .../listener/PlayerEventListener.java | 8 +-- .../listener/VehicleEventListener.java | 6 +- .../stargate/portal/PortalActivator.java | 2 +- .../stargate/portal/PortalCreator.java | 12 ++-- .../stargate/portal/PortalHandler.java | 8 +-- .../stargate/utility/EconomyHelper.java | 8 +-- .../stargate/utility/PermissionHelper.java | 12 ++-- 11 files changed, 108 insertions(+), 74 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/config/MessageSender.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index e050e80..76058d1 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.config.EconomyConfig; import net.knarcraft.stargate.config.LanguageLoader; +import net.knarcraft.stargate.config.MessageSender; import net.knarcraft.stargate.config.StargateGateConfig; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.ChunkUnloadRequest; @@ -26,7 +27,6 @@ import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.utility.FileHelper; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Server; import org.bukkit.World; import org.bukkit.block.Sign; @@ -88,6 +88,7 @@ public class Stargate extends JavaPlugin { private FileConfiguration newConfig; private PluginManager pluginManager; + private static MessageSender messageSender; /** * Empty constructor necessary for Spigot @@ -108,6 +109,15 @@ public class Stargate extends JavaPlugin { super(loader, descriptionFile, dataFolder, file); } + /** + * Gets the sender for sending messages to players + * + * @return

The sender for sending messages to players

+ */ + public static MessageSender getMessageSender() { + return messageSender; + } + /** * Gets the object containing gate configuration values * @@ -176,46 +186,6 @@ public class Stargate extends JavaPlugin { } } - /** - * Sends an error message to a player - * - * @param player

The player to send the message to

- * @param message

The message to send

- */ - public static void sendErrorMessage(CommandSender player, String message) { - sendMessage(player, message, true); - } - - /** - * Sends a success message to a player - * - * @param player

The player to send the message to

- * @param message

The message to send

- */ - public static void sendSuccessMessage(CommandSender player, String message) { - sendMessage(player, message, false); - } - - /** - * Sends a message to a player - * - * @param player

The player to send the message to

- * @param message

The message to send

- * @param error

Whether the message sent is an error

- */ - private static void sendMessage(CommandSender player, String message, boolean error) { - if (message.isEmpty()) { - return; - } - //Replace color codes with green? What's the deal with the dollar sign? - message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); - if (error) { - player.sendMessage(ChatColor.RED + Stargate.getString("prefix") + ChatColor.WHITE + message); - } else { - player.sendMessage(ChatColor.GREEN + Stargate.getString("prefix") + ChatColor.WHITE + message); - } - } - /** * Sets a line on a sign, adding the chosen sign color * @@ -339,6 +309,7 @@ public class Stargate extends JavaPlugin { // It is important to load languages here, as they are used during reloadGates() languageLoader = new LanguageLoader(languageFolder, Stargate.languageName); + messageSender = new MessageSender(languageLoader); if (debuggingEnabled) { languageLoader.debug(); } @@ -549,7 +520,7 @@ public class Stargate extends JavaPlugin { startStopBungeeListener(stargateGateConfig.enableBungee()); } - sendErrorMessage(sender, "stargate reloaded"); + messageSender.sendErrorMessage(sender, "stargate reloaded"); } /** diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index 73cdf93..c66da9f 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -28,7 +28,7 @@ public class CommandReload implements CommandExecutor { @NotNull String[] args) { if (commandSender instanceof Player player) { if (!player.hasPermission("stargate.reload")) { - Stargate.sendErrorMessage(commandSender, "Permission Denied"); + Stargate.getMessageSender().sendErrorMessage(commandSender, "Permission Denied"); return true; } } diff --git a/src/main/java/net/knarcraft/stargate/config/MessageSender.java b/src/main/java/net/knarcraft/stargate/config/MessageSender.java new file mode 100644 index 0000000..2ada1f4 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/MessageSender.java @@ -0,0 +1,63 @@ +package net.knarcraft.stargate.config; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * The message sender is responsible sending messages to players with correct coloring and formatting + */ +public final class MessageSender { + + private final LanguageLoader languageLoader; + + /** + * Instantiates a new message sender + * + * @param languageLoader

The language loader to get translated strings from

+ */ + public MessageSender(LanguageLoader languageLoader) { + this.languageLoader = languageLoader; + } + + /** + * Sends an error message to a player + * + * @param player

The player to send the message to

+ * @param message

The message to send

+ */ + public void sendErrorMessage(CommandSender player, String message) { + sendMessage(player, message, true); + } + + /** + * Sends a success message to a player + * + * @param player

The player to send the message to

+ * @param message

The message to send

+ */ + public void sendSuccessMessage(CommandSender player, String message) { + sendMessage(player, message, false); + } + + /** + * Sends a message to a player + * + * @param sender

The player to send the message to

+ * @param message

The message to send

+ * @param error

Whether the message sent is an error

+ */ + private void sendMessage(CommandSender sender, String message, boolean error) { + if (message.isEmpty()) { + return; + } + //Replace color codes with green? What's the deal with the dollar sign? + //TODO: Figure out what this is actually supposed to do and do it in a better way + message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); + if (error) { + sender.sendMessage(ChatColor.RED + languageLoader.getString("prefix") + ChatColor.WHITE + message); + } else { + sender.sendMessage(ChatColor.GREEN + languageLoader.getString("prefix") + ChatColor.WHITE + message); + } + } + +} diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 690a340..9a68b40 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -81,7 +81,7 @@ public class BlockEventListener implements Listener { return; } - Stargate.sendSuccessMessage(player, Stargate.getString("createMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("createMsg")); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); } @@ -130,7 +130,7 @@ public class BlockEventListener implements Listener { //Destroy denied if (destroyEvent.getDeny()) { - Stargate.sendErrorMessage(player, destroyEvent.getDenyReason()); + Stargate.getMessageSender().sendErrorMessage(player, destroyEvent.getDenyReason()); event.setCancelled(true); return; } @@ -141,7 +141,7 @@ public class BlockEventListener implements Listener { } PortalRegistry.unregisterPortal(portal, true); - Stargate.sendSuccessMessage(player, Stargate.getString("destroyMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("destroyMsg")); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index c7b960f..af8f211 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -114,7 +114,7 @@ public class PlayerEventListener implements Listener { //Just teleport the player like normal new PlayerTeleporter(destination, player).teleport(entrancePortal, event); } - Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); entrancePortal.getPortalOpener().closePortal(false); } @@ -155,7 +155,7 @@ public class PlayerEventListener implements Listener { //Decide if the user should be teleported to another bungee server if (entrancePortal.getOptions().isBungee()) { if (bungeeTeleport(player, entrancePortal, event)) { - Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); } return false; } @@ -236,7 +236,7 @@ public class PlayerEventListener implements Listener { boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); if (PermissionHelper.cannotAccessPortal(player, portal, deny)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return true; } return false; @@ -318,7 +318,7 @@ public class PlayerEventListener implements Listener { private boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { //Check if bungee is actually enabled if (!Stargate.getGateConfig().enableBungee()) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); entrancePortal.getPortalOpener().closePortal(false); return false; } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 765b478..e022b16 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -90,7 +90,7 @@ public class VehicleEventListener implements Listener { //On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open // to one player at a time, we only need to check if the portal is open to the driver. if (!entrancePortal.getPortalOpener().isOpenFor(player)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } @@ -116,7 +116,7 @@ public class VehicleEventListener implements Listener { } } - Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); entrancePortal.getPortalOpener().closePortal(false); } @@ -150,7 +150,7 @@ public class VehicleEventListener implements Listener { private static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { //Make sure the user can access the portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); entrancePortal.getPortalOpener().closePortal(false); return false; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 16fa5ef..4848717 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -250,7 +250,7 @@ public class PortalActivator { //If no destinations are available, just tell the player and quit if (destinations.size() == 0) { - Stargate.sendErrorMessage(player, Stargate.getString("destEmpty")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("destEmpty")); return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 43379d5..fa72fa1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -116,7 +116,7 @@ public class PortalCreator { network = network.substring(0, 11); } Stargate.debug("createPortal", "Creating personal portal"); - Stargate.sendErrorMessage(player, Stargate.getString("createPersonal")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createPersonal")); } else { Stargate.debug("createPortal", "Player does not have access to network"); deny = true; @@ -184,7 +184,7 @@ public class PortalCreator { //Tell the user why it was denied from creating the portal if (stargateCreateEvent.getDeny()) { - Stargate.sendErrorMessage(player, stargateCreateEvent.getDenyReason()); + Stargate.getMessageSender().sendErrorMessage(player, stargateCreateEvent.getDenyReason()); return null; } @@ -226,7 +226,7 @@ public class PortalCreator { // Name & Network can be changed in the event, so do these checks here. if (portal.getName().length() < 1 || portal.getName().length() > 11) { Stargate.debug("createPortal", "Name length error"); - Stargate.sendErrorMessage(player, Stargate.getString("createNameLength")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength")); return false; } @@ -234,13 +234,13 @@ public class PortalCreator { if (portal.getOptions().isBungee()) { if (PortalHandler.getBungeePortals().get(portal.getName().toLowerCase()) != null) { Stargate.debug("createPortal::Bungee", "Gate name duplicate"); - Stargate.sendErrorMessage(player, Stargate.getString("createExists")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); return false; } } else { if (PortalHandler.getByName(portal.getName(), portal.getNetwork()) != null) { Stargate.debug("createPortal", "Gate name duplicate"); - Stargate.sendErrorMessage(player, Stargate.getString("createExists")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); return false; } @@ -248,7 +248,7 @@ public class PortalCreator { List networkList = PortalHandler.getAllPortalNetworks().get(portal.getNetwork().toLowerCase()); int maxGates = Stargate.getGateConfig().maxGatesEachNetwork(); if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) { - Stargate.sendErrorMessage(player, Stargate.getString("createFull")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createFull")); return false; } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 53ef384..af947d9 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -121,13 +121,13 @@ public class PortalHandler { String destinationName, String network) { if (portalOptions.get(PortalOption.BUNGEE)) { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeDeny")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDeny")); return false; } else if (!Stargate.getGateConfig().enableBungee()) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); return false; } else if (destinationName.isEmpty() || network.isEmpty()) { - Stargate.sendErrorMessage(player, Stargate.getString("bungeeEmpty")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeEmpty")); return false; } } @@ -188,7 +188,7 @@ public class PortalHandler { BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); if (getByBlock(borderBlockLocation.getBlock()) != null) { Stargate.debug("createPortal", "Gate conflicts with existing gate"); - Stargate.sendErrorMessage(player, Stargate.getString("createConflict")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createConflict")); return true; } } diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index b3c8f94..627e7ae 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -72,7 +72,7 @@ public final class EconomyHelper { public static void sendObtainMessage(String portalName, Player portalOwner, int earnings) { String obtainedMsg = Stargate.getString("ecoObtain"); obtainedMsg = replaceVars(obtainedMsg, portalName, earnings); - Stargate.sendSuccessMessage(portalOwner, obtainedMsg); + Stargate.getMessageSender().sendSuccessMessage(portalOwner, obtainedMsg); } /** @@ -85,7 +85,7 @@ public final class EconomyHelper { public static void sendDeductMessage(String portalName, Player player, int cost) { String deductMsg = Stargate.getString("ecoDeduct"); deductMsg = replaceVars(deductMsg, portalName, cost); - Stargate.sendSuccessMessage(player, deductMsg); + Stargate.getMessageSender().sendSuccessMessage(player, deductMsg); } /** @@ -98,7 +98,7 @@ public final class EconomyHelper { public static void sendInsufficientFundsMessage(String portalName, Player player, int cost) { String inFundMsg = Stargate.getString("ecoInFunds"); inFundMsg = replaceVars(inFundMsg, portalName, cost); - Stargate.sendErrorMessage(player, inFundMsg); + Stargate.getMessageSender().sendErrorMessage(player, inFundMsg); } /** @@ -111,7 +111,7 @@ public final class EconomyHelper { public static void sendRefundMessage(String portalName, Player player, int cost) { String refundMsg = Stargate.getString("ecoRefund"); refundMsg = replaceVars(refundMsg, portalName, -cost); - Stargate.sendSuccessMessage(player, refundMsg); + Stargate.getMessageSender().sendSuccessMessage(player, refundMsg); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 8dfb1ad..ef93713 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -38,7 +38,7 @@ public final class PermissionHelper { //Invalid destination if ((destination == null) || (destination == portal)) { - Stargate.sendErrorMessage(player, Stargate.getString("invalidMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); return; } @@ -54,19 +54,19 @@ public final class PermissionHelper { //Gate that someone else is using -- Deny access if ((!portal.getOptions().isFixed()) && portal.getPortalActivator().isActive() && (portal.getActivePlayer() != player)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } //Check if the player can use the private gate if (portal.getOptions().isPrivate() && !PermissionHelper.canPrivate(player, portal)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } //Destination blocked if ((destination.isOpen()) && (!destination.getOptions().isAlwaysOn())) { - Stargate.sendErrorMessage(player, Stargate.getString("blockMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg")); return; } @@ -390,7 +390,7 @@ public final class PermissionHelper { // Not open for this player if (!entrancePortal.getPortalOpener().isOpenFor(player)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); return true; } @@ -402,7 +402,7 @@ public final class PermissionHelper { //Player cannot access portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); entrancePortal.getPortalOpener().closePortal(false); return true; From deba2e5c2c38b9b5871666782b57265b6eea3546 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 14:25:46 +0200 Subject: [PATCH 184/378] Makes the stargate logger private --- .../java/net/knarcraft/stargate/Stargate.java | 11 ++++++++++- .../stargate/config/EconomyConfig.java | 6 ++++-- .../stargate/config/LanguageLoader.java | 18 ++++++++++-------- .../stargate/config/StargateGateConfig.java | 2 +- .../stargate/listener/BlockEventListener.java | 3 ++- .../net/knarcraft/stargate/portal/Gate.java | 2 +- .../knarcraft/stargate/portal/GateHandler.java | 6 +++--- .../stargate/portal/PortalHandler.java | 6 +++--- .../stargate/portal/PortalSignDrawer.java | 3 ++- .../knarcraft/stargate/portal/Teleporter.java | 4 ++-- .../stargate/portal/VehicleTeleporter.java | 2 +- .../stargate/utility/BungeeHelper.java | 11 +++++++---- .../knarcraft/stargate/utility/GateReader.java | 12 ++++++------ .../stargate/utility/PortalFileHelper.java | 15 ++++++++------- 14 files changed, 60 insertions(+), 41 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 76058d1..43c1578 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -64,7 +64,7 @@ public class Stargate extends JavaPlugin { private static final int activeTime = 10; private static final int openTime = 10; - public static Logger logger; + private static Logger logger; public static Server server; public static Stargate stargate; public static LanguageLoader languageLoader; @@ -172,6 +172,15 @@ public class Stargate extends JavaPlugin { return activeTime; } + /** + * Gets the logger used for logging to the console + * + * @return

The logger

+ */ + public static Logger getConsoleLogger() { + return logger; + } + /** * Sends a debug message * diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 57aa347..9eeca5e 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -242,10 +242,12 @@ public final class EconomyConfig { this.vault = vault; return true; } else { - Stargate.logger.info(Stargate.getString("prefix") + Stargate.getString("ecoLoadError")); + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + + Stargate.getString("ecoLoadError")); } } else { - Stargate.logger.info(Stargate.getString("prefix") + Stargate.getString("vaultLoadError")); + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + + Stargate.getString("vaultLoadError")); } economyEnabled = false; return false; diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index e238e0a..25e726a 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -35,7 +35,7 @@ public final class LanguageLoader { File tmp = new File(languageFolder, chosenLanguage + ".txt"); if (!tmp.exists()) { if (tmp.getParentFile().mkdirs() && Stargate.debuggingEnabled) { - Stargate.logger.info("[stargate] Created language folder"); + Stargate.getConsoleLogger().info("[stargate] Created language folder"); } } updateLanguage(chosenLanguage); @@ -47,7 +47,8 @@ public final class LanguageLoader { loadedBackupStrings = load("en", inputStream); } else { loadedBackupStrings = null; - Stargate.logger.severe("[stargate] Error loading backup language. There may be missing text in-game"); + Stargate.getConsoleLogger().severe("[stargate] Error loading backup language. There may be missing " + + "text in-game"); } } @@ -101,10 +102,10 @@ public final class LanguageLoader { InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); if (inputStream == null) { - Stargate.logger.info("[stargate] The language " + language + " is not available. Falling back to " + - "english, You can add a custom language by creating a new text file in the lang directory."); + Stargate.getConsoleLogger().info("[stargate] The language " + language + " is not available. Falling " + + "back to english, You can add a custom language by creating a new text file in the lang directory."); if (Stargate.debuggingEnabled) { - Stargate.logger.info("[stargate] Unable to load /lang/" + language + ".txt"); + Stargate.getConsoleLogger().info("[stargate] Unable to load /lang/" + language + ".txt"); } return; } @@ -133,7 +134,7 @@ public final class LanguageLoader { //If currentLanguageValues is null; the chosen language has not been used before if (currentLanguageValues == null) { updateLanguageFile(language, internalLanguageValues, null); - Stargate.logger.info("[stargate] Language (" + language + ") has been loaded"); + Stargate.getConsoleLogger().info("[stargate] Language (" + language + ") has been loaded"); return; } @@ -154,7 +155,8 @@ public final class LanguageLoader { //Update the file itself if (updateNecessary) { updateLanguageFile(language, newLanguageValues, currentLanguageValues); - Stargate.logger.info("[stargate] Your language file (" + language + ".txt) has been updated"); + Stargate.getConsoleLogger().info("[stargate] Your language file (" + language + + ".txt) has been updated"); } } } @@ -216,7 +218,7 @@ public final class LanguageLoader { strings = FileHelper.readKeyValuePairs(bufferedReader); } catch (Exception e) { if (Stargate.debuggingEnabled) { - Stargate.logger.info("[stargate] Unable to load language " + lang); + Stargate.getConsoleLogger().info("[stargate] Unable to load language " + lang); } return null; } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 2b04016..8ab9cf5 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -161,7 +161,7 @@ public final class StargateGateConfig { } catch (IllegalArgumentException | NullPointerException ignored) { } } - Stargate.logger.warning(getString("prefix") + + Stargate.getConsoleLogger().warning(getString("prefix") + "You have specified an invalid color in your config.yml. Defaulting to BLACK"); this.signColor = ChatColor.BLACK; } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 9a68b40..a74a30f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -115,7 +115,8 @@ public class BlockEventListener implements Listener { if (!PermissionHelper.canDestroyPortal(player, portal)) { denyMessage = Stargate.getString("denyMsg"); deny = true; - Stargate.logger.info(Stargate.getString("prefix") + player.getName() + " tried to destroy gate"); + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + player.getName() + + " tried to destroy gate"); } int cost = Stargate.getEconomyConfig().getDestroyCost(player, portal.getGate()); diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 7bb5150..31b36c1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -268,7 +268,7 @@ public class Gate { bufferedWriter.close(); } catch (IOException ex) { - Stargate.logger.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); + Stargate.getConsoleLogger().log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index c706240..139386f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -106,7 +106,7 @@ public class GateHandler { try (Scanner scanner = new Scanner(file)) { return loadGate(file.getName(), file.getParent(), scanner); } catch (Exception ex) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); return null; } } @@ -190,13 +190,13 @@ public class GateHandler { */ private static boolean validateGate(Gate gate, String fileName) { if (gate.getLayout().getControls().length != 2) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + + Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); return false; } if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + + Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); return false; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index af947d9..2aca540 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -88,7 +88,7 @@ public class PortalHandler { } //Check if this player can access the dest world if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { - Stargate.logger.info("cannot access world"); + Stargate.getConsoleLogger().info("cannot access world"); continue; } //Visible to this player. @@ -439,14 +439,14 @@ public class PortalHandler { } } PortalRegistry.unregisterPortal(portal, false); - Stargate.logger.info(Stargate.getString("prefix") + "Destroying stargate at " + portal); + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Destroying stargate at " + portal); } /** * Closes all portals */ public static void closeAllPortals() { - Stargate.logger.info("Closing all stargates."); + Stargate.getConsoleLogger().info("Closing all stargates."); for (Portal portal : PortalRegistry.getAllPortals()) { if (portal != null) { portal.getPortalOpener().closePortal(true); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 8ba642b..437941c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -30,7 +30,8 @@ public class PortalSignDrawer { Block signBlock = portal.getSignLocation().getBlock(); BlockState state = signBlock.getState(); if (!(state instanceof Sign sign)) { - Stargate.logger.warning(Stargate.getString("prefix") + "Sign block is not a Sign object"); + Stargate.getConsoleLogger().warning(Stargate.getString("prefix") + + "Sign block is not a Sign object"); Stargate.debug("Portal::drawSign", "Block: " + signBlock.getType() + " @ " + signBlock.getLocation()); return; diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index fb1c79b..f4c8040 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -80,7 +80,7 @@ public abstract class Teleporter { } } } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + Stargate.getConsoleLogger().log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + portal.getGate().getFilename()); } @@ -180,7 +180,7 @@ public abstract class Teleporter { exitLocation.setPitch(traveller.getPitch()); return exitLocation; } else { - Stargate.logger.log(Level.WARNING, Stargate.getString("prefix") + + Stargate.getConsoleLogger().log(Level.WARNING, Stargate.getString("prefix") + "Unable to generate exit location"); } return traveller; diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java index 72462b3..e637cb1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -138,7 +138,7 @@ public class VehicleTeleporter extends Teleporter { Vector newVelocity) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { - Stargate.logger.warning(Stargate.getString("prefix") + + Stargate.getConsoleLogger().warning(Stargate.getString("prefix") + "Unable to get the world to teleport the vehicle to"); return; } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 4aee35c..e0040a8 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -66,7 +66,7 @@ public final class BungeeHelper { dataOutputStream.writeBytes(message); player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { - Stargate.logger.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); + Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); ex.printStackTrace(); return false; } @@ -90,7 +90,8 @@ public final class BungeeHelper { player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); byteArrayOutputStream.reset(); } catch (IOException ex) { - Stargate.logger.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); + Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + + "Error sending BungeeCord connect packet"); ex.printStackTrace(); return false; } @@ -117,7 +118,8 @@ public final class BungeeHelper { data = new byte[dataLength]; dataInputStream.readFully(data); } catch (IOException ex) { - Stargate.logger.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); + Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + + "Error receiving BungeeCord message"); ex.printStackTrace(); return null; } @@ -145,7 +147,8 @@ public final class BungeeHelper { Portal destinationPortal = PortalHandler.getBungeePortal(destination); // Specified an invalid gate. For now, we'll just let them connect at their current location if (destinationPortal == null) { - Stargate.logger.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Bungee gate " + + destination + " does not exist"); return; } new PlayerTeleporter(destinationPortal, player).teleport(destinationPortal, null); diff --git a/src/main/java/net/knarcraft/stargate/utility/GateReader.java b/src/main/java/net/knarcraft/stargate/utility/GateReader.java index a04a10a..77d651c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/GateReader.java +++ b/src/main/java/net/knarcraft/stargate/utility/GateReader.java @@ -55,7 +55,7 @@ public final class GateReader { } } } catch (Exception ex) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); return -1; } finally { if (scanner != null) { @@ -90,8 +90,8 @@ public final class GateReader { for (Character symbol : line.toCharArray()) { //Refuse read gate designs with unknown characters if (symbol.equals('?') || (!characterMaterialMap.containsKey(symbol))) { - Stargate.logger.log(Level.SEVERE, "Could not load Gate " + fileName + " - Unknown symbol '" + - symbol + "' in diagram"); + Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + + " - Unknown symbol '" + symbol + "' in diagram"); return -1; } //Add the read character to the row @@ -148,7 +148,7 @@ public final class GateReader { try { return Integer.parseInt(config.get(key)); } catch (NumberFormatException ex) { - Stargate.logger.log(Level.WARNING, String.format("%s reading %s: %s is not numeric", + Stargate.getConsoleLogger().log(Level.WARNING, String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), fileName, key)); } } @@ -172,8 +172,8 @@ public final class GateReader { if (material != null) { return material; } else { - Stargate.logger.log(Level.WARNING, String.format("Error reading %s: %s is not a material", fileName, - key)); + Stargate.getConsoleLogger().log(Level.WARNING, String.format("Error reading %s: %s is not a material", + fileName, key)); } } return defaultMaterial; diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 502110a..2e42767 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -53,7 +53,8 @@ public final class PortalFileHelper { bufferedWriter.close(); } catch (Exception e) { - Stargate.logger.log(Level.SEVERE, "Exception while writing stargates to " + saveFileLocation + ": " + e); + Stargate.getConsoleLogger().log(Level.SEVERE, "Exception while writing stargates to " + + saveFileLocation + ": " + e); } } @@ -131,7 +132,7 @@ public final class PortalFileHelper { if (database.exists()) { return loadPortals(world, database); } else { - Stargate.logger.info(Stargate.getString("prefix") + "{" + world.getName() + + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "{" + world.getName() + "} No stargates for world "); } return false; @@ -158,8 +159,8 @@ public final class PortalFileHelper { doPostLoadTasks(world); return true; } catch (Exception e) { - Stargate.logger.log(Level.SEVERE, "Exception while reading stargates from " + database.getName() + - ": " + lineIndex); + Stargate.getConsoleLogger().log(Level.SEVERE, "Exception while reading stargates from " + + database.getName() + ": " + lineIndex); e.printStackTrace(); } return false; @@ -183,7 +184,7 @@ public final class PortalFileHelper { //Check if the min. required portal data is present String[] portalData = line.split(":"); if (portalData.length < 8) { - Stargate.logger.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); return; } @@ -206,7 +207,7 @@ public final class PortalFileHelper { int openCount = PortalHandler.openAlwaysOpenPortals(); //Print info about loaded stargates so that admins can see if all stargates loaded - Stargate.logger.info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", + Stargate.getConsoleLogger().info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", Stargate.getString("prefix"), world.getName(), portalCount, openCount)); //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since @@ -270,7 +271,7 @@ public final class PortalFileHelper { Stargate.setLine(sign, 3, Stargate.getString("signInvalidGate")); sign.update(); - Stargate.logger.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + + Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + " does not exist [" + gateName + "]"); } From b7998023f59467c56c05f82fafbad72d490f5251 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 14:35:07 +0200 Subject: [PATCH 185/378] Moves activeTime and openTime into the StargateGateConfig --- .../java/net/knarcraft/stargate/Stargate.java | 22 ------------------- .../stargate/config/StargateGateConfig.java | 20 +++++++++++++++++ .../stargate/thread/StarGateThread.java | 4 ++-- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 43c1578..a49d9df 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -60,10 +60,6 @@ public class Stargate extends JavaPlugin { public static final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); private static final Queue chunkUnloadQueue = new PriorityQueue<>(); - //Amount of seconds before deactivating/closing portals - private static final int activeTime = 10; - private static final int openTime = 10; - private static Logger logger; public static Server server; public static Stargate stargate; @@ -154,24 +150,6 @@ public class Stargate extends JavaPlugin { return stargateGateConfig.destroyedByExplosion(); } - /** - * Gets the amount of seconds a portal should be open before automatically closing - * - * @return

The open time of a gate

- */ - public static int getOpenTime() { - return openTime; - } - - /** - * Gets the amount of seconds a portal should be active before automatically deactivating - * - * @return

The active time of a gate

- */ - public static int getActiveTime() { - return activeTime; - } - /** * Gets the logger used for logging to the console * diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 8ab9cf5..8a39a4b 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -21,6 +21,8 @@ public final class StargateGateConfig { private boolean destroyExplosion = false; private ChatColor signColor; private String defaultGateNetwork = "central"; + private static final int activeTime = 10; + private static final int openTime = 10; /** * Instantiates a new stargate config @@ -31,6 +33,24 @@ public final class StargateGateConfig { loadGateConfig(newConfig); } + /** + * Gets the amount of seconds a portal should be open before automatically closing + * + * @return

The open time of a gate

+ */ + public int getOpenTime() { + return openTime; + } + + /** + * Gets the amount of seconds a portal should be active before automatically deactivating + * + * @return

The active time of a gate

+ */ + public int getActiveTime() { + return activeTime; + } + /** * Gets the maximum number of gates allowed on each network * diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index c2ad0a4..ac734eb 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -20,7 +20,7 @@ public class StarGateThread implements Runnable { if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) { continue; } - if (time > portal.getActivatedTime() + Stargate.getOpenTime()) { + if (time > portal.getActivatedTime() + Stargate.getGateConfig().getOpenTime()) { portal.getPortalOpener().closePortal(false); iterator.remove(); } @@ -31,7 +31,7 @@ public class StarGateThread implements Runnable { if (!portal.getPortalActivator().isActive()) { continue; } - if (time > portal.getActivatedTime() + Stargate.getActiveTime()) { + if (time > portal.getActivatedTime() + Stargate.getGateConfig().getActiveTime()) { portal.getPortalActivator().deactivate(); iterator.remove(); } From 2541391d3e35551dbe5731eb821535308c4fba0a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 18:34:31 +0200 Subject: [PATCH 186/378] Moves all config related code from Stargate to StargateConfig --- .../java/net/knarcraft/stargate/Stargate.java | 360 +++------------ .../stargate/command/CommandAbout.java | 2 +- .../stargate/command/CommandReload.java | 13 +- .../stargate/command/CommandStarGate.java | 13 +- .../stargate/config/LanguageLoader.java | 8 +- .../stargate/config/StargateConfig.java | 433 ++++++++++++++++++ .../listener/EntityEventListener.java | 2 +- .../stargate/listener/WorldEventListener.java | 11 +- .../stargate/portal/PortalRegistry.java | 9 +- .../stargate/portal/PortalSignDrawer.java | 47 +- .../stargate/utility/PermissionHelper.java | 6 +- .../stargate/utility/PortalFileHelper.java | 9 +- 12 files changed, 545 insertions(+), 368 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/config/StargateConfig.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index a49d9df..1e18ddf 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -3,13 +3,12 @@ package net.knarcraft.stargate; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.config.EconomyConfig; -import net.knarcraft.stargate.config.LanguageLoader; import net.knarcraft.stargate.config.MessageSender; +import net.knarcraft.stargate.config.StargateConfig; import net.knarcraft.stargate.config.StargateGateConfig; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.listener.BlockEventListener; -import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.listener.EntityEventListener; import net.knarcraft.stargate.listener.PlayerEventListener; import net.knarcraft.stargate.listener.PluginEventListener; @@ -17,34 +16,23 @@ import net.knarcraft.stargate.listener.PortalEventListener; import net.knarcraft.stargate.listener.TeleportEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; -import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; -import net.knarcraft.stargate.utility.FileHelper; -import net.knarcraft.stargate.utility.PortalFileHelper; -import org.bukkit.Bukkit; import org.bukkit.Server; -import org.bukkit.World; -import org.bukkit.block.Sign; -import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import org.bukkit.plugin.messaging.Messenger; import org.bukkit.scheduler.BukkitScheduler; import java.io.File; -import java.io.IOException; -import java.util.HashSet; import java.util.LinkedList; -import java.util.Map; import java.util.PriorityQueue; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -63,28 +51,11 @@ public class Stargate extends JavaPlugin { private static Logger logger; public static Server server; public static Stargate stargate; - public static LanguageLoader languageLoader; - - private String dataFolderPath; - private static StargateGateConfig stargateGateConfig; - private static EconomyConfig economyConfig; - - //Used for debug - public static boolean debuggingEnabled = false; - public static boolean permissionDebuggingEnabled = false; - - //World names that contain stargates - public static final HashSet managedWorlds = new HashSet<>(); private static String pluginVersion; - private static String portalFolder; - private static String gateFolder; - private static String languageName = "en"; - - private FileConfiguration newConfig; - private PluginManager pluginManager; - private static MessageSender messageSender; + private static PluginManager pluginManager; + private static StargateConfig stargateConfig; /** * Empty constructor necessary for Spigot @@ -111,7 +82,7 @@ public class Stargate extends JavaPlugin { * @return

The sender for sending messages to players

*/ public static MessageSender getMessageSender() { - return messageSender; + return stargateConfig.getMessageSender(); } /** @@ -120,16 +91,7 @@ public class Stargate extends JavaPlugin { * @return

The object containing gate configuration values

*/ public static StargateGateConfig getGateConfig() { - return stargateGateConfig; - } - - /** - * Gets the object containing economy config values - * - * @return

The object containing economy config values

- */ - public static EconomyConfig getEconomyConfig() { - return economyConfig; + return stargateConfig.getStargateGateConfig(); } /** @@ -141,15 +103,6 @@ public class Stargate extends JavaPlugin { return pluginVersion; } - /** - * Gets whether portals should be destroyed by explosions - * - * @return

True if portals should be destroyed

- */ - public static boolean destroyedByExplosion() { - return stargateGateConfig.destroyedByExplosion(); - } - /** * Gets the logger used for logging to the console * @@ -166,24 +119,13 @@ public class Stargate extends JavaPlugin { * @param message

A message describing what happened

*/ public static void debug(String route, String message) { - if (Stargate.debuggingEnabled) { + if (Stargate.stargateConfig.isDebuggingEnabled()) { logger.info("[stargate::" + route + "] " + message); } else { logger.log(Level.FINEST, "[stargate::" + route + "] " + message); } } - /** - * Sets a line on a sign, adding the chosen sign color - * - * @param sign

The sign to update

- * @param index

The index of the sign line to change

- * @param text

The new text on the sign

- */ - public static void setLine(Sign sign, int index, String text) { - sign.setLine(index, stargateGateConfig.getSignColor() + text); - } - /** * Gets the folder for saving created portals * @@ -191,8 +133,8 @@ public class Stargate extends JavaPlugin { * * @return

The folder for storing the portal database

*/ - public static String getSaveLocation() { - return portalFolder; + public static String getPortalFolder() { + return stargateConfig.getPortalFolder(); } /** @@ -203,7 +145,7 @@ public class Stargate extends JavaPlugin { * @return

The folder storing gate files

*/ public static String getGateFolder() { - return gateFolder; + return stargateConfig.getGateFolder(); } /** @@ -212,7 +154,7 @@ public class Stargate extends JavaPlugin { * @return

The default network

*/ public static String getDefaultNetwork() { - return stargateGateConfig.getDefaultPortalNetwork(); + return stargateConfig.getStargateGateConfig().getDefaultPortalNetwork(); } /** @@ -224,7 +166,7 @@ public class Stargate extends JavaPlugin { * @return

The full translated string

*/ public static String getString(String name) { - return languageLoader.getString(name); + return stargateConfig.getLanguageLoader().getString(name); } /** @@ -257,11 +199,29 @@ public class Stargate extends JavaPlugin { return input.replace(search, value); } + /** + * Gets this plugin's plugin manager + * + * @return

A plugin manager

+ */ + public static PluginManager getPluginManager() { + return pluginManager; + } + + /** + * Gets the object containing economy config values + * + * @return

The object containing economy config values

+ */ + public static EconomyConfig getEconomyConfig() { + return stargateConfig.getEconomyConfig(); + } + @Override public void onDisable() { PortalHandler.closeAllPortals(); PortalRegistry.clearPortals(); - managedWorlds.clear(); + stargateConfig.clearManagedWorlds(); getServer().getScheduler().cancelTasks(this); } @@ -269,52 +229,35 @@ public class Stargate extends JavaPlugin { public void onEnable() { PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); - newConfig = this.getConfig(); + FileConfiguration newConfig = this.getConfig(); logger = Logger.getLogger("Minecraft"); Stargate.server = getServer(); Stargate.stargate = this; - // Set portalFile and gateFolder to the plugin folder as defaults. - dataFolderPath = getDataFolder().getPath().replaceAll("\\\\", "/"); - portalFolder = dataFolderPath + "/portals/"; - gateFolder = dataFolderPath + "/gates/"; - String languageFolder = dataFolderPath + "/lang/"; + stargateConfig = new StargateConfig(logger); + stargateConfig.finishSetup(); pluginVersion = pluginDescriptionFile.getVersion(); logger.info(pluginDescriptionFile.getName() + " v." + pluginDescriptionFile.getVersion() + " is enabled."); - //Register events before loading gates to stop weird things happening. + //Register events before loading gates to stop weird things from happening. registerEventListeners(); - this.loadConfig(); - - //Enable the required channels for Bungee support - if (stargateGateConfig.enableBungee()) { - startStopBungeeListener(true); - } - - // It is important to load languages here, as they are used during reloadGates() - languageLoader = new LanguageLoader(languageFolder, Stargate.languageName); - messageSender = new MessageSender(languageLoader); - if (debuggingEnabled) { - languageLoader.debug(); - } - - this.createMissingFolders(); - this.loadGates(); - this.loadAllPortals(); - - //Check to see if Economy is loaded yet. - setupVaultEconomy(); - //Run necessary threads + runThreads(); + + this.registerCommands(); + } + + /** + * Starts threads using the bukkit scheduler + */ + private void runThreads() { BukkitScheduler scheduler = getServer().getScheduler(); scheduler.runTaskTimer(this, new StarGateThread(), 0L, 100L); scheduler.runTaskTimer(this, new BlockChangeThread(), 0L, 1L); scheduler.runTaskTimer(this, new ChunkUnloadThread(), 0L, 100L); - - this.registerCommands(); } /** @@ -338,218 +281,11 @@ public class Stargate extends JavaPlugin { private void registerCommands() { PluginCommand stargateCommand = this.getCommand("stargate"); if (stargateCommand != null) { - stargateCommand.setExecutor(new CommandStarGate(this)); + stargateCommand.setExecutor(new CommandStarGate()); stargateCommand.setTabCompleter(new StarGateTabCompleter()); } } - /** - * Loads all config values - */ - public void loadConfig() { - this.reloadConfig(); - newConfig = this.getConfig(); - - boolean isMigrating = false; - if (newConfig.getString("lang") != null || - newConfig.getString("gates.integrity.ignoreEntrance") != null || - newConfig.getString("ignoreEntrance") != null) { - migrateConfig(newConfig); - isMigrating = true; - } - - // Copy default values if required - newConfig.options().copyDefaults(true); - - //Language - languageName = newConfig.getString("language"); - - //Folders - portalFolder = newConfig.getString("folders.portalFolder"); - gateFolder = newConfig.getString("folders.gateFolder"); - - //Debug - debuggingEnabled = newConfig.getBoolean("debugging.debug"); - permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug"); - - //If users have an outdated config, assume they also need to update their default gates - if (isMigrating) { - GateHandler.writeDefaultGatesToFolder(gateFolder); - } - - //Gates - stargateGateConfig = new StargateGateConfig(newConfig); - - //Economy - economyConfig = new EconomyConfig(newConfig); - - this.saveConfig(); - } - - /** - * Changes all configuration values from the old name to the new name - * - * @param newConfig

The config to read from and write to

- */ - private void migrateConfig(FileConfiguration newConfig) { - try { - newConfig.save(dataFolderPath + "/config.old"); - } catch (IOException e) { - Stargate.debug("Stargate::migrateConfig", "Unable to save old backup and do migration"); - e.printStackTrace(); - return; - } - - Map migrationFields; - try { - migrationFields = FileHelper.readKeyValuePairs(FileHelper.getBufferedReaderFromInputStream( - FileHelper.getInputStreamForInternalFile("/config-migrations.txt"))); - } catch (IOException e) { - Stargate.debug("Stargate::migrateConfig", "Unable to load config migration file"); - e.printStackTrace(); - return; - } - - //Replace old config names with the new ones - for (String key : migrationFields.keySet()) { - if (newConfig.contains(key)) { - String newPath = migrationFields.get(key); - Object oldValue = newConfig.get(key); - if (!newPath.trim().isEmpty()) { - newConfig.set(newPath, oldValue); - } - newConfig.set(key, null); - } - } - } - - /** - * Forces all open portals to close - */ - public void closeAllPortals() { - // Close all gates prior to reloading - for (Portal openPortal : openPortalsQueue) { - openPortal.getPortalOpener().closePortal(true); - } - } - - /** - * Loads all available gates - */ - public void loadGates() { - GateHandler.loadGates(gateFolder); - logger.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); - } - - /** - * Loads all portals in all un-managed worlds - */ - public void loadAllPortals() { - for (World world : getServer().getWorlds()) { - if (!managedWorlds.contains(world.getName())) { - PortalFileHelper.loadAllPortals(world); - managedWorlds.add(world.getName()); - } - } - } - - /** - * Creates missing folders - */ - private void createMissingFolders() { - File newPortalDir = new File(portalFolder); - if (!newPortalDir.exists()) { - if (!newPortalDir.mkdirs()) { - logger.severe("Unable to create portal directory"); - } - } - File newFile = new File(portalFolder, getServer().getWorlds().get(0).getName() + ".db"); - if (!newFile.exists() && !newFile.getParentFile().exists()) { - if (!newFile.getParentFile().mkdirs()) { - logger.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); - } - } - } - - /** - * Reloads all portals and files - * - * @param sender

The sender of the reload request

- */ - public void reload(CommandSender sender) { - // Deactivate portals - for (Portal activePortal : activePortalsQueue) { - activePortal.getPortalActivator().deactivate(); - } - // Close portals - closeAllPortals(); - // Clear all lists - activePortalsQueue.clear(); - openPortalsQueue.clear(); - managedWorlds.clear(); - PortalRegistry.clearPortals(); - GateHandler.clearGates(); - - // Store the old Bungee enabled value - boolean oldEnableBungee = stargateGateConfig.enableBungee(); - // Reload data - loadConfig(); - loadGates(); - loadAllPortals(); - languageLoader.setChosenLanguage(languageName); - languageLoader.reload(); - - //Load Economy support if enabled/clear if disabled - reloadEconomy(); - - //Enable or disable the required channels for Bungee support - if (oldEnableBungee != stargateGateConfig.enableBungee()) { - startStopBungeeListener(stargateGateConfig.enableBungee()); - } - - messageSender.sendErrorMessage(sender, "stargate reloaded"); - } - - /** - * Reloads economy by enabling or disabling it as necessary - */ - private void reloadEconomy() { - EconomyConfig economyConfig = Stargate.getEconomyConfig(); - if (economyConfig.isEconomyEnabled() && economyConfig.getEconomy() == null) { - setupVaultEconomy(); - } else if (!economyConfig.isEconomyEnabled()) { - economyConfig.disableEconomy(); - } - } - - /** - * Loads economy from Vault - */ - private void setupVaultEconomy() { - EconomyConfig economyConfig = Stargate.getEconomyConfig(); - if (economyConfig.setupEconomy(pluginManager) && economyConfig.getEconomy() != null) { - String vaultVersion = economyConfig.getVault().getDescription().getVersion(); - logger.info(Stargate.getString("prefix") + Stargate.replaceVars( - Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); - } - } - - /** - * Starts the listener for listening to BungeeCord messages - */ - private void startStopBungeeListener(boolean start) { - Messenger messenger = Bukkit.getMessenger(); - String bungeeChannel = "BungeeCord"; - - if (start) { - messenger.registerOutgoingPluginChannel(this, bungeeChannel); - messenger.registerIncomingPluginChannel(this, bungeeChannel, new BungeeCordListener()); - } else { - messenger.unregisterIncomingPluginChannel(this, bungeeChannel); - messenger.unregisterOutgoingPluginChannel(this, bungeeChannel); - } - } - /** * Gets the chunk unload queue containing chunks to unload * @@ -569,4 +305,12 @@ public class Stargate extends JavaPlugin { chunkUnloadQueue.add(request); } + /** + * Gets the stargate configuration + * + * @return

The stargate configuration

+ */ + public static StargateConfig getStargateConfig() { + return stargateConfig; + } } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 1470f46..1a43ef5 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -22,7 +22,7 @@ public class CommandAbout implements CommandExecutor { "Drakia" + textColor + ", and revived by " + highlightColor + "EpicKnarvik97"); commandSender.sendMessage(textColor + "Go to " + highlightColor + "https://git.knarcraft.net/EpicKnarvik97/Stargate " + textColor + "for the official repository"); - String author = Stargate.languageLoader.getString("author"); + String author = Stargate.getStargateConfig().getLanguageLoader().getString("author"); if (!author.isEmpty()) commandSender.sendMessage(textColor + "Language created by " + highlightColor + 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 index c66da9f..56366f8 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -12,17 +12,6 @@ import org.jetbrains.annotations.NotNull; */ public class CommandReload implements CommandExecutor { - private final 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[] args) { @@ -32,7 +21,7 @@ public class CommandReload implements CommandExecutor { return true; } } - plugin.reload(commandSender); + Stargate.getStargateConfig().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 index 82939ec..98cf8f5 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -15,17 +15,6 @@ import org.jetbrains.annotations.NotNull; */ public class CommandStarGate implements CommandExecutor { - private final 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[] args) { @@ -33,7 +22,7 @@ public class CommandStarGate implements CommandExecutor { if (args[0].equalsIgnoreCase("about")) { return new CommandAbout().onCommand(commandSender, command, s, args); } else if (args[0].equalsIgnoreCase("reload")) { - return new CommandReload(plugin).onCommand(commandSender, command, s, args); + return new CommandReload().onCommand(commandSender, command, s, args); } return false; } else { diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index 25e726a..da5d789 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -34,7 +34,7 @@ public final class LanguageLoader { File tmp = new File(languageFolder, chosenLanguage + ".txt"); if (!tmp.exists()) { - if (tmp.getParentFile().mkdirs() && Stargate.debuggingEnabled) { + if (tmp.getParentFile().mkdirs() && Stargate.getStargateConfig().isDebuggingEnabled()) { Stargate.getConsoleLogger().info("[stargate] Created language folder"); } } @@ -104,7 +104,7 @@ public final class LanguageLoader { if (inputStream == null) { Stargate.getConsoleLogger().info("[stargate] The language " + language + " is not available. Falling " + "back to english, You can add a custom language by creating a new text file in the lang directory."); - if (Stargate.debuggingEnabled) { + if (Stargate.getStargateConfig().isDebuggingEnabled()) { Stargate.getConsoleLogger().info("[stargate] Unable to load /lang/" + language + ".txt"); } return; @@ -217,7 +217,7 @@ public final class LanguageLoader { } strings = FileHelper.readKeyValuePairs(bufferedReader); } catch (Exception e) { - if (Stargate.debuggingEnabled) { + if (Stargate.getStargateConfig().isDebuggingEnabled()) { Stargate.getConsoleLogger().info("[stargate] Unable to load language " + lang); } return null; @@ -226,7 +226,7 @@ public final class LanguageLoader { } /** - * Prints debug output to the console for checking of loading language strings/translations + * Prints debug output to the console for checking loaded language strings/translations */ public void debug() { Set keys = loadedStringTranslations.keySet(); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java new file mode 100644 index 0000000..48c2225 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -0,0 +1,433 @@ +package net.knarcraft.stargate.config; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.listener.BungeeCordListener; +import net.knarcraft.stargate.portal.GateHandler; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.utility.FileHelper; +import net.knarcraft.stargate.utility.PortalFileHelper; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.messaging.Messenger; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.logging.Logger; + +/** + * The stargate config is responsible for keeping track of all configuration values + */ +public final class StargateConfig { + + public final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); + public final ConcurrentLinkedQueue openPortalsQueue = new ConcurrentLinkedQueue<>(); + private final HashSet managedWorlds = new HashSet<>(); + + private StargateGateConfig stargateGateConfig; + private MessageSender messageSender; + public LanguageLoader languageLoader; + private EconomyConfig economyConfig; + private final Logger logger; + + private final String languageFolder; + private final String dataFolderPath; + private String gateFolder; + private String portalFolder; + private String languageName = "en"; + + private boolean debuggingEnabled = false; + private boolean permissionDebuggingEnabled = false; + + /** + * Instantiates a new stargate config + * + * @param logger

The logger to use for logging errors

+ */ + public StargateConfig(Logger logger) { + this.logger = logger; + + dataFolderPath = Stargate.stargate.getDataFolder().getPath().replaceAll("\\\\", "/"); + portalFolder = dataFolderPath + "/portals/"; + gateFolder = dataFolderPath + "/gates/"; + languageFolder = dataFolderPath + "/lang/"; + + this.loadConfig(); + + //Enable the required channels for Bungee support + if (stargateGateConfig.enableBungee()) { + startStopBungeeListener(true); + } + } + + /** + * Finish the config setup by loading languages, gates and portals, and loading economy if vault is loaded + */ + public void finishSetup() { + //Load the translated strings before they're used by loadGates + languageLoader = new LanguageLoader(languageFolder, languageName); + messageSender = new MessageSender(languageLoader); + if (debuggingEnabled) { + languageLoader.debug(); + } + + this.createMissingFolders(); + this.loadGates(); + this.loadAllPortals(); + + //Set up vault economy if vault has been loaded + setupVaultEconomy(); + } + + /** + * Gets whether debugging is enabled + * + * @return

Whether debugging is enabled

+ */ + public boolean isDebuggingEnabled() { + return debuggingEnabled; + } + + /** + * Gets whether permission debugging is enabled + * + * @return

Whether permission debugging is enabled

+ */ + public boolean isPermissionDebuggingEnabled() { + return permissionDebuggingEnabled; + } + + /** + * Gets the object containing economy config values + * + * @return

The object containing economy config values

+ */ + public EconomyConfig getEconomyConfig() { + return this.economyConfig; + } + + /** + * Reloads all portals and files + * + * @param sender

The sender of the reload request

+ */ + public void reload(CommandSender sender) { + //Unload all saved data + unload(); + + //Store the old enable bungee state in case it changes + boolean oldEnableBungee = stargateGateConfig.enableBungee(); + + //Load all data + load(); + + //Enable or disable the required channels for Bungee support + if (oldEnableBungee != stargateGateConfig.enableBungee()) { + startStopBungeeListener(stargateGateConfig.enableBungee()); + } + + messageSender.sendErrorMessage(sender, "stargate reloaded"); + } + + /** + * Un-loads all loaded data + */ + private void unload() { + //De-activate all currently active portals + for (Portal activePortal : activePortalsQueue) { + activePortal.getPortalActivator().deactivate(); + } + //Force all portals to close + closeAllPortals(); + //Clear queues and lists + activePortalsQueue.clear(); + openPortalsQueue.clear(); + managedWorlds.clear(); + + //Clear all loaded portals + PortalRegistry.clearPortals(); + + //Clear all loaded gates + GateHandler.clearGates(); + } + + /** + * Clears the set of managed worlds + */ + public void clearManagedWorlds() { + managedWorlds.clear(); + } + + /** + * Gets a copy of the set of managed worlds + * + * @return

The managed worlds

+ */ + public Set getManagedWorlds() { + return new HashSet<>(managedWorlds); + } + + /** + * Adds a world to the managed worlds + * + * @param worldName

The name of the world to manage

+ */ + public void addManagedWorld(String worldName) { + managedWorlds.add(worldName); + } + + /** + * Removes a world from the managed worlds + * + * @param worldName

The name of the world to stop managing

+ */ + public void removeManagedWorld(String worldName) { + managedWorlds.remove(worldName); + } + + /** + * Loads all necessary data + */ + private void load() { + //Load the config from disk + loadConfig(); + + //Load all gates + loadGates(); + + //Load all portals + loadAllPortals(); + + //Update the language loader in case the loaded language changed + languageLoader.setChosenLanguage(languageName); + languageLoader.reload(); + if (debuggingEnabled) { + languageLoader.debug(); + } + + //Load Economy support if enabled/clear if disabled + reloadEconomy(); + } + + /** + * Starts the listener for listening to BungeeCord messages + */ + private void startStopBungeeListener(boolean start) { + Messenger messenger = Bukkit.getMessenger(); + String bungeeChannel = "BungeeCord"; + + if (start) { + messenger.registerOutgoingPluginChannel(Stargate.stargate, bungeeChannel); + messenger.registerIncomingPluginChannel(Stargate.stargate, bungeeChannel, new BungeeCordListener()); + } else { + messenger.unregisterIncomingPluginChannel(Stargate.stargate, bungeeChannel); + messenger.unregisterOutgoingPluginChannel(Stargate.stargate, bungeeChannel); + } + } + + /** + * Reloads economy by enabling or disabling it as necessary + */ + private void reloadEconomy() { + EconomyConfig economyConfig = getEconomyConfig(); + if (economyConfig.isEconomyEnabled() && economyConfig.getEconomy() == null) { + setupVaultEconomy(); + } else if (!economyConfig.isEconomyEnabled()) { + economyConfig.disableEconomy(); + } + } + + /** + * Forces all open portals to close + */ + public void closeAllPortals() { + for (Portal openPortal : openPortalsQueue) { + openPortal.getPortalOpener().closePortal(true); + } + } + + /** + * Loads all config values + */ + public void loadConfig() { + Stargate.stargate.reloadConfig(); + FileConfiguration newConfig = Stargate.stargate.getConfig(); + + boolean isMigrating = false; + if (newConfig.getString("lang") != null || + newConfig.getString("gates.integrity.ignoreEntrance") != null || + newConfig.getString("ignoreEntrance") != null) { + migrateConfig(newConfig); + isMigrating = true; + } + + //Copy missing default values if any values are missing + newConfig.options().copyDefaults(true); + + //Get the language name from the config + languageName = newConfig.getString("language"); + + //Get important folders from the config + portalFolder = newConfig.getString("folders.portalFolder"); + gateFolder = newConfig.getString("folders.gateFolder"); + + //Get enabled debug settings from the config + debuggingEnabled = newConfig.getBoolean("debugging.debug"); + permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug"); + + //If users have an outdated config, assume they also need to update their default gates + if (isMigrating) { + GateHandler.writeDefaultGatesToFolder(gateFolder); + } + + //Load all gate config values + stargateGateConfig = new StargateGateConfig(newConfig); + + //Load all economy config values + economyConfig = new EconomyConfig(newConfig); + + Stargate.stargate.saveConfig(); + } + + /** + * Gets the object containing configuration values regarding gates + * + * @return

Gets the gate config

+ */ + public StargateGateConfig getStargateGateConfig() { + return stargateGateConfig; + } + + /** + * Loads all available gates + */ + public void loadGates() { + GateHandler.loadGates(gateFolder); + logger.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); + } + + /** + * Changes all configuration values from the old name to the new name + * + * @param newConfig

The config to read from and write to

+ */ + private void migrateConfig(FileConfiguration newConfig) { + //Save the old config just in case something goes wrong + try { + newConfig.save(dataFolderPath + "/config.yml.old"); + } catch (IOException e) { + Stargate.debug("Stargate::migrateConfig", "Unable to save old backup and do migration"); + e.printStackTrace(); + return; + } + + //Read all available config migrations + Map migrationFields; + try { + migrationFields = FileHelper.readKeyValuePairs(FileHelper.getBufferedReaderFromInputStream( + FileHelper.getInputStreamForInternalFile("/config-migrations.txt"))); + } catch (IOException e) { + Stargate.debug("Stargate::migrateConfig", "Unable to load config migration file"); + e.printStackTrace(); + return; + } + + //Replace old config names with the new ones + for (String key : migrationFields.keySet()) { + if (newConfig.contains(key)) { + String newPath = migrationFields.get(key); + Object oldValue = newConfig.get(key); + if (!newPath.trim().isEmpty()) { + newConfig.set(newPath, oldValue); + } + newConfig.set(key, null); + } + } + } + + /** + * Loads economy from Vault + */ + private void setupVaultEconomy() { + EconomyConfig economyConfig = getEconomyConfig(); + if (economyConfig.setupEconomy(Stargate.getPluginManager()) && economyConfig.getEconomy() != null) { + String vaultVersion = economyConfig.getVault().getDescription().getVersion(); + logger.info(Stargate.getString("prefix") + Stargate.replaceVars( + Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + } + } + + /** + * Loads all portals in all un-managed worlds + */ + public void loadAllPortals() { + for (World world : Stargate.stargate.getServer().getWorlds()) { + if (!managedWorlds.contains(world.getName())) { + PortalFileHelper.loadAllPortals(world); + managedWorlds.add(world.getName()); + } + } + } + + /** + * Creates missing folders + */ + private void createMissingFolders() { + File newPortalDir = new File(portalFolder); + if (!newPortalDir.exists()) { + if (!newPortalDir.mkdirs()) { + logger.severe("Unable to create portal directory"); + } + } + File newFile = new File(portalFolder, Stargate.stargate.getServer().getWorlds().get(0).getName() + ".db"); + if (!newFile.exists() && !newFile.getParentFile().exists()) { + if (!newFile.getParentFile().mkdirs()) { + logger.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); + } + } + } + + /** + * Gets the folder all portals are stored in + * + * @return

The portal folder

+ */ + public String getPortalFolder() { + return portalFolder; + } + + /** + * Gets the folder storing gate files + * + *

The returned String path is the full path to the folder

+ * + * @return

The folder storing gate files

+ */ + public String getGateFolder() { + return gateFolder; + } + + /** + * Gets the sender for sending messages to players + * + * @return

The sender for sending messages to players

+ */ + public MessageSender getMessageSender() { + return messageSender; + } + + /** + * Gets the language loader containing translated strings + * + * @return

The language loader

+ */ + public LanguageLoader getLanguageLoader() { + return languageLoader; + } +} diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 82728de..cc181c2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -55,7 +55,7 @@ public class EntityEventListener implements Listener { if (portal == null) { continue; } - if (Stargate.destroyedByExplosion()) { + if (Stargate.getGateConfig().destroyedByExplosion()) { PortalRegistry.unregisterPortal(portal, true); } else { event.setCancelled(true); diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 6ee5ba8..bd4ccc5 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.StargateConfig; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.World; @@ -22,9 +23,10 @@ public class WorldEventListener implements Listener { */ @EventHandler public void onWorldLoad(WorldLoadEvent event) { - if (!Stargate.managedWorlds.contains(event.getWorld().getName()) && + StargateConfig config = Stargate.getStargateConfig(); + if (!config.getManagedWorlds().contains(event.getWorld().getName()) && PortalFileHelper.loadAllPortals(event.getWorld())) { - Stargate.managedWorlds.add(event.getWorld().getName()); + config.addManagedWorld(event.getWorld().getName()); } } @@ -38,8 +40,9 @@ public class WorldEventListener implements Listener { Stargate.debug("onWorldUnload", "Reloading all Stargates"); World world = event.getWorld(); String worldName = world.getName(); - if (Stargate.managedWorlds.contains(worldName)) { - Stargate.managedWorlds.remove(worldName); + StargateConfig config = Stargate.getStargateConfig(); + if (config.getManagedWorlds().contains(worldName)) { + config.removeManagedWorld(worldName); PortalRegistry.clearPortals(world); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index a12b69e..290c1f7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; /** * The portal registry keeps track of all registered portals and all their lookup blocks @@ -263,7 +264,13 @@ public class PortalRegistry { //Register the portal portalLookupByNetwork.get(networkName).put(portalName, portal); - allPortalNetworks.get(networkName).add(portalName); + + if (!allPortalNetworks.get(networkName).contains(portalName)) { + allPortalNetworks.get(networkName).add(portalName); + } else { + Stargate.getConsoleLogger().log(Level.SEVERE, "Portal " + portal + " was registered twice. Check " + + "your portal database for duplicates."); + } } //Register all frame blocks to the lookup list diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 437941c..8f27906 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -50,7 +50,7 @@ public class PortalSignDrawer { for (int index = 0; index <= 3; index++) { sign.setLine(index, ""); } - Stargate.setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.getGateConfig().getSignColor() + + setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.getGateConfig().getSignColor() + portal.getName() + ChatColor.WHITE + "-"); if (!portal.getPortalActivator().isActive()) { @@ -116,14 +116,25 @@ public class PortalSignDrawer { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + + setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + portal.getDestinationName() + (green ? ChatColor.DARK_GREEN : "") + "<"); } else { - Stargate.setLine(sign, signLineIndex, Stargate.getGateConfig().getSignColor() + " >" + + setLine(sign, signLineIndex, Stargate.getGateConfig().getSignColor() + " >" + portal.getDestinationName() + Stargate.getGateConfig().getSignColor() + "< "); } } + /** + * Sets a line on a sign, adding the chosen sign color + * + * @param sign

The sign to update

+ * @param index

The index of the sign line to change

+ * @param text

The new text on the sign

+ */ + public void setLine(Sign sign, int index, String text) { + sign.setLine(index, Stargate.getGateConfig().getSignColor() + text); + } + /** * Draws one network destination on one sign line * @@ -138,10 +149,10 @@ public class PortalSignDrawer { Portal destination = PortalHandler.getByName(destinations.getDestinations().get(destinationIndex), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - Stargate.setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + + setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + destinations.getDestinations().get(destinationIndex)); } else { - Stargate.setLine(sign, signLineIndex, destinations.getDestinations().get(destinationIndex)); + setLine(sign, signLineIndex, destinations.getDestinations().get(destinationIndex)); } } @@ -151,9 +162,9 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawBungeeSign(Sign sign) { - Stargate.setLine(sign, 1, Stargate.getString("bungeeSign")); - Stargate.setLine(sign, 2, ">" + portal.getDestinationName() + "<"); - Stargate.setLine(sign, 3, "[" + portal.getNetwork() + "]"); + setLine(sign, 1, Stargate.getString("bungeeSign")); + setLine(sign, 2, ">" + portal.getDestinationName() + "<"); + setLine(sign, 3, "[" + portal.getNetwork() + "]"); } /** @@ -162,12 +173,12 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawInactiveSign(Sign sign) { - Stargate.setLine(sign, 1, Stargate.getString("signRightClick")); - Stargate.setLine(sign, 2, Stargate.getString("signToUse")); + setLine(sign, 1, Stargate.getString("signRightClick")); + setLine(sign, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { - Stargate.setLine(sign, 3, "(" + portal.getNetwork() + ")"); + setLine(sign, 3, "(" + portal.getNetwork() + ")"); } else { - Stargate.setLine(sign, 3, ""); + setLine(sign, 3, ""); } } @@ -178,20 +189,20 @@ public class PortalSignDrawer { */ private void drawFixedSign(Sign sign) { if (portal.getOptions().isRandom()) { - Stargate.setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); + setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); } else { - Stargate.setLine(sign, 1, ">" + portal.getDestinationName() + "<"); + setLine(sign, 1, ">" + portal.getDestinationName() + "<"); } if (portal.getOptions().isNoNetwork()) { - Stargate.setLine(sign, 2, ""); + setLine(sign, 2, ""); } else { - Stargate.setLine(sign, 2, "(" + portal.getNetwork() + ")"); + setLine(sign, 2, "(" + portal.getNetwork() + ")"); } Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { - Stargate.setLine(sign, 3, Stargate.getString("signDisconnected")); + setLine(sign, 3, Stargate.getString("signDisconnected")); } else { - Stargate.setLine(sign, 3, ""); + setLine(sign, 3, ""); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index ef93713..0b86582 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -126,7 +126,7 @@ public final class PermissionHelper { * @return

True if the player has the permission

*/ public static boolean hasPermission(Player player, String perm) { - if (Stargate.permissionDebuggingEnabled) { + if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); } return player.hasPermission(perm); @@ -144,12 +144,12 @@ public final class PermissionHelper { */ public static boolean hasPermDeep(Player player, String permission) { if (!player.isPermissionSet(permission)) { - if (Stargate.permissionDebuggingEnabled) { + if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPermDeep::SuperPerm", permission + " => true"); } return true; } - if (Stargate.permissionDebuggingEnabled) { + if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPermDeep::SuperPerms", permission + " => " + player.hasPermission(permission)); } return player.hasPermission(permission); diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 2e42767..8858b73 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.portal.PortalLocation; import net.knarcraft.stargate.portal.PortalOptions; import net.knarcraft.stargate.portal.PortalOwner; import net.knarcraft.stargate.portal.PortalRegistry; +import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.block.Sign; @@ -35,8 +36,8 @@ public final class PortalFileHelper { * @param world

The world to save portals for

*/ public static void saveAllPortals(World world) { - Stargate.managedWorlds.add(world.getName()); - String saveFileLocation = Stargate.getSaveLocation() + "/" + world.getName() + ".db"; + Stargate.getStargateConfig().addManagedWorld(world.getName()); + String saveFileLocation = Stargate.getPortalFolder() + "/" + world.getName() + ".db"; try { BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(saveFileLocation, false)); @@ -125,7 +126,7 @@ public final class PortalFileHelper { * @return

True if portals could be loaded

*/ public static boolean loadAllPortals(World world) { - String location = Stargate.getSaveLocation(); + String location = Stargate.getPortalFolder(); File database = new File(location, world.getName() + ".db"); @@ -268,7 +269,7 @@ public final class PortalFileHelper { */ private static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) { Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); - Stargate.setLine(sign, 3, Stargate.getString("signInvalidGate")); + sign.setLine(3, ChatColor.DARK_RED + Stargate.getString("signInvalidGate")); sign.update(); Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + From a100ad3fea384f4b592cdfe94e8076e0db022497 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 22:16:36 +0200 Subject: [PATCH 187/378] Fixes a check which broke all bungee portals --- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index af8f211..d63ad65 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -143,7 +143,7 @@ public class PlayerEventListener implements Listener { Portal destination = entrancePortal.getPortalActivator().getDestination(player); //Catch always open portals without a valid destination to prevent the user for being teleported and denied - if (destination == null) { + if (!entrancePortal.getOptions().isBungee() && destination == null) { return false; } From 3367d4bb769813e2951dee96292bbd01365cbe09 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 23 Oct 2021 22:17:02 +0200 Subject: [PATCH 188/378] Disables the generation of buttons on bungee portals --- src/main/java/net/knarcraft/stargate/portal/PortalCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index fa72fa1..cd5ecba 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -196,7 +196,7 @@ public class PortalCreator { } //Add button if the portal is not always on - if (!portalOptions.isAlwaysOn()) { + if (!portalOptions.isAlwaysOn() && !portalOptions.isBungee()) { generatePortalButton(portalLocation.getTopLeft(), portalLocation.getButtonVector(), portalLocation.getButtonFacing()); } From 822f8fb2b52f809df766da3ad6493d0c3d04e508 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 24 Oct 2021 21:15:43 +0200 Subject: [PATCH 189/378] Changes BungeeCord messages to use UUID instead of player name --- .../stargate/listener/BungeeCordListener.java | 6 +- .../listener/PlayerEventListener.java | 2 +- .../stargate/portal/PortalCreator.java | 4 +- .../stargate/utility/BungeeHelper.java | 73 ++++++++++++------- .../stargate/utility/PermissionHelper.java | 20 ++--- 5 files changed, 62 insertions(+), 43 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java index 2a7d2e1..fba579d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BungeeCordListener.java @@ -9,8 +9,8 @@ import org.jetbrains.annotations.NotNull; * This listener teleports a user if a valid message is received from BungeeCord * *

Specifically, if a string starts with SGBungee encoded to be readable by readUTF followed by - * PlayerName#@#DestinationPortal is received on the BungeeCord channel, this listener will teleport the player to the - * destination portal.

+ * [PlayerUUID]delimiter[DestinationPortal] is received on the BungeeCord channel, this listener will teleport the + * player to the destination portal.

*/ public class BungeeCordListener implements PluginMessageListener { @@ -24,7 +24,7 @@ public class BungeeCordListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, byte[] message) { //Ignore plugin messages if some other plugin message is received - if (!channel.equals("BungeeCord")) { + if (!channel.equals(BungeeHelper.getBungeeChannel())) { return; } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index d63ad65..4ba8599 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -48,7 +48,7 @@ public class PlayerEventListener implements Listener { Player player = event.getPlayer(); //Check if the player is waiting to be teleported to a stargate - String destination = BungeeHelper.removeFromQueue(player.getName()); + String destination = BungeeHelper.removeFromQueue(player.getUniqueId()); if (destination == null) { return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index cd5ecba..0714e2a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -110,7 +110,7 @@ public class PortalCreator { //Check if the player can create portals on this network. If not, create a personal portal if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); - if (PermissionHelper.canCreatePersonalGate(player)) { + if (PermissionHelper.canCreatePersonalPortal(player)) { network = player.getName(); if (network.length() > 11) { network = network.substring(0, 11); @@ -127,7 +127,7 @@ public class PortalCreator { //Check if the player can create this gate layout String gateName = gate.getFilename(); gateName = gateName.substring(0, gateName.indexOf('.')); - if (!deny && !PermissionHelper.canCreateGate(player, gateName)) { + if (!deny && !PermissionHelper.canCreatePortal(player, gateName)) { Stargate.debug("createPortal", "Player does not have access to gate layout"); deny = true; denyMessage = Stargate.getString("createGateDeny"); diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index e0040a8..18577e8 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -13,6 +13,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.UUID; /** * This class contains helpful functions to help with sending and receiving BungeeCord plugin messages @@ -22,12 +23,21 @@ public final class BungeeHelper { private final static String bungeeSubChannel = "SGBungee"; private final static String bungeeChannel = "BungeeCord"; private final static String teleportMessageDelimiter = "#@#"; - private final static Map bungeeQueue = new HashMap<>(); + private final static Map bungeeQueue = new HashMap<>(); private BungeeHelper() { } + /** + * Get the plugin message channel use for BungeeCord messages + * + * @return

The bungee plugin channel

+ */ + public static String getBungeeChannel() { + return bungeeChannel; + } + /** * Removes a player from the queue of players teleporting through BungeeCord * @@ -35,38 +45,43 @@ public final class BungeeHelper { * server, it'll be added to this queue. Once the player joins this server, the player should be removed from the * queue and teleported to the destination.

* - * @param playerName

The name of the player to remove

+ * @param playerUUID

The UUID of the player to remove

* @return

The name of the destination portal the player should be teleported to

*/ - public static String removeFromQueue(String playerName) { - return bungeeQueue.remove(playerName.toLowerCase()); + public static String removeFromQueue(UUID playerUUID) { + return bungeeQueue.remove(playerUUID); } /** * Sends a plugin message to BungeeCord allowing the target server to catch it * - * @param player

The player teleporting

+ * @param player

The teleporting player

* @param entrancePortal

The portal the player is teleporting from

* @return

True if the message was successfully sent

*/ public static boolean sendTeleportationMessage(Player player, Portal entrancePortal) { try { - // Build the message, format is #@# - String message = player.getName() + teleportMessageDelimiter + entrancePortal.getDestinationName(); - // Build the message data, sent over the SGBungee BungeeCord channel + //Build the teleportation message, format is delimiter + String message = player.getUniqueId() + teleportMessageDelimiter + entrancePortal.getDestinationName(); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + + //Build the message data and send it over the SGBungee BungeeCord channel dataOutputStream.writeUTF("Forward"); - dataOutputStream.writeUTF(entrancePortal.getNetwork()); // Server - //Specify SGBungee channel/tag + //Send the message to the server defined in the entrance portal's network line + dataOutputStream.writeUTF(entrancePortal.getNetwork()); + //Specify the sub-channel/tag to make it recognizable on arrival dataOutputStream.writeUTF(bungeeSubChannel); - //Length of the message + //Write the length of the message dataOutputStream.writeShort(message.length()); - //The data to send + //Write the actual message dataOutputStream.writeBytes(message); + //Send the plugin message player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { - Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); + Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + "Error sending BungeeCord " + + "teleport packet"); ex.printStackTrace(); return false; } @@ -74,21 +89,23 @@ public final class BungeeHelper { } /** - * Sends the bungee message necessary to change the server + * Sends the bungee message necessary to make a player connect to another server * * @param player

The player to teleport

- * @param entrancePortal

The bungee portal the player teleports from

- * @return

True if able to send the plugin message

+ * @param entrancePortal

The bungee portal the player is teleporting from

+ * @return

True if the plugin message was sent successfully

*/ public static boolean changeServer(Player player, Portal entrancePortal) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + + //Send a connect-message to connect the player to the server defined in the entrance portal's network line dataOutputStream.writeUTF("Connect"); dataOutputStream.writeUTF(entrancePortal.getNetwork()); + //Send the plugin message player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); - byteArrayOutputStream.reset(); } catch (IOException ex) { Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); @@ -102,7 +119,7 @@ public final class BungeeHelper { * Reads a plugin message byte array to a string if it's sent from another stargate plugin * * @param message

The byte array to read

- * @return

The message contained in the byte array or null on failure

+ * @return

The message contained in the byte array, or null on failure

*/ public static String readPluginMessage(byte[] message) { // Get data from message @@ -114,8 +131,12 @@ public final class BungeeHelper { if (!subChannel.equals(bungeeSubChannel)) { return null; } + + //Get the length of the contained message short dataLength = dataInputStream.readShort(); + //Prepare a byte array for the sent message data = new byte[dataLength]; + //Read the message to the prepared array dataInputStream.readFully(data); } catch (IOException ex) { Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + @@ -123,29 +144,27 @@ public final class BungeeHelper { ex.printStackTrace(); return null; } - - // Data should be player name, and destination gate name return new String(data); } /** * Handles the receival of a teleport message * - * @param receivedMessage

The received message

+ * @param receivedMessage

The received teleport message

*/ public static void handleTeleportMessage(String receivedMessage) { + //Get the player id and destination from the message String[] messageParts = receivedMessage.split(teleportMessageDelimiter); - - String playerName = messageParts[0]; + UUID playerUUID = UUID.fromString(messageParts[0]); String destination = messageParts[1]; - // Check if the player is online, if so, teleport, otherwise, queue - Player player = Stargate.server.getPlayer(playerName); + //Check if the player is online, if so, teleport, otherwise, queue + Player player = Stargate.server.getPlayer(playerUUID); if (player == null) { - bungeeQueue.put(playerName.toLowerCase(), destination); + bungeeQueue.put(playerUUID, destination); } else { Portal destinationPortal = PortalHandler.getBungeePortal(destination); - // Specified an invalid gate. For now, we'll just let them connect at their current location + //If teleporting to an invalid portal, let the server decide where the player arrives if (destinationPortal == null) { Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 0b86582..3592b56 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -59,7 +59,7 @@ public final class PermissionHelper { } //Check if the player can use the private gate - if (portal.getOptions().isPrivate() && !PermissionHelper.canPrivate(player, portal)) { + if (portal.getOptions().isPrivate() && !PermissionHelper.canUsePrivatePortal(player, portal)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } @@ -121,15 +121,16 @@ public final class PermissionHelper { * *

This is the same as player.hasPermission(), but this function allows for printing permission debugging info.

* - * @param player

The player to check

- * @param perm

The permission to check

+ * @param player

The player to check

+ * @param permission

The permission to check

* @return

True if the player has the permission

*/ - public static boolean hasPermission(Player player, String perm) { + public static boolean hasPermission(Player player, String permission) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { - Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", perm + " => " + player.hasPermission(perm)); + Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", permission + " => " + + player.hasPermission(permission)); } - return player.hasPermission(perm); + return player.hasPermission(permission); } /** @@ -264,7 +265,7 @@ public final class PermissionHelper { * @param portal

The private portal used

* @return

True if the player is allowed to use the portal

*/ - public static boolean canPrivate(Player player, Portal portal) { + public static boolean canUsePrivatePortal(Player player, Portal portal) { //Check if the player is the owner of the gate if (portal.isOwner(player)) { return true; @@ -308,7 +309,6 @@ public final class PermissionHelper { } //Check for this specific network return hasPermission(player, "stargate.create.network." + network); - } /** @@ -317,7 +317,7 @@ public final class PermissionHelper { * @param player

The player trying to create the new gate

* @return

True if the player is allowed

*/ - public static boolean canCreatePersonalGate(Player player) { + public static boolean canCreatePersonalPortal(Player player) { //Check for general create if (hasPermission(player, "stargate.create")) { return true; @@ -333,7 +333,7 @@ public final class PermissionHelper { * @param gate

The gate type of the new portal

* @return

True if the player is allowed to create a portal with the given gate layout

*/ - public static boolean canCreateGate(Player player, String gate) { + public static boolean canCreatePortal(Player player, String gate) { //Check for general create if (hasPermission(player, "stargate.create")) { return true; From 669767ef89deae6c44307e9d3af3c8561a9a0680 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 24 Oct 2021 22:48:13 +0200 Subject: [PATCH 190/378] Renames RelativeBlockVector's right, depth and distance to right, down and out respectively --- .../stargate/container/BlockLocation.java | 14 ++--- .../container/RelativeBlockVector.java | 53 ++++++++++--------- .../net/knarcraft/stargate/portal/Gate.java | 2 +- .../stargate/portal/PortalCreator.java | 2 +- .../knarcraft/stargate/portal/Teleporter.java | 2 +- .../stargate/utility/DirectionHelper.java | 52 ++++++++++-------- .../stargate/RelativeBlockVectorTest.java | 4 +- .../stargate/container/BlockLocationTest.java | 8 +-- .../container/RelativeBlockVectorTest.java | 16 +++--- 9 files changed, 82 insertions(+), 71 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index 1f552fb..bb8b533 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -86,29 +86,29 @@ public class BlockLocation extends Location { * Gets a location relative to this block location * * @param relativeVector

The relative block vector describing the relative location

- * @param yaw

The yaw pointing outwards from a portal (in the relative vector's distance direction)

+ * @param yaw

The yaw pointing outwards from a portal (in the relative vector's out direction)

* @return

A location relative to this location

*/ public BlockLocation getRelativeLocation(RelativeBlockVector relativeVector, double yaw) { Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(relativeVector.getRight(), - relativeVector.getDepth(), relativeVector.getDistance(), yaw); + relativeVector.getDown(), relativeVector.getOut(), yaw); return makeRelativeBlockLocation(realVector.getBlockX(), realVector.getBlockY(), realVector.getBlockZ()); } /** * Makes a location relative to the current location according to given parameters * - *

The distance goes in the direction of the yaw. Right goes in the direction of (yaw - 90) degrees. + *

Out goes in the direction of the yaw. Right goes in the direction of (yaw - 90) degrees. * Depth goes downwards following the -y direction.

* * @param right

The amount of blocks to go right when looking towards a portal

- * @param depth

The amount of blocks to go downwards when looking towards a portal

- * @param distance

The amount of blocks to go outwards when looking towards a portal

+ * @param down

The amount of blocks to go downwards when looking towards a portal

+ * @param out

The amount of blocks to go outwards when looking towards a portal

* @param portalYaw

The yaw when looking out from the portal

* @return A new location relative to this block location */ - public Location getRelativeLocation(double right, double depth, double distance, float portalYaw) { - Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(right, depth, distance, portalYaw); + public Location getRelativeLocation(double right, double down, double out, float portalYaw) { + Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(right, down, out, portalYaw); return makeRelativeLocation(0.5 + realVector.getBlockX(), realVector.getBlockY(), 0.5 + realVector.getBlockZ(), portalYaw); } diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 30b23de..932ee84 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -5,28 +5,33 @@ package net.knarcraft.stargate.container; * *

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 (top-left when looking at the side with the sign). 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.

+ * from the top-left corner towards the top-right corner. Down is the distance from the top-left corner towards the + * bottom-left corner. Out is the distance outward from the gate.

*/ public class RelativeBlockVector { private final int right; - private final int depth; - private final int distance; + private final int down; + private final int out; - public enum Property {RIGHT, DEPTH, DISTANCE} + public enum Property {RIGHT, DOWN, OUT} /** * Instantiates a new relative block vector * - * @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

+ *

Relative block vectors start from a top-left corner. A yaw is used to orient a relative block vector in the + * "real world". + * In terms of a gate layout, the origin is 0,0. Right is towards the end of the line. Down is to the + * next line. Out is towards the observer.

+ * + * @param right

The distance rightward relative to the origin

+ * @param down

The distance downward relative to the origin

+ * @param out

The distance outward relative to the origin

*/ - public RelativeBlockVector(int right, int depth, int distance) { + public RelativeBlockVector(int right, int down, int out) { this.right = right; - this.depth = depth; - this.distance = distance; + this.down = down; + this.out = out; } /** @@ -39,11 +44,11 @@ public class RelativeBlockVector { public RelativeBlockVector addToVector(Property propertyToAddTo, int valueToAdd) { switch (propertyToAddTo) { case RIGHT: - return new RelativeBlockVector(this.right + valueToAdd, this.depth, this.distance); - case DEPTH: - return new RelativeBlockVector(this.right, this.depth + valueToAdd, this.distance); - case DISTANCE: - return new RelativeBlockVector(this.right, this.depth, this.distance + valueToAdd); + return new RelativeBlockVector(this.right + valueToAdd, this.down, this.out); + case DOWN: + return new RelativeBlockVector(this.right, this.down + valueToAdd, this.out); + case OUT: + return new RelativeBlockVector(this.right, this.down, this.out + valueToAdd); default: throw new IllegalArgumentException("Invalid relative block vector property given"); } @@ -55,7 +60,7 @@ public class RelativeBlockVector { * @return

This vector, but inverted

*/ public RelativeBlockVector invert() { - return new RelativeBlockVector(-this.right, -this.depth, -this.distance); + return new RelativeBlockVector(-this.right, -this.down, -this.out); } /** @@ -72,8 +77,8 @@ public class RelativeBlockVector { * * @return

The distance downward relative to the origin

*/ - public int getDepth() { - return depth; + public int getDown() { + return down; } /** @@ -81,13 +86,13 @@ public class RelativeBlockVector { * * @return

The distance outward relative to the origin

*/ - public int getDistance() { - return distance; + public int getOut() { + return out; } @Override public String toString() { - return String.format("(right = %d, depth = %d, distance = %d)", right, depth, distance); + return String.format("(right = %d, down = %d, out = %d)", right, down, out); } @Override @@ -99,8 +104,8 @@ public class RelativeBlockVector { return false; } RelativeBlockVector otherVector = (RelativeBlockVector) other; - return this.right == otherVector.right && this.depth == otherVector.depth && - this.distance == otherVector.distance; + return this.right == otherVector.right && this.down == otherVector.down && + this.out == otherVector.out; } } diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 31b36c1..0d0c312 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -189,7 +189,7 @@ public class Gate { Map characterMaterialMap = new HashMap<>(this.characterMaterialMap); for (RelativeBlockVector borderVector : layout.getBorder()) { int rowIndex = borderVector.getRight(); - int lineIndex = borderVector.getDepth(); + int lineIndex = borderVector.getDown(); Character key = layout.getLayout()[lineIndex][rowIndex]; Material materialInLayout = characterMaterialMap.get(key); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 0714e2a..e5c06e7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -276,7 +276,7 @@ public class PortalCreator { BlockFace buttonFacing) { //Go one block outwards to find the button's location rather than the control block's location BlockLocation button = topLeft.getRelativeLocation(buttonVector.addToVector( - RelativeBlockVector.Property.DISTANCE, 1), portal.getYaw()); + RelativeBlockVector.Property.OUT, 1), portal.getYaw()); Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); buttonData.setFacing(buttonFacing); diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index f4c8040..683fc04 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -146,7 +146,7 @@ public abstract class Teleporter { RelativeBlockVector openingEdge = relativeExit; do { RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, - openingEdge.getDepth(), openingEdge.getDistance()); + openingEdge.getDown(), openingEdge.getOut()); if (portal.getGate().getLayout().getExits().contains(possibleOpening)) { openingEdge = possibleOpening; } else { diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 5564633..3229c6d 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -5,7 +5,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; /** - * This class helps with direction-dependent calculations + * This class helps with direction-related calculations */ public final class DirectionHelper { @@ -17,11 +17,12 @@ public final class DirectionHelper { * Gets a yaw by comparing two locations * *

The yaw here is the direction an observer a the first location has to look to face the second location. - * The yaw is only meant to be calculated for locations with equal x or equal z.

+ * The yaw is only meant to be calculated for locations where both have either the same x value or the same z value. + * Equal locations, or locations with equal x and equal z will throw an exception.

* * @param location1

The first location, which works as the origin

- * @param location2

The second location, which the yaw will point at

- * @return

The yaw

+ * @param location2

The second location, which the yaw will point towards

+ * @return

The yaw pointing from the first location to the second location

*/ public static float getYawFromLocationDifference(Location location1, Location location2) { Location difference = location1.clone().subtract(location2.clone()); @@ -38,9 +39,11 @@ public final class DirectionHelper { } /** - * Gets a block face given a yaw + * Gets a block face given a yaw value * - * @param yaw

The yaw to use

+ *

The supplied yaw must be a value such that (yaw mod 90) = 0. If not, an exception is thrown.

+ * + * @param yaw

The yaw value to convert

* @return

The block face the yaw corresponds to

*/ public static BlockFace getBlockFaceFromYaw(double yaw) { @@ -56,15 +59,15 @@ public final class DirectionHelper { } else if (yaw == 270) { return BlockFace.EAST; } else { - throw new IllegalArgumentException("Invalid yaw given"); + throw new IllegalArgumentException("Invalid yaw given. Yaw must be divisible by 90."); } } /** * Gets a direction vector given a yaw * - * @param yaw

The yaw to use

- * @return

The direction vector of the yaw

+ * @param yaw

The yaw to convert to a direction vector

+ * @return

The direction vector pointing in the same direction as the yaw

*/ public static Vector getDirectionVectorFromYaw(double yaw) { //Make sure the yaw is between 0 and 360 @@ -84,37 +87,40 @@ public final class DirectionHelper { } /** - * Moves a location relatively + * Moves a location by the given amounts * - * @param location

The location to move

- * @param right

The amount to go right (When looking at the front of a portal)

- * @param depth

The amount to go downward (When looking at the front of a portal)

- * @param distance

The amount to go outward (When looking a the front of a portal)

+ *

The right, down and out work the same as for the relative block vector. Looking a the front of a portal, + * right goes rightwards, down goes downwards and out goes towards the observer.

+ * + * @param location

The location to start at

+ * @param right

The amount to go right

+ * @param down

The amount to go downward

+ * @param out

The amount to go outward

* @param yaw

The yaw when looking directly outwards from a portal

* @return

A location relative to the given location

*/ - public static Location moveLocation(Location location, double right, double depth, double distance, double yaw) { - return location.add(getCoordinateVectorFromRelativeVector(right, depth, distance, yaw)); + public static Location moveLocation(Location location, double right, double down, double out, double yaw) { + return location.add(getCoordinateVectorFromRelativeVector(right, down, out, yaw)); } /** * Gets a vector in Minecraft's normal X,Y,Z-space from a relative block vector * - * @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 yaw

The yaw when looking directly outwards from a portal

+ * @param right

The amount of rightward steps from the top-left origin

+ * @param down

The amount of downward steps from the top-left origin

+ * @param out

The distance outward from the top-left origin

+ * @param yaw

The yaw when looking directly outwards from a portal

* @return

A normal vector

*/ - public static Vector getCoordinateVectorFromRelativeVector(double right, double depth, double distance, double yaw) { + public static Vector getCoordinateVectorFromRelativeVector(double right, double down, double out, double yaw) { Vector distanceVector = DirectionHelper.getDirectionVectorFromYaw(yaw); - distanceVector.multiply(distance); + distanceVector.multiply(out); Vector rightVector = DirectionHelper.getDirectionVectorFromYaw(yaw - 90); rightVector.multiply(right); Vector depthVector = new Vector(0, -1, 0); - depthVector.multiply(depth); + depthVector.multiply(down); return distanceVector.add(rightVector).add(depthVector); } diff --git a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java index 8310474..f75aefe 100644 --- a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java +++ b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java @@ -12,8 +12,8 @@ public class RelativeBlockVectorTest { public void getTest() { RelativeBlockVector relativeBlockVector = new RelativeBlockVector(56, 44, 23); assertEquals(56, relativeBlockVector.getRight()); - assertEquals(44, relativeBlockVector.getDepth()); - assertEquals(23, relativeBlockVector.getDistance()); + assertEquals(44, relativeBlockVector.getDown()); + assertEquals(23, relativeBlockVector.getOut()); } @Test diff --git a/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java b/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java index c3cd916..520627a 100644 --- a/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java +++ b/src/test/java/net/knarcraft/stargate/container/BlockLocationTest.java @@ -27,22 +27,22 @@ public class BlockLocationTest { RelativeBlockVector relativeBlockVector = new RelativeBlockVector(2, 1, 3); BlockLocation relativeLocation1 = startLocation.getRelativeLocation(relativeBlockVector, 0); - //With yaw = 0, going right goes in the x direction, and distance goes in the z direction, while y is decremented + //With yaw = 0, going right goes in the x direction, and out goes in the z direction, while y is decremented BlockLocation targetLocation1 = new BlockLocation(world, 9, 2, 9); Assertions.assertEquals(targetLocation1, relativeLocation1); BlockLocation relativeLocation2 = startLocation.getRelativeLocation(relativeBlockVector, 90); - //With yaw = 90, going right goes in the z direction, and distance goes in the -x direction, while y is decremented + //With yaw = 90, going right goes in the z direction, and out goes in the -x direction, while y is decremented BlockLocation targetLocation2 = new BlockLocation(world, 4, 2, 8); Assertions.assertEquals(targetLocation2, relativeLocation2); BlockLocation relativeLocation3 = startLocation.getRelativeLocation(relativeBlockVector, 180); - //With yaw = 180, going right goes in the -x direction, and distance goes in the -z direction, while y is decremented + //With yaw = 180, going right goes in the -x direction, and out goes in the -z direction, while y is decremented BlockLocation targetLocation3 = new BlockLocation(world, 5, 2, 3); Assertions.assertEquals(targetLocation3, relativeLocation3); BlockLocation relativeLocation4 = startLocation.getRelativeLocation(relativeBlockVector, 270); - //With yaw = 270, going right goes in the -z direction, and distance goes in the x direction, while y is decremented + //With yaw = 270, going right goes in the -z direction, and out goes in the x direction, while y is decremented BlockLocation targetLocation4 = new BlockLocation(world, 10, 2, 4); Assertions.assertEquals(targetLocation4, relativeLocation4); } diff --git a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java index 54613f1..8259b37 100644 --- a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java +++ b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java @@ -8,21 +8,21 @@ public class RelativeBlockVectorTest { @Test public void addToVectorTest() { int right = 5; - int depth = 5; - int distance = 3; + int down = 5; + int out = 3; - RelativeBlockVector relativeBlockVector = new RelativeBlockVector(right, depth, distance); + RelativeBlockVector relativeBlockVector = new RelativeBlockVector(right, down, out); for (int i = 0; i < 1000; i++) { int randomValue = getRandomNumber(); RelativeBlockVector newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.RIGHT, randomValue); - Assertions.assertEquals(new RelativeBlockVector(right + randomValue, depth, distance), newVector); + Assertions.assertEquals(new RelativeBlockVector(right + randomValue, down, out), newVector); - newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.DISTANCE, randomValue); - Assertions.assertEquals(new RelativeBlockVector(right, depth, distance + randomValue), newVector); + newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.OUT, randomValue); + Assertions.assertEquals(new RelativeBlockVector(right, down, out + randomValue), newVector); - newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.DEPTH, randomValue); - Assertions.assertEquals(new RelativeBlockVector(right, depth + randomValue, distance), newVector); + newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.DOWN, randomValue); + Assertions.assertEquals(new RelativeBlockVector(right, down + randomValue, out), newVector); } } From eaf759601479e332f4c1e5dca08d03bb96831b17 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 26 Oct 2021 12:51:05 +0200 Subject: [PATCH 191/378] Adds information about the new default gates to the Building a gate section --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dacb2c0..91bffb3 100644 --- a/README.md +++ b/README.md @@ -73,12 +73,15 @@ stargate.admin -- Op ## Building a gate: -This is the default gate configuration. See the Custom Gate Layout section on how to change this. +There are currently three default gate configurations. They all use the same structure as a standard nether portal. One +gate is using obsidian blocks, one is using end bricks and the last uses sea lanterns. Only the sea lantern one can be +used underwater. You must put a sign on one of the blocks in the middle of the layout to activate the portal (see next +section). See the Custom Gate Layout section to learn how to add custom gates. ``` OO - O O - These are Obsidian blocks. You need 10. - O O - Place a sign on either of these two blocks of Obsidian. + O O - These are Obsidian blocks, End bricks or Sea Lanterns. You need 10. + O O - Place a sign on either of these two middle blocks. O O OO ``` From 1c906528f2451baa0fc957cf90395bf980ae1557 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 26 Oct 2021 15:05:05 +0200 Subject: [PATCH 192/378] Cleans up message logging quite a bit Adds methods to Stargate for easier logging and less redundancy Loads the language loader in two parts to make it available while loading Adds a translated string to the reload-message Uses String.format to make long messages more readable Makes it possible to get strings directly from the backup language to make debugging easier --- .../java/net/knarcraft/stargate/Stargate.java | 53 ++++++++++++++- .../stargate/config/EconomyConfig.java | 6 +- .../stargate/config/LanguageLoader.java | 68 +++++++++++-------- .../stargate/config/StargateConfig.java | 18 ++--- .../stargate/config/StargateGateConfig.java | 5 +- .../stargate/listener/BlockEventListener.java | 3 +- .../listener/PluginEventListener.java | 5 +- .../listener/VehicleEventListener.java | 7 +- .../net/knarcraft/stargate/portal/Gate.java | 3 +- .../stargate/portal/GateHandler.java | 12 ++-- .../stargate/portal/PortalHandler.java | 5 +- .../stargate/portal/PortalRegistry.java | 5 +- .../stargate/portal/PortalSignDrawer.java | 7 +- .../knarcraft/stargate/portal/Teleporter.java | 8 +-- .../stargate/portal/VehicleTeleporter.java | 3 +- .../stargate/utility/BungeeHelper.java | 13 ++-- .../stargate/utility/EconomyHelper.java | 10 ++- .../stargate/utility/GateReader.java | 16 ++--- .../stargate/utility/PortalFileHelper.java | 20 +++--- src/main/resources/lang/en.txt | 1 + src/main/resources/lang/nb-no.txt | 1 + src/main/resources/lang/nn-no.txt | 3 +- 22 files changed, 154 insertions(+), 118 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 1e18ddf..e6298ce 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -120,12 +120,49 @@ public class Stargate extends JavaPlugin { */ public static void debug(String route, String message) { if (Stargate.stargateConfig.isDebuggingEnabled()) { - logger.info("[stargate::" + route + "] " + message); + logger.info("[Stargate::" + route + "] " + message); } else { - logger.log(Level.FINEST, "[stargate::" + route + "] " + message); + logger.log(Level.FINEST, "[Stargate::" + route + "] " + message); } } + /** + * Logs an info message to the console + * + * @param message

The message to log

+ */ + public static void logInfo(String message) { + logger.info(Stargate.getBackupString("prefix") + message); + } + + /** + * Logs a severe error message to the console + * + * @param message

The message to log

+ */ + public static void logSevere(String message) { + log(Level.SEVERE, message); + } + + /** + * Logs a warning message to the console + * + * @param message

The message to log

+ */ + public static void logWarning(String message) { + log(Level.WARNING, message); + } + + /** + * Logs a message to the console + * + * @param severity

The severity of the event triggering the message

+ * @param message

The message to log

+ */ + private static void log(Level severity, String message) { + logger.log(severity, Stargate.getBackupString("prefix") + message); + } + /** * Gets the folder for saving created portals * @@ -169,6 +206,18 @@ public class Stargate extends JavaPlugin { return stargateConfig.getLanguageLoader().getString(name); } + /** + * Gets a backup string given its string key + * + *

The name/key is the string before the equals sign in the language files

+ * + * @param name

The name/key of the string to get

+ * @return

The full string in the backup language (English)

+ */ + public static String getBackupString(String name) { + return stargateConfig.getLanguageLoader().getBackupString(name); + } + /** * Replaces a list of variables in a string in the order they are given * diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 9eeca5e..4afe9b8 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -242,12 +242,10 @@ public final class EconomyConfig { this.vault = vault; return true; } else { - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + - Stargate.getString("ecoLoadError")); + Stargate.logInfo(Stargate.getString("ecoLoadError")); } } else { - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + - Stargate.getString("vaultLoadError")); + Stargate.logInfo(Stargate.getString("vaultLoadError")); } economyEnabled = false; return false; diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index da5d789..f5ca821 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -25,30 +25,27 @@ public final class LanguageLoader { /** * Instantiates a new language loader * + *

This will only load the backup language. Set the chosen language and reload afterwards.

+ * * @param languageFolder

The folder containing the language files

- * @param chosenLanguage

The chosen plugin language

*/ - public LanguageLoader(String languageFolder, String chosenLanguage) { - this.chosenLanguage = chosenLanguage; + public LanguageLoader(String languageFolder) { this.languageFolder = languageFolder; - - File tmp = new File(languageFolder, chosenLanguage + ".txt"); - if (!tmp.exists()) { - if (tmp.getParentFile().mkdirs() && Stargate.getStargateConfig().isDebuggingEnabled()) { - Stargate.getConsoleLogger().info("[stargate] Created language folder"); + File testFile = new File(languageFolder, "en.txt"); + if (!testFile.exists()) { + if (testFile.getParentFile().mkdirs()) { + Stargate.debug("LanguageLoader", "Created language folder"); } } - updateLanguage(chosenLanguage); - loadedStringTranslations = load(chosenLanguage); //Load english as backup language in case the chosen language is missing newly added text strings InputStream inputStream = FileHelper.getInputStreamForInternalFile("/lang/en.txt"); if (inputStream != null) { loadedBackupStrings = load("en", inputStream); } else { loadedBackupStrings = null; - Stargate.getConsoleLogger().severe("[stargate] Error loading backup language. There may be missing " + - "text in-game"); + Stargate.getConsoleLogger().severe("[stargate] Error loading backup language. " + + "There may be missing text in-game"); } } @@ -56,7 +53,7 @@ public final class LanguageLoader { * Reloads languages from the files on disk */ public void reload() { - // This extracts/updates the language as needed + //Extracts/Updates the language as needed updateLanguage(chosenLanguage); loadedStringTranslations = load(chosenLanguage); } @@ -72,7 +69,21 @@ public final class LanguageLoader { if (loadedStringTranslations != null) { value = loadedStringTranslations.get(name); } - if (value == null && loadedBackupStrings != null) { + if (value == null) { + value = getBackupString(name); + } + return value; + } + + /** + * Gets the string to display given its name/key + * + * @param name

The name/key of the string to display

+ * @return

The string in the backup language (English)

+ */ + public String getBackupString(String name) { + String value = null; + if (loadedBackupStrings != null) { value = loadedBackupStrings.get(name); } if (value == null) { @@ -96,17 +107,13 @@ public final class LanguageLoader { * @param language

The language to update

*/ private void updateLanguage(String language) { - // Load the current language file - Map currentLanguageValues = load(language); InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); if (inputStream == null) { - Stargate.getConsoleLogger().info("[stargate] The language " + language + " is not available. Falling " + - "back to english, You can add a custom language by creating a new text file in the lang directory."); - if (Stargate.getStargateConfig().isDebuggingEnabled()) { - Stargate.getConsoleLogger().info("[stargate] Unable to load /lang/" + language + ".txt"); - } + Stargate.logInfo(String.format("The language %s is not available. Falling back to english, You can add a " + + "custom language by creating a new text file in the lang directory.", language)); + Stargate.debug("LanguageLoader::updateLanguage", String.format("Unable to load /lang/%s.txt", language)); return; } @@ -134,7 +141,7 @@ public final class LanguageLoader { //If currentLanguageValues is null; the chosen language has not been used before if (currentLanguageValues == null) { updateLanguageFile(language, internalLanguageValues, null); - Stargate.getConsoleLogger().info("[stargate] Language (" + language + ") has been loaded"); + Stargate.logInfo(String.format("Language (%s) has been loaded", language)); return; } @@ -155,8 +162,7 @@ public final class LanguageLoader { //Update the file itself if (updateNecessary) { updateLanguageFile(language, newLanguageValues, currentLanguageValues); - Stargate.getConsoleLogger().info("[stargate] Your language file (" + language + - ".txt) has been updated"); + Stargate.logInfo(String.format("Your language file (%s.txt) has been updated", language)); } } } @@ -218,7 +224,7 @@ public final class LanguageLoader { strings = FileHelper.readKeyValuePairs(bufferedReader); } catch (Exception e) { if (Stargate.getStargateConfig().isDebuggingEnabled()) { - Stargate.getConsoleLogger().info("[stargate] Unable to load language " + lang); + Stargate.getConsoleLogger().info("[Stargate] Unable to load language " + lang); } return null; } @@ -229,15 +235,17 @@ public final class LanguageLoader { * Prints debug output to the console for checking loaded language strings/translations */ public void debug() { - Set keys = loadedStringTranslations.keySet(); - for (String key : keys) { - Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + - loadedStringTranslations.get(key)); + if (loadedStringTranslations != null) { + Set keys = loadedStringTranslations.keySet(); + for (String key : keys) { + Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + + loadedStringTranslations.get(key)); + } } if (loadedBackupStrings == null) { return; } - keys = loadedBackupStrings.keySet(); + Set keys = loadedBackupStrings.keySet(); for (String key : keys) { Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " + loadedBackupStrings.get(key)); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 48c2225..80da9dc 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -32,11 +32,10 @@ public final class StargateConfig { private StargateGateConfig stargateGateConfig; private MessageSender messageSender; - public LanguageLoader languageLoader; + public final LanguageLoader languageLoader; private EconomyConfig economyConfig; private final Logger logger; - private final String languageFolder; private final String dataFolderPath; private String gateFolder; private String portalFolder; @@ -56,7 +55,7 @@ public final class StargateConfig { dataFolderPath = Stargate.stargate.getDataFolder().getPath().replaceAll("\\\\", "/"); portalFolder = dataFolderPath + "/portals/"; gateFolder = dataFolderPath + "/gates/"; - languageFolder = dataFolderPath + "/lang/"; + languageLoader = new LanguageLoader(dataFolderPath + "/lang/"); this.loadConfig(); @@ -70,8 +69,10 @@ public final class StargateConfig { * Finish the config setup by loading languages, gates and portals, and loading economy if vault is loaded */ public void finishSetup() { - //Load the translated strings before they're used by loadGates - languageLoader = new LanguageLoader(languageFolder, languageName); + //Set the chosen language and reload the language loader + languageLoader.setChosenLanguage(languageName); + languageLoader.reload(); + messageSender = new MessageSender(languageLoader); if (debuggingEnabled) { languageLoader.debug(); @@ -132,7 +133,7 @@ public final class StargateConfig { startStopBungeeListener(stargateGateConfig.enableBungee()); } - messageSender.sendErrorMessage(sender, "stargate reloaded"); + messageSender.sendErrorMessage(sender, languageLoader.getString("reloaded")); } /** @@ -309,7 +310,7 @@ public final class StargateConfig { */ public void loadGates() { GateHandler.loadGates(gateFolder); - logger.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts"); + Stargate.logInfo(String.format("Loaded %s gate layouts", GateHandler.getGateCount())); } /** @@ -358,8 +359,7 @@ public final class StargateConfig { EconomyConfig economyConfig = getEconomyConfig(); if (economyConfig.setupEconomy(Stargate.getPluginManager()) && economyConfig.getEconomy() != null) { String vaultVersion = economyConfig.getVault().getDescription().getVersion(); - logger.info(Stargate.getString("prefix") + Stargate.replaceVars( - Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + Stargate.logInfo(Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 8a39a4b..da38bfc 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -4,8 +4,6 @@ import net.knarcraft.stargate.Stargate; import org.bukkit.ChatColor; import org.bukkit.configuration.file.FileConfiguration; -import static net.knarcraft.stargate.Stargate.getString; - /** * The Stargate gate config keeps track of all global config values related to gates */ @@ -181,8 +179,7 @@ public final class StargateGateConfig { } catch (IllegalArgumentException | NullPointerException ignored) { } } - Stargate.getConsoleLogger().warning(getString("prefix") + - "You have specified an invalid color in your config.yml. Defaulting to BLACK"); + Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK"); this.signColor = ChatColor.BLACK; } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index a74a30f..8d6dbd4 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -115,8 +115,7 @@ public class BlockEventListener implements Listener { if (!PermissionHelper.canDestroyPortal(player, portal)) { denyMessage = Stargate.getString("denyMsg"); deny = true; - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + player.getName() + - " tried to destroy gate"); + Stargate.logInfo(String.format("%s tried to destroy gate", player.getName())); } int cost = Stargate.getEconomyConfig().getDestroyCost(player, portal.getGate()); diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index 1e44b0a..a6e0dba 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -34,8 +34,7 @@ public class PluginEventListener implements Listener { public void onPluginEnable(PluginEnableEvent ignored) { if (Stargate.getEconomyConfig().setupEconomy(stargate.getServer().getPluginManager())) { String vaultVersion = Stargate.getEconomyConfig().getVault().getDescription().getVersion(); - stargate.getLogger().info(Stargate.getString("prefix") + - Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + Stargate.logInfo(Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } } @@ -47,7 +46,7 @@ public class PluginEventListener implements Listener { @EventHandler public void onPluginDisable(PluginDisableEvent event) { if (event.getPlugin().equals(Stargate.getEconomyConfig().getVault())) { - stargate.getLogger().info(Stargate.getString("prefix") + "Vault plugin lost."); + Stargate.logInfo("Vault plugin lost."); } } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index e022b16..6793abc 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -60,16 +60,15 @@ public class VehicleEventListener implements Listener { */ private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { String route = "VehicleEventListener::teleportVehicle"; - String prefix = Stargate.getString("prefix"); if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - Stargate.debug(route, prefix + "Found passenger vehicle"); + Stargate.debug(route, "Found passenger vehicle"); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Stargate.debug(route, prefix + "Found empty vehicle"); + Stargate.debug(route, "Found empty vehicle"); Portal destinationPortal = entrancePortal.getPortalActivator().getDestination(); if (destinationPortal == null) { - Stargate.debug(route, prefix + "Unable to find portal destination"); + Stargate.debug(route, "Unable to find portal destination"); return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/Gate.java index 0d0c312..dd25a9b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/Gate.java @@ -10,7 +10,6 @@ import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Map; -import java.util.logging.Level; /** * A gate describes the physical structure of a stargate @@ -268,7 +267,7 @@ public class Gate { bufferedWriter.close(); } catch (IOException ex) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage()); + Stargate.logSevere(String.format("Could not save Gate %s - %s", filename, ex.getMessage())); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java index 139386f..b7a4eb0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/GateHandler.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; -import java.util.logging.Level; import static net.knarcraft.stargate.utility.GateReader.generateLayoutMatrix; import static net.knarcraft.stargate.utility.GateReader.readGateConfig; @@ -105,8 +104,8 @@ public class GateHandler { private static Gate loadGate(File file) { try (Scanner scanner = new Scanner(file)) { return loadGate(file.getName(), file.getParent(), scanner); - } catch (Exception ex) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); + } catch (Exception exception) { + Stargate.logSevere(String.format("Could not load Gate %s - %s", file.getName(), exception.getMessage())); return null; } } @@ -190,14 +189,13 @@ public class GateHandler { */ private static boolean validateGate(Gate gate, String fileName) { if (gate.getLayout().getControls().length != 2) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + - " - Gates must have exactly 2 control points."); + Stargate.logSevere(String.format("Could not load Gate %s - Gates must have exactly 2 control points.", + fileName)); return false; } if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + - " - Gate button must be a type of button."); + Stargate.logSevere(String.format("Could not load Gate %s - Gate button must be a type of button.", fileName)); return false; } return true; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 2aca540..8d536b5 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -88,7 +88,6 @@ public class PortalHandler { } //Check if this player can access the dest world if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { - Stargate.getConsoleLogger().info("cannot access world"); continue; } //Visible to this player. @@ -439,14 +438,14 @@ public class PortalHandler { } } PortalRegistry.unregisterPortal(portal, false); - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Destroying stargate at " + portal); + Stargate.logInfo(String.format("Destroying stargate at %s", portal)); } /** * Closes all portals */ public static void closeAllPortals() { - Stargate.getConsoleLogger().info("Closing all stargates."); + Stargate.logInfo("Closing all stargates."); for (Portal portal : PortalRegistry.getAllPortals()) { if (portal != null) { portal.getPortalOpener().closePortal(true); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 290c1f7..da9476a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.logging.Level; /** * The portal registry keeps track of all registered portals and all their lookup blocks @@ -268,8 +267,8 @@ public class PortalRegistry { if (!allPortalNetworks.get(networkName).contains(portalName)) { allPortalNetworks.get(networkName).add(portalName); } else { - Stargate.getConsoleLogger().log(Level.SEVERE, "Portal " + portal + " was registered twice. Check " + - "your portal database for duplicates."); + Stargate.logSevere(String.format("Portal %s was registered twice. Check your portal database for " + + "duplicates.", portal)); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 8f27906..43d51f1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -30,10 +30,9 @@ public class PortalSignDrawer { Block signBlock = portal.getSignLocation().getBlock(); BlockState state = signBlock.getState(); if (!(state instanceof Sign sign)) { - Stargate.getConsoleLogger().warning(Stargate.getString("prefix") + - "Sign block is not a Sign object"); - Stargate.debug("Portal::drawSign", "Block: " + signBlock.getType() + " @ " + - signBlock.getLocation()); + Stargate.logWarning("Sign block is not a Sign object"); + Stargate.debug("Portal::drawSign", String.format("Block: %s @ %s", signBlock.getType(), + signBlock.getLocation())); return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index 683fc04..2e11a83 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -18,7 +18,6 @@ import org.bukkit.scheduler.BukkitScheduler; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; /** * The portal teleporter takes care of common teleportation logic @@ -80,8 +79,8 @@ public abstract class Teleporter { } } } else { - Stargate.getConsoleLogger().log(Level.WARNING, Stargate.getString("prefix") + - "Missing destination point in .gate file " + portal.getGate().getFilename()); + Stargate.logWarning(String.format("Missing destination point in .gate file %s", + portal.getGate().getFilename())); } return adjustExitLocation(traveller, exitLocation); @@ -180,8 +179,7 @@ public abstract class Teleporter { exitLocation.setPitch(traveller.getPitch()); return exitLocation; } else { - Stargate.getConsoleLogger().log(Level.WARNING, Stargate.getString("prefix") + - "Unable to generate exit location"); + Stargate.logWarning("Unable to generate exit location"); } return traveller; } diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java index e637cb1..689cce8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -138,8 +138,7 @@ public class VehicleTeleporter extends Teleporter { Vector newVelocity) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { - Stargate.getConsoleLogger().warning(Stargate.getString("prefix") + - "Unable to get the world to teleport the vehicle to"); + Stargate.logWarning("Unable to get the world to teleport the vehicle to"); return; } //Spawn a new vehicle diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 18577e8..6f62234 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -80,8 +80,7 @@ public final class BungeeHelper { //Send the plugin message player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { - Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + "Error sending BungeeCord " + - "teleport packet"); + Stargate.logSevere("Error sending BungeeCord teleport packet"); ex.printStackTrace(); return false; } @@ -107,8 +106,7 @@ public final class BungeeHelper { //Send the plugin message player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { - Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + - "Error sending BungeeCord connect packet"); + Stargate.logSevere("Error sending BungeeCord connect packet"); ex.printStackTrace(); return false; } @@ -122,7 +120,6 @@ public final class BungeeHelper { * @return

The message contained in the byte array, or null on failure

*/ public static String readPluginMessage(byte[] message) { - // Get data from message byte[] data; try { DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(message)); @@ -139,8 +136,7 @@ public final class BungeeHelper { //Read the message to the prepared array dataInputStream.readFully(data); } catch (IOException ex) { - Stargate.getConsoleLogger().severe(Stargate.getString("prefix") + - "Error receiving BungeeCord message"); + Stargate.logSevere("Error receiving BungeeCord message"); ex.printStackTrace(); return null; } @@ -166,8 +162,7 @@ public final class BungeeHelper { Portal destinationPortal = PortalHandler.getBungeePortal(destination); //If teleporting to an invalid portal, let the server decide where the player arrives if (destinationPortal == null) { - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Bungee gate " + - destination + " does not exist"); + Stargate.logInfo(String.format("Bungee portal %s does not exist", destination)); return; } new PlayerTeleporter(destinationPortal, player).teleport(destinationPortal, null); diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 627e7ae..880c878 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -28,9 +28,13 @@ public final class EconomyHelper { boolean success; //Try to charge the player. Paying the portal owner is only possible if a UUID is available - if (entrancePortal.getGate().getToOwner()) { - UUID ownerUUID = entrancePortal.getOwner().getUUID(); - success = ownerUUID != null && Stargate.getEconomyConfig().chargePlayerIfNecessary(player, ownerUUID, cost); + UUID ownerUUID = entrancePortal.getOwner().getUUID(); + if (ownerUUID == null) { + Stargate.logWarning(String.format("The owner of the portal %s does not have a UUID and payment to owner " + + "was therefore not possible. Make the owner re-create the portal to fix this.", entrancePortal)); + } + if (entrancePortal.getGate().getToOwner() && ownerUUID != null) { + success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, ownerUUID, cost); } else { success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost); } diff --git a/src/main/java/net/knarcraft/stargate/utility/GateReader.java b/src/main/java/net/knarcraft/stargate/utility/GateReader.java index 77d651c..0334019 100644 --- a/src/main/java/net/knarcraft/stargate/utility/GateReader.java +++ b/src/main/java/net/knarcraft/stargate/utility/GateReader.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; -import java.util.logging.Level; /** * Helper class for reading gate files @@ -54,8 +53,8 @@ public final class GateReader { } } } - } catch (Exception ex) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + " - " + ex.getMessage()); + } catch (Exception exception) { + Stargate.logSevere(String.format("Could not load Gate %s - %s", fileName, exception.getMessage())); return -1; } finally { if (scanner != null) { @@ -90,8 +89,8 @@ public final class GateReader { for (Character symbol : line.toCharArray()) { //Refuse read gate designs with unknown characters if (symbol.equals('?') || (!characterMaterialMap.containsKey(symbol))) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Could not load Gate " + fileName + - " - Unknown symbol '" + symbol + "' in diagram"); + Stargate.logSevere(String.format("Could not load Gate %s - Unknown symbol '%s' in diagram", fileName, + symbol)); return -1; } //Add the read character to the row @@ -148,8 +147,8 @@ public final class GateReader { try { return Integer.parseInt(config.get(key)); } catch (NumberFormatException ex) { - Stargate.getConsoleLogger().log(Level.WARNING, String.format("%s reading %s: %s is not numeric", - ex.getClass().getName(), fileName, key)); + Stargate.logWarning(String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), + fileName, key)); } } @@ -172,8 +171,7 @@ public final class GateReader { if (material != null) { return material; } else { - Stargate.getConsoleLogger().log(Level.WARNING, String.format("Error reading %s: %s is not a material", - fileName, key)); + Stargate.logWarning(String.format("Error reading %s: %s is not a material", fileName, key)); } } return defaultMaterial; diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 8858b73..d9763f2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -19,7 +19,6 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; -import java.util.logging.Level; /** * Helper class for saving and loading portal save files @@ -54,8 +53,7 @@ public final class PortalFileHelper { bufferedWriter.close(); } catch (Exception e) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Exception while writing stargates to " + - saveFileLocation + ": " + e); + Stargate.logSevere(String.format("Exception while writing stargates to %s: %s", saveFileLocation, e)); } } @@ -133,8 +131,7 @@ public final class PortalFileHelper { if (database.exists()) { return loadPortals(world, database); } else { - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "{" + world.getName() + - "} No stargates for world "); + Stargate.logInfo(String.format("{%s} No stargates for world ", world.getName())); } return false; } @@ -160,8 +157,8 @@ public final class PortalFileHelper { doPostLoadTasks(world); return true; } catch (Exception e) { - Stargate.getConsoleLogger().log(Level.SEVERE, "Exception while reading stargates from " + - database.getName() + ": " + lineIndex); + Stargate.logSevere(String.format("Exception while reading stargates from %s: %d", database.getName(), + lineIndex)); e.printStackTrace(); } return false; @@ -185,7 +182,7 @@ public final class PortalFileHelper { //Check if the min. required portal data is present String[] portalData = line.split(":"); if (portalData.length < 8) { - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Invalid line - " + lineIndex); + Stargate.logInfo(String.format("Invalid line - %s", lineIndex)); return; } @@ -208,8 +205,8 @@ public final class PortalFileHelper { int openCount = PortalHandler.openAlwaysOpenPortals(); //Print info about loaded stargates so that admins can see if all stargates loaded - Stargate.getConsoleLogger().info(String.format("%s{%s} Loaded %d stargates with %d set as always-on", - Stargate.getString("prefix"), world.getName(), portalCount, openCount)); + Stargate.logInfo(String.format("{%s} Loaded %d stargates with %d set as always-on", world.getName(), + portalCount, openCount)); //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since for (Portal portal : PortalRegistry.getAllPortals()) { @@ -272,8 +269,7 @@ public final class PortalFileHelper { sign.setLine(3, ChatColor.DARK_RED + Stargate.getString("signInvalidGate")); sign.update(); - Stargate.getConsoleLogger().info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + - " does not exist [" + gateName + "]"); + Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName)); } } diff --git a/src/main/resources/lang/en.txt b/src/main/resources/lang/en.txt index 3d40ae4..82f6c04 100644 --- a/src/main/resources/lang/en.txt +++ b/src/main/resources/lang/en.txt @@ -5,6 +5,7 @@ invalidMsg=Invalid Destination blockMsg=Destination Blocked destEmpty=Destination List Empty denyMsg=Access Denied +reloaded=Stargate Reloaded ecoDeduct=Deducted %cost% ecoRefund=Refunded %cost% diff --git a/src/main/resources/lang/nb-no.txt b/src/main/resources/lang/nb-no.txt index 72b9320..87907c6 100644 --- a/src/main/resources/lang/nb-no.txt +++ b/src/main/resources/lang/nb-no.txt @@ -6,6 +6,7 @@ invalidMsg=Ugyldig Destinasjon blockMsg=Destinasjon Blokkert destEmpty=Destinasjonslisten Er Tom denyMsg=Tilgang Avslรฅtt +reloaded=Stjerneport Ble Lastet Inn Pรฅ Nytt ecoDeduct=Fratrekk %cost% ecoRefund=Refundert %cost% diff --git a/src/main/resources/lang/nn-no.txt b/src/main/resources/lang/nn-no.txt index 98e981b..ff0b01f 100644 --- a/src/main/resources/lang/nn-no.txt +++ b/src/main/resources/lang/nn-no.txt @@ -1,11 +1,12 @@ author=EpicKnarvik97 -prefix=[Stjerneport] +prefix=[Stjerneport] teleportMsg=Teleporterte destroyMsg=Port ร˜ydelagd invalidMsg=Ugyldig Destinasjon blockMsg=Destinasjon Blokkert destEmpty=Destinasjonslista Er Tom denyMsg=Tilgang Avslรฅtt +reloaded=Stjerneport Vart Lasta Inn Pรฅ Nytt ecoDeduct=Frรฅtrekk %cost% ecoRefund=Refundert %cost% From 5c730eb6139b80f69d255b93306047c89437150e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 26 Oct 2021 16:22:20 +0200 Subject: [PATCH 193/378] Fixes some portal closing bugs, a NullPointerException and a typo Fixes a typo in nn-no Fixes a bug causing always-on portals not to be closed properly Fixes a possible NullPointerException in onEntityPortalEnter Waits for block change request on reload which makes it possible to change the open-material with just a reload --- .../stargate/config/StargateConfig.java | 21 +++++++-- .../listener/PortalEventListener.java | 3 ++ .../stargate/portal/PortalOpener.java | 2 +- .../stargate/thread/BlockChangeThread.java | 43 +++++++++++-------- .../stargate/utility/PermissionHelper.java | 10 ++--- src/main/resources/lang/nn-no.txt | 2 +- 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 80da9dc..5ec3ee9 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -1,10 +1,13 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.listener.BungeeCordListener; import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.utility.FileHelper; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; @@ -121,7 +124,15 @@ public final class StargateConfig { public void reload(CommandSender sender) { //Unload all saved data unload(); - + + //Perform all block change requests to prevent mismatch if a gate's open-material changes. Changing the + // closed-material still requires a restart. + BlockChangeRequest firstElement = Stargate.blockChangeRequestQueue.peek(); + while (firstElement != null) { + BlockChangeThread.pollQueue(); + firstElement = Stargate.blockChangeRequestQueue.peek(); + } + //Store the old enable bungee state in case it changes boolean oldEnableBungee = stargateGateConfig.enableBungee(); @@ -145,7 +156,9 @@ public final class StargateConfig { activePortal.getPortalActivator().deactivate(); } //Force all portals to close - closeAllPortals(); + closeAllOpenPortals(); + PortalHandler.closeAllPortals(); + //Clear queues and lists activePortalsQueue.clear(); openPortalsQueue.clear(); @@ -247,9 +260,9 @@ public final class StargateConfig { /** * Forces all open portals to close */ - public void closeAllPortals() { + public void closeAllOpenPortals() { for (Portal openPortal : openPortalsQueue) { - openPortal.getPortalOpener().closePortal(true); + openPortal.getPortalOpener().closePortal(false); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index fd26668..d739e2c 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -60,6 +60,9 @@ public class PortalEventListener implements Listener { if (entity instanceof Player player && location.getBlock().getType() == Material.END_PORTAL && world != null && world.getEnvironment() == World.Environment.THE_END) { Portal portal = PortalHandler.getByAdjacentEntrance(location); + if (portal == null) { + return; + } //Remove any old player teleportations in case weird things happen playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player)); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 995479a..9dd3612 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -146,7 +146,7 @@ public class PortalOpener { */ public void closePortal(boolean force) { //No need to close a portal which is already closed - if (!isOpen) { + if (!isOpen()) { return; } diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index 985ba5a..27f75b4 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -21,24 +21,31 @@ public class BlockChangeThread implements Runnable { long sTime = System.nanoTime(); //Repeat for at most 0.025 seconds while (System.nanoTime() - sTime < 25000000) { - //Abort if there's no work to be done - BlockChangeRequest blockChangeRequest = Stargate.blockChangeRequestQueue.poll(); - if (blockChangeRequest == null) { - return; - } + pollQueue(); + } + } - //Change the material of the pulled block - Block block = blockChangeRequest.getBlockLocation().getBlock(); - block.setType(blockChangeRequest.getMaterial(), false); + /** + * Polls the block change request queue for any waiting requests + */ + public static void pollQueue() { + //Abort if there's no work to be done + BlockChangeRequest blockChangeRequest = Stargate.blockChangeRequestQueue.poll(); + if (blockChangeRequest == null) { + return; + } - if (blockChangeRequest.getMaterial() == Material.END_GATEWAY && - block.getWorld().getEnvironment() == World.Environment.THE_END) { - //Force a specific location to prevent exit gateway generation - fixEndGatewayGate(block); - } else if (blockChangeRequest.getAxis() != null) { - //If orientation is relevant, adjust the block's orientation - orientBlock(block, blockChangeRequest.getAxis()); - } + //Change the material of the pulled block + Block block = blockChangeRequest.getBlockLocation().getBlock(); + block.setType(blockChangeRequest.getMaterial(), false); + + if (blockChangeRequest.getMaterial() == Material.END_GATEWAY && + block.getWorld().getEnvironment() == World.Environment.THE_END) { + //Force a specific location to prevent exit gateway generation + fixEndGatewayGate(block); + } else if (blockChangeRequest.getAxis() != null) { + //If orientation is relevant, adjust the block's orientation + orientBlock(block, blockChangeRequest.getAxis()); } } @@ -47,7 +54,7 @@ public class BlockChangeThread implements Runnable { * * @param block

The block to fix

*/ - private void fixEndGatewayGate(Block block) { + private static void fixEndGatewayGate(Block block) { EndGateway gateway = (EndGateway) block.getState(); gateway.setExitLocation(block.getLocation()); gateway.setExactTeleport(true); @@ -60,7 +67,7 @@ public class BlockChangeThread implements Runnable { * @param block

The block to orient

* @param axis

The axis to use for orienting the block

*/ - private void orientBlock(Block block, Axis axis) { + private static void orientBlock(Block block, Axis axis) { Orientable orientable = (Orientable) block.getBlockData(); orientable.setAxis(axis); block.setBlockData(orientable); diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 3592b56..64f4dee 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -26,12 +26,12 @@ public final class PermissionHelper { public static void openPortal(Player player, Portal portal) { Portal destination = portal.getPortalActivator().getDestination(); - //Always-open gate -- Do nothing + //Always-open portal -- Do nothing if (portal.getOptions().isAlwaysOn()) { return; } - //Random gate -- Do nothing + //Random portal -- Do nothing if (portal.getOptions().isRandom()) { return; } @@ -42,16 +42,16 @@ public final class PermissionHelper { return; } - //Gate is already open + //Portal is already open if (portal.isOpen()) { - // Close if this player opened the gate + //Close if this player opened the portal if (portal.getActivePlayer() == player) { portal.getPortalOpener().closePortal(false); } return; } - //Gate that someone else is using -- Deny access + //Portal is used by another player -- Deny access if ((!portal.getOptions().isFixed()) && portal.getPortalActivator().isActive() && (portal.getActivePlayer() != player)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); diff --git a/src/main/resources/lang/nn-no.txt b/src/main/resources/lang/nn-no.txt index ff0b01f..4d8c541 100644 --- a/src/main/resources/lang/nn-no.txt +++ b/src/main/resources/lang/nn-no.txt @@ -34,4 +34,4 @@ signDisconnected=Kopla frรฅ bungeeDisabled=BungeeCord stรธtte er slรฅtt av. bungeeDeny=Du har ikkje lรธyve til รฅ opprette BungeeCord portar. bungeeEmpty=BungeeCord portar treng bade ein destinasjon og eit nettverk. -bungeeSign=Teleportar til +bungeeSign=Teleporter til From 3fc0e6963a36e890de87f9148e29e42ec2af2ed5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 27 Oct 2021 20:56:56 +0200 Subject: [PATCH 194/378] Adds tests for the material helper and adds all chest variations as button compatible --- .../stargate/utility/MaterialHelper.java | 3 +- .../stargate/utility/MaterialHelperTest.java | 84 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 285e118..0a84791 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -19,6 +19,7 @@ public final class MaterialHelper { * @return

True if the material is a wall coral

*/ public static boolean isWallCoral(Material material) { + //Unfortunately, there is no tag for dead wall corals, so they need to be checked manually return Tag.WALL_CORALS.isTagged(material) || material.equals(Material.DEAD_BRAIN_CORAL_WALL_FAN) || material.equals(Material.DEAD_BUBBLE_CORAL_WALL_FAN) || @@ -35,7 +36,7 @@ public final class MaterialHelper { */ public static boolean isButtonCompatible(Material material) { return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || Tag.SHULKER_BOXES.isTagged(material) || - material == Material.CHEST; + material == Material.CHEST || material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST; } } diff --git a/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java b/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java new file mode 100644 index 0000000..61687b7 --- /dev/null +++ b/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java @@ -0,0 +1,84 @@ +package net.knarcraft.stargate.utility; + +import be.seeseemelk.mockbukkit.MockBukkit; +import org.bukkit.Material; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class MaterialHelperTest { + + @BeforeAll + public static void setUp() { + MockBukkit.mock(); + } + + @Test + public void isWallCoralTest() { + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_BRAIN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.BRAIN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_BUBBLE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.BUBBLE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_FIRE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.FIRE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_HORN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.HORN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_TUBE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isWallCoral(Material.TUBE_CORAL_WALL_FAN)); + + Assertions.assertFalse(MaterialHelper.isWallCoral(Material.DEAD_TUBE_CORAL)); + Assertions.assertFalse(MaterialHelper.isWallCoral(Material.TUBE_CORAL)); + Assertions.assertFalse(MaterialHelper.isWallCoral(Material.TUBE_CORAL_BLOCK)); + } + + @Test + public void isButtonCompatibleTest() { + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DEAD_BRAIN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.BRAIN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DEAD_BUBBLE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.BUBBLE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DEAD_FIRE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.FIRE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DEAD_HORN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.HORN_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DEAD_TUBE_CORAL_WALL_FAN)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.TUBE_CORAL_WALL_FAN)); + + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.STONE_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.BIRCH_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.ACACIA_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.CRIMSON_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.OAK_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DARK_OAK_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.JUNGLE_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.POLISHED_BLACKSTONE_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.SPRUCE_BUTTON)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.WARPED_BUTTON)); + + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.BLACK_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.RED_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.GREEN_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.BLUE_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.YELLOW_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.CYAN_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.LIME_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.BROWN_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.GRAY_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.LIGHT_BLUE_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.LIGHT_GRAY_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.MAGENTA_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.ORANGE_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.PINK_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.PURPLE_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.WHITE_SHULKER_BOX)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.SHULKER_BOX)); + + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.CHEST)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.ENDER_CHEST)); + Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.TRAPPED_CHEST)); + + //Chek something random to make sure isButtonCompatible is not just "return true;" + Assertions.assertFalse(MaterialHelper.isButtonCompatible(Material.OAK_LOG)); + } + +} From 544384f69bed6afbdecfb20ba30c23e8293830c3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 28 Oct 2021 18:29:33 +0200 Subject: [PATCH 195/378] Cleans up permissions a lot and adds missing permissions to plugin.yml Removes the checking of both parent and child by adding the child permissions to plugin.yml Cleans comments in the PermissionHelper class Renames hasPermDeep to hasPermissionImplicit as I finally understand how it's supposed to work Adds missing unmock() to prevent test errors Adds a ton of permissions which were mentioned in the code, but did not exist in the plugin.yml --- .../java/net/knarcraft/stargate/Stargate.java | 10 +- .../stargate/config/EconomyConfig.java | 6 +- .../stargate/listener/BlockEventListener.java | 1 - .../listener/PlayerEventListener.java | 5 +- .../stargate/utility/EntityHelper.java | 5 +- .../stargate/utility/FileHelper.java | 16 +- .../stargate/utility/PermissionHelper.java | 176 ++++++++---------- src/main/resources/plugin.yml | 142 +++++++++++--- .../stargate/portal/GateLayoutTest.java | 6 + .../stargate/utility/MaterialHelperTest.java | 6 + 10 files changed, 231 insertions(+), 142 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index e6298ce..5a6ad8e 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -119,7 +119,7 @@ public class Stargate extends JavaPlugin { * @param message

A message describing what happened

*/ public static void debug(String route, String message) { - if (Stargate.stargateConfig.isDebuggingEnabled()) { + if (stargateConfig == null || stargateConfig.isDebuggingEnabled()) { logger.info("[Stargate::" + route + "] " + message); } else { logger.log(Level.FINEST, "[Stargate::" + route + "] " + message); @@ -132,7 +132,7 @@ public class Stargate extends JavaPlugin { * @param message

The message to log

*/ public static void logInfo(String message) { - logger.info(Stargate.getBackupString("prefix") + message); + logger.info(getBackupString("prefix") + message); } /** @@ -160,7 +160,7 @@ public class Stargate extends JavaPlugin { * @param message

The message to log

*/ private static void log(Level severity, String message) { - logger.log(severity, Stargate.getBackupString("prefix") + message); + logger.log(severity, getBackupString("prefix") + message); } /** @@ -280,8 +280,8 @@ public class Stargate extends JavaPlugin { pluginManager = getServer().getPluginManager(); FileConfiguration newConfig = this.getConfig(); logger = Logger.getLogger("Minecraft"); - Stargate.server = getServer(); - Stargate.stargate = this; + server = getServer(); + stargate = this; stargateConfig = new StargateConfig(logger); stargateConfig.finishSetup(); diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 4afe9b8..8c6e233 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -292,8 +292,7 @@ public final class EconomyConfig { return 0; } //Player gets free gate use - if (PermissionHelper.hasPermission(player, "stargate.free") || - PermissionHelper.hasPermission(player, "stargate.free.use")) { + if (PermissionHelper.hasPermission(player, "stargate.free.use")) { return 0; } @@ -353,8 +352,7 @@ public final class EconomyConfig { * @return

*/ private boolean isFree(Player player, String permissionNode) { - return !useEconomy() || PermissionHelper.hasPermission(player, "stargate.free") || - PermissionHelper.hasPermission(player, "stargate.free." + permissionNode); + return !useEconomy() || PermissionHelper.hasPermission(player, "stargate.free." + permissionNode); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 8d6dbd4..730632f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -185,7 +185,6 @@ public class BlockEventListener implements Listener { Block block = event.getBlock(); Portal portal = null; - // Handle keeping portal material and buttons around if (block.getType() == Material.NETHER_PORTAL) { portal = PortalHandler.getByEntrance(block); } else if (MaterialHelper.isButtonCompatible(block.getType())) { diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 4ba8599..b0df9ce 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -235,7 +235,7 @@ public class PlayerEventListener implements Listener { private boolean cannotAccessPortal(Player player, Portal portal) { boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); - if (PermissionHelper.cannotAccessPortal(player, portal, deny)) { + if (PermissionHelper.portalAccessDenied(player, portal, deny)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return true; } @@ -255,7 +255,6 @@ public class PlayerEventListener implements Listener { return; } - // Implement right-click to toggle a stargate, gets around spawn protection problem. if (MaterialHelper.isButtonCompatible(block.getType())) { //Prevent a double click caused by a Spigot bug if (clickIsBug(event, block)) { @@ -267,7 +266,7 @@ public class PlayerEventListener implements Listener { return; } - // Cancel item use + //Prevent the held item from being placed event.setUseItemInHand(Event.Result.DENY); event.setUseInteractedBlock(Event.Result.DENY); diff --git a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java index 157eb3c..2888443 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java @@ -14,8 +14,9 @@ public final class EntityHelper { /** * Gets the max size of an entity along its x and z axis * - *

This function gets the ceiling of the max size of an entity, thus calculating the smallest square needed to - * contain the entity.

+ *

This function gets the ceiling of the max size of an entity, thus calculating the smallest box, using whole + * blocks as unit, needed to contain the entity. Assuming n is returned, an (n x n) box is needed to contain the + * entity.

* * @param entity

The entity to get max size for

* @return

The max size of the entity

diff --git a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java index 829b5dc..a893946 100644 --- a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java @@ -25,10 +25,13 @@ public final class FileHelper { } /** - * Gets a buffered reader from a string pointing to a file + * Gets an input stream from a string pointing to an internal file + * + *

This is used for getting an input stream for reading a file contained within the compiled .jar file. The file + * should be in the resources directory, and the file path should start with a forward slash ("/") character.

* * @param file

The file to read

- * @return

A buffered reader reading the file

+ * @return

An input stream for the file

*/ public static InputStream getInputStreamForInternalFile(String file) { return FileHelper.class.getResourceAsStream(file); @@ -47,10 +50,10 @@ public final class FileHelper { } /** - * Gets a buffered reader from an input stream + * Gets a buffered reader given an input stream * * @param inputStream

The input stream to read

- * @return

A buffered reader reading the stream

+ * @return

A buffered reader reading the input stream

*/ public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) { InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); @@ -71,20 +74,19 @@ public final class FileHelper { } /** - * Reads key value pairs from an input stream + * Reads key/value pairs from an input stream * * @param bufferedReader

The buffered reader to read

* @return

A map containing the read pairs

* @throws IOException

If unable to read from the stream

*/ public static Map readKeyValuePairs(BufferedReader bufferedReader) throws IOException { - Map readPairs = new HashMap<>(); String line = bufferedReader.readLine(); boolean firstLine = true; while (line != null) { - // Strip UTF BOM + //Strip UTF BOM from the first line if (firstLine) { line = removeUTF8BOM(line); firstLine = false; diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 64f4dee..47d0e0a 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -26,34 +26,29 @@ public final class PermissionHelper { public static void openPortal(Player player, Portal portal) { Portal destination = portal.getPortalActivator().getDestination(); - //Always-open portal -- Do nothing - if (portal.getOptions().isAlwaysOn()) { + //For an always open portal, no action is necessary + if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee()) { return; } - //Random portal -- Do nothing - if (portal.getOptions().isRandom()) { - return; - } - - //Invalid destination - if ((destination == null) || (destination == portal)) { + //Destination is invalid or the same portal. Send an error message + if (destination == null || destination == portal) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); return; } //Portal is already open if (portal.isOpen()) { - //Close if this player opened the portal + //Close the portal if this player opened the portal if (portal.getActivePlayer() == player) { portal.getPortalOpener().closePortal(false); } return; } - //Portal is used by another player -- Deny access - if ((!portal.getOptions().isFixed()) && portal.getPortalActivator().isActive() && - (portal.getActivePlayer() != player)) { + //Deny access if another player has activated the portal, and it's still in use + if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && + portal.getActivePlayer() != player) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } @@ -64,27 +59,27 @@ public final class PermissionHelper { return; } - //Destination blocked - if ((destination.isOpen()) && (!destination.getOptions().isAlwaysOn())) { + //Destination is currently in use by another player, blocking teleportation + if (destination.isOpen() && !destination.getOptions().isAlwaysOn()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg")); return; } - //Open gate + //Open the portal portal.getPortalOpener().openPortal(player, false); } /** - * Creates a StargateAccessPortal and gives the result + * Creates a StargateAccessEvent and gets the updated deny value * - *

The event is used for other plugins to bypass the permission checks

+ *

The event is used for other plugins to bypass the permission checks.

* * @param player

The player trying to use the portal

* @param portal

The portal the player is trying to use

- * @param deny

Whether the player's access has already been denied by a check

+ * @param deny

Whether the player's access has already been denied by a previous check

* @return

False if the player should be allowed through the portal

*/ - public static boolean cannotAccessPortal(Player player, Portal portal, boolean deny) { + public static boolean portalAccessDenied(Player player, Portal portal, boolean deny) { StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); Stargate.server.getPluginManager().callEvent(event); return event.getDeny(); @@ -95,25 +90,29 @@ public final class PermissionHelper { * * @param player

The player to check

* @param entrancePortal

The portal the user wants to enter

- * @param destination

The portal the user wants to exit

+ * @param destination

The portal the user wants to exit from

* @return

False if the user is allowed to access the portal

*/ public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { boolean deny = false; - // Check if player has access to this server for Bungee gates - if (entrancePortal.getOptions().isBungee() && !PermissionHelper.canAccessServer(player, - entrancePortal.getNetwork())) { - Stargate.debug("cannotAccessPortal", "Cannot access server"); - deny = true; + + if (entrancePortal.getOptions().isBungee()) { + if (!PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { + //If the portal is a bungee portal, and the player cannot access the server, deny + Stargate.debug("cannotAccessPortal", "Cannot access server"); + deny = true; + } } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { + //If the player does not have access to the network, deny Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (!entrancePortal.getOptions().isBungee() && PermissionHelper.cannotAccessWorld(player, - destination.getWorld().getName())) { + } else if (PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { + //If the player does not have access to the portal's world, deny Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } - return cannotAccessPortal(player, entrancePortal, deny); + //Allow other plugins to override whether the player can access the portal + return portalAccessDenied(player, entrancePortal, deny); } /** @@ -127,31 +126,32 @@ public final class PermissionHelper { */ public static boolean hasPermission(Player player, String permission) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { - Stargate.debug("hasPerm::SuperPerm(" + player.getName() + ")", permission + " => " + + Stargate.debug("hasPerm::Permission(" + player.getName() + ")", permission + " => " + player.hasPermission(permission)); } return player.hasPermission(permission); } /** - * Check a deep permission, this will check to see if the permissions is defined for this use + * Check if a player has been given a permission implicitly * - *

If using Permissions it will return the same as hasPerm. If using SuperPerms will return true if the node - * isn't defined, or the value of the node if it is

+ *

This should be run if a player has a parent permission to check for the child permission. It is assumed the + * player has the child permission unless it's explicitly set to false.

* * @param player

The player to check

* @param permission

The permission to check

- * @return

True if the player has the permission or it is not set

+ * @return

True if the player has the permission implicitly or explicitly

*/ - public static boolean hasPermDeep(Player player, String permission) { + public static boolean hasPermissionImplicit(Player player, String permission) { if (!player.isPermissionSet(permission)) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { - Stargate.debug("hasPermDeep::SuperPerm", permission + " => true"); + Stargate.debug("hasPermissionImplicit::Permission", permission + " => implicitly true"); } return true; } if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { - Stargate.debug("hasPermDeep::SuperPerms", permission + " => " + player.hasPermission(permission)); + Stargate.debug("hasPermissionImplicit::Permission", permission + " => " + + player.hasPermission(permission)); } return player.hasPermission(permission); } @@ -164,12 +164,12 @@ public final class PermissionHelper { * @return

False if the player should be allowed to access the world

*/ public static boolean cannotAccessWorld(Player player, String world) { - // Can use all stargate player features or access all worlds - if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.world")) { - // Do a deep check to see if the player lacks this specific world node - return !hasPermDeep(player, "stargate.world." + world); + //The player can access all worlds + if (hasPermission(player, "stargate.world")) { + //Check if the world permission has been explicitly denied + return !hasPermissionImplicit(player, "stargate.world." + world); } - // Can access dest world + //The player can access the destination world return !hasPermission(player, "stargate.world." + world); } @@ -181,10 +181,10 @@ public final class PermissionHelper { * @return

True if the player is denied from accessing the network

*/ public static boolean cannotAccessNetwork(Player player, String network) { - // Can user all stargate player features, or access all networks - if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.network")) { - // Do a deep check to see if the player lacks this specific network node - return !hasPermDeep(player, "stargate.network." + network); + //The player can access all networks + if (hasPermission(player, "stargate.network")) { + //Check if the world permission has been explicitly denied + return !hasPermissionImplicit(player, "stargate.network." + network); } //Check if the player can access this network if (hasPermission(player, "stargate.network." + network)) { @@ -206,12 +206,12 @@ public final class PermissionHelper { * @return

True if the player is allowed to access the given server

*/ public static boolean canAccessServer(Player player, String server) { - //Can user all stargate player features, or access all servers - if (hasPermission(player, "stargate.use") || hasPermission(player, "stargate.servers")) { - //Do a deep check to see if the player lacks this specific server node - return hasPermDeep(player, "stargate.server." + server); + //The player can access all servers + if (hasPermission(player, "stargate.server")) { + //Check if the server permission has been explicitly denied + return hasPermissionImplicit(player, "stargate.server." + server); } - //Can access this server + //The player can access the destination server return hasPermission(player, "stargate.server." + server); } @@ -224,15 +224,15 @@ public final class PermissionHelper { * @return

True if the player can travel for free

*/ public static boolean isFree(Player player, Portal src, Portal dest) { - // This gate is free + //This portal is free if (src.getOptions().isFree()) { return true; } - // Player gets free use - if (hasPermission(player, "stargate.free") || hasPermission(player, "stargate.free.use")) { + //Player can use this portal for free + if (hasPermission(player, "stargate.free.use")) { return true; } - // Don't charge for free destination gates + //Don't charge for free destinations unless specified in the config return dest != null && !Stargate.getEconomyConfig().chargeFreeDestination() && dest.getOptions().isFree(); } @@ -246,15 +246,15 @@ public final class PermissionHelper { * @return

True if the given player can see the given portal

*/ public static boolean canSeePortal(Player player, Portal portal) { - // The gate is not hidden + //The portal is not hidden if (!portal.getOptions().isHidden()) { return true; } - // The player is an admin with the ability to see hidden gates - if (hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.hidden")) { + //The player can see all hidden portals + if (hasPermission(player, "stargate.admin.hidden")) { return true; } - // The player is the owner of the gate + //The player is the owner of the portal return portal.isOwner(player); } @@ -271,7 +271,7 @@ public final class PermissionHelper { return true; } //The player is an admin with the ability to use private gates - return hasPermission(player, "stargate.admin") || hasPermission(player, "stargate.admin.private"); + return hasPermission(player, "stargate.admin.private"); } /** @@ -282,11 +282,6 @@ public final class PermissionHelper { * @return

True if the player is allowed to create a portal with the given option

*/ public static boolean canUseOption(Player player, PortalOption option) { - //Check if the player can use all options - if (hasPermission(player, "stargate.option") || option == PortalOption.BUNGEE) { - return true; - } - //Check if they can use this specific option return hasPermission(player, option.getPermissionString()); } @@ -298,16 +293,12 @@ public final class PermissionHelper { * @return

True if the player is allowed to create the new gate

*/ public static boolean canCreateNetworkGate(Player player, String network) { - //Check for general create - if (hasPermission(player, "stargate.create")) { - return true; - } - //Check for all network create permission + //Check if the player is allowed to create a portal on any network if (hasPermission(player, "stargate.create.network")) { - // Do a deep check to see if the player lacks this specific network node - return hasPermDeep(player, "stargate.create.network." + network); + //Check if the network has been explicitly denied + return hasPermissionImplicit(player, "stargate.create.network." + network); } - //Check for this specific network + //Check if the player is allowed to create on this specific network return hasPermission(player, "stargate.create.network." + network); } @@ -318,11 +309,6 @@ public final class PermissionHelper { * @return

True if the player is allowed

*/ public static boolean canCreatePersonalPortal(Player player) { - //Check for general create - if (hasPermission(player, "stargate.create")) { - return true; - } - //Check for personal return hasPermission(player, "stargate.create.personal"); } @@ -334,16 +320,12 @@ public final class PermissionHelper { * @return

True if the player is allowed to create a portal with the given gate layout

*/ public static boolean canCreatePortal(Player player, String gate) { - //Check for general create - if (hasPermission(player, "stargate.create")) { - return true; - } - //Check for all gate create permissions + //Check if the player is allowed to create all gates if (hasPermission(player, "stargate.create.gate")) { - // Do a deep check to see if the player lacks this specific gate node - return hasPermDeep(player, "stargate.create.gate." + gate); + //Check if the gate type has been explicitly denied + return hasPermissionImplicit(player, "stargate.create.gate." + gate); } - //Check for this specific gate + //Check if the player can create the specific gate type return hasPermission(player, "stargate.create.gate." + gate); } @@ -356,20 +338,22 @@ public final class PermissionHelper { */ public static boolean canDestroyPortal(Player player, Portal portal) { String network = portal.getNetwork(); - //Check for general destroy - if (hasPermission(player, "stargate.destroy")) { - return true; + + //Use a special check for bungee portals + if (portal.getOptions().isBungee()) { + return hasPermission(player, "stargate.admin.bungee"); } - //Check for all network destroy permission + + //Check if the player is allowed to destroy on all networks if (hasPermission(player, "stargate.destroy.network")) { - //Do a deep check to see if the player lacks permission for this network node - return hasPermDeep(player, "stargate.destroy.network." + network); + //Check if the network has been explicitly denied + return hasPermissionImplicit(player, "stargate.destroy.network." + network); } - //Check for this specific network + //Check if the player is allowed to destroy on the network if (hasPermission(player, "stargate.destroy.network." + network)) { return true; } - //Check for personal gate + //Check if personal portal and if the player is allowed to destroy it return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); } @@ -383,12 +367,12 @@ public final class PermissionHelper { * @return

True if the player cannot teleport. False otherwise

*/ public static boolean playerCannotTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) { - // No portal or not open + //No portal or not open if (entrancePortal == null || !entrancePortal.isOpen()) { return true; } - // Not open for this player + //Not open for this player if (!entrancePortal.getPortalOpener().isOpenFor(player)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 39ff56a..dc4eb91 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -15,7 +15,120 @@ commands: usage: / - Used to see stargate info or reload the plugin permissions: stargate.*: - description: Wildcard permission + description: Wildcard permission. Same as stargate.admin + default: op + children: + stargate.admin: true + stargate.reload: + description: Allows reloading the plugin + default: false + stargate.use: + description: Allow use of all stargates linking to any world in any network + default: true + children: + stargate.world: true + stargate.network: true + stargate.server: true + stargate.world: + description: Allow use of stargates in any world + default: false + stargate.network: + description: Allows use of stargates in any network + default: false + stargate.create: + description: Allow creating gates on any network + default: op + children: + stargate.create.personal: true + stargate.create.network: true + stargate.create.gate: true + stargate.create.personal: + description: Allows the creation of a personal stargate if a player is missing permission for the given network + default: false + stargate.create.network: + description: Allows the creation of a stargate on any network + default: false + stargate.create.gate: + description: Allows the creation of a stargate using any gate type + default: false + stargate.destroy: + description: Allows the destruction of all stargates + default: op + children: + stargate.destroy.network: true + stargate.destroy.personal: true + stargate.destroy.network: + description: Allows the destruction of stargates on any network + default: false + stargate.destroy.personal: + description: Allows the destruction of any personal stargates the player has created + default: false + stargate.free: + description: Allow free use/creation/destruction of stargates + default: op + children: + stargate.free.use: true + stargate.free.create: true + stargate.free.destroy: true + stargate.free.use: + description: Allows free usage of all stargates + default: false + stargate.free.create: + description: Allows creating stargates for free + default: false + stargate.free.destroy: + description: Allows destroying stargates for free + default: false + stargate.option: + description: Allows use of all options + default: op + children: + stargate.option.hidden: true + stargate.option.alwayson: true + stargate.option.private: true + stargate.option.free: true + stargate.option.backwards: true + stargate.option.show: true + stargate.option.nonetwork: true + stargate.option.random: true + stargate.option.hidden: + description: Allows the creation of a hidden stargate + default: false + stargate.option.alwayson: + description: Allows the creation of an always open stargate + default: false + stargate.option.private: + description: Allows the creation of a private stargate + default: false + stargate.option.free: + description: Allows the creation of a stargate which is free regardless of any set prices + default: false + stargate.option.backwards: + description: Allows the creation of a stargate where players will exit through the back + default: false + stargate.option.show: + description: Allows the creation of a stargate which is shown on the network, even if always on + default: false + stargate.option.nonetwork: + description: Allows the creation of a stargate with a hidden network name + default: false + stargate.option.random: + description: Allows the creation of a stargate with a random destination + default: false + stargate.admin.hidden: + description: Allows this player to see all hidden stargates + default: false + stargate.admin.private: + description: Allows this player to use all private stargates + default: false + stargate.admin.bungee: + description: Allows the creation and destruction of a stargate between BungeeCord servers + default: false + stargate.server: + description: Allows the creation of a BungeeCord stargate going to any server + default: false + stargate.admin: + description: Allow all features and admin commands default: op children: stargate.use: true @@ -25,26 +138,7 @@ permissions: 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 - stargate.create: - description: Allow creating gates on any network - default: op - stargate.destroy: - description: Allow destruction gates on any network - default: op - stargate.free: - description: Allow free use/creation/destruction of gates - default: op - stargate.option: - description: Allow use of all options - default: op - stargate.admin: - description: Allow all admin features (Hidden/Private only so far) - default: op - children: - stargate.reload: true \ No newline at end of file + stargate.admin.hidden: true + stargate.admin.private: true + stargate.admin.bungee: true + stargate.server: true \ No newline at end of file diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index f1a24cd..72c2517 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -6,6 +6,7 @@ import be.seeseemelk.mockbukkit.WorldMock; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.RelativeBlockVector; import org.bukkit.Material; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -27,6 +28,11 @@ public class GateLayoutTest { layout = GateHandler.getGateByName("nethergate.gate").getLayout(); } + @AfterAll + public static void tearDown() { + MockBukkit.unmock(); + } + @Test public void gateLayoutExitTest() { assertEquals(new RelativeBlockVector(1, 3, 0), layout.getExit()); diff --git a/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java b/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java index 61687b7..c5edb92 100644 --- a/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java +++ b/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.utility; import be.seeseemelk.mockbukkit.MockBukkit; import org.bukkit.Material; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -13,6 +14,11 @@ public class MaterialHelperTest { MockBukkit.mock(); } + @AfterAll + public static void tearDown() { + MockBukkit.unmock(); + } + @Test public void isWallCoralTest() { Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_BRAIN_CORAL_WALL_FAN)); From 487cb3ad9ee8cf9564580ff6b1ce650a29a8eca0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 01:45:50 +0200 Subject: [PATCH 196/378] Adds missing info about Bungee-related permissions to the readme and adjusts permissions a bit Adds stargate.server and stargate.admin.bungee permissions to the readme Renames stargate.reload to stargate.admin.reload for better consistency Makes the stargate.admin permission only give the reload, hidden, private and bungee permissions while the wildcard permission gives all permissions --- README.md | 45 +++++++++++-------- .../stargate/command/CommandReload.java | 2 +- src/main/resources/plugin.yml | 31 +++++++------ 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 91bffb3..6d96651 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,14 @@ version of Stargate compliant with Spigot 1.17, even if it means changing the en # Permissions ``` -stargate.use -- Allow use of all gates linking to any world in any network (Override ALL network/world permissions. Set to false to use network/world specific permissions) - stargate.world -- Allow use of gates linking to any world - stargate.world.{world} -- Allow use of gates with a destination in {world}. Set to false to disallow use. - stargate.network -- Allow use of gates on all networks - stargate.network.{network} -- Allow use of all gates in {network}. Set to false to disallow use. - +stargate.use -- Allow use of all Stargates linking to any world in any network (Override ALL network/world permissions. Set to false to use network/world specific permissions) + stargate.world -- Allow use of Stargates linking to any world + stargate.world.{world} -- Allow use of Stargates with a destination in {world}. Set to false to disallow use. + stargate.network -- Allow use of Stargates on all networks + stargate.network.{network} -- Allow use of all Stargates in {network}. Set to false to disallow use. + stargate.server -- Allow use of Stargates going to all servers + stargate.server.{server} -- Allow usee of all Stargates going to {server}. Set to false to disallow use. + stargate.option -- Allow use of all options stargate.option.hidden -- Allow use of 'H'idden stargate.option.alwayson -- Allow use of 'A'lways-On @@ -33,21 +35,21 @@ stargate.option -- Allow use of all options stargate.option.backwards -- Allow use of 'B'ackwards stargate.option.show -- Allow use of 'S'how stargate.option.nonetwork -- Allow use of 'N'oNetwork - stargate.option.random -- Allow use of 'Random' gates + stargate.option.random -- Allow use of 'Random' stargates -stargate.create -- Allow creating gates on any network (Override all create permissions) - stargate.create.personal -- Allow creating gates on network {playername} - stargate.create.network -- Allow creating gates on any network - stargate.create.network.{networkname} -- Allow creating gates on network {networkname}. Set to false to disallow creation on {networkname} - stargate.create.gate -- Allow creation of any gate layout - stargate.create.gate.{gatefile} -- Allow creation of only {gatefile} gates +stargate.create -- Allow creating Stargates on any network (Override all create permissions) + stargate.create.personal -- Allow creating Stargates on network {playername} + stargate.create.network -- Allow creating Stargates on any network + stargate.create.network.{networkname} -- Allow creating Stargates on network {networkname}. Set to false to disallow creation on {networkname} + stargate.create.gate -- Allow creation using any gate layout + stargate.create.gate.{gatefile} -- Allow creation using only {gatefile} gates -stargate.destroy -- Allow destruction gates on any network (Orderride all destroy permissions) - stargate.destroy.personal -- Allow destruction of gates owned by user only - stargate.destroy.network -- Allow destruction of gates on any network - stargate.destroy.network.{networkname} -- Allow destruction of gates on network {networkname}. Set to false to disallow destruction of {networkname} +stargate.destroy -- Allow destruction of Stargates on any network (Orderride all destroy permissions) + stargate.destroy.personal -- Allow destruction of Stargates owned by the player only + stargate.destroy.network -- Allow destruction of Stargates on any network + stargate.destroy.network.{networkname} -- Allow destruction of Stargates on network {networkname}. Set to false to disallow destruction of {networkname} -stargate.free -- Allow free use/creation/destruction of gates +stargate.free -- Allow free use/creation/destruction of Stargates stargate.free.use -- Allow free use of Stargates stargate.free.create -- Allow free creation of Stargates stargate.free.destroy -- Allow free destruction of Stargates @@ -55,7 +57,8 @@ stargate.free -- Allow free use/creation/destruction of gates stargate.admin -- Allow all admin features (Hidden/Private only so far) stargate.admin.private -- Allow use of Private gates not owned by user stargate.admin.hidden -- Allow access to Hidden gates not ownerd by user - stargate.admin.reload -- Allow use of /sg reload + stargate.admin.bungee -- Allow the creation of BungeeCord stargates (U option) + stargate.admin.reload -- Allow use of the reload command ``` ## Default Permissions @@ -369,6 +372,10 @@ bungeeSign=Teleport to - Implements proper snowman snow blocking, and removes the "temporary" ignoreEntrances option - Adds a default gate using end stone bricks and end gateway for more default diversity - Makes portals using end portal blocks work as expected +- Adds missing permissions to the readme +- Adds missing permissions to plugin.yml and simplifies permission checks by specifying default values for child + permissions +- Renames stargate.reload to stargate.admin.reload to maintain consistency #### \[Version 0.8.0.3] PseudoKnight fork diff --git a/src/main/java/net/knarcraft/stargate/command/CommandReload.java b/src/main/java/net/knarcraft/stargate/command/CommandReload.java index 56366f8..6d29304 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandReload.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandReload.java @@ -16,7 +16,7 @@ public class CommandReload implements CommandExecutor { public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { if (commandSender instanceof Player player) { - if (!player.hasPermission("stargate.reload")) { + if (!player.hasPermission("stargate.admin.reload")) { Stargate.getMessageSender().sendErrorMessage(commandSender, "Permission Denied"); return true; } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index dc4eb91..1f4abd2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -15,17 +15,23 @@ commands: usage: / - Used to see stargate info or reload the plugin permissions: stargate.*: - description: Wildcard permission. Same as stargate.admin - default: op + description: Wildcard permission which gives all Stargate permissions + default: false children: stargate.admin: true + stargate.use: true + stargate.create: true + stargate.destroy: true + stargate.free: true + stargate.option: true + stargate.server: true stargate.reload: description: Allows reloading the plugin default: false stargate.use: description: Allow use of all stargates linking to any world in any network default: true - children: + children: stargate.world: true stargate.network: true stargate.server: true @@ -36,9 +42,9 @@ permissions: description: Allows use of stargates in any network default: false stargate.create: - description: Allow creating gates on any network + description: Allow creating stargates on any network using any gate type default: op - children: + children: stargate.create.personal: true stargate.create.network: true stargate.create.gate: true @@ -66,7 +72,7 @@ permissions: stargate.free: description: Allow free use/creation/destruction of stargates default: op - children: + children: stargate.free.use: true stargate.free.create: true stargate.free.destroy: true @@ -128,17 +134,10 @@ permissions: description: Allows the creation of a BungeeCord stargate going to any server default: false stargate.admin: - description: Allow all features and admin commands + description: Allow all admin features and commands (Hidden/Private bypass, BungeeCord, Reload) 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.admin.reload: true stargate.admin.hidden: true stargate.admin.private: true - stargate.admin.bungee: true - stargate.server: true \ No newline at end of file + stargate.admin.bungee: true \ No newline at end of file From f0e5cd45a42c979159e2ac192a4cfad28489a606 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 01:46:15 +0200 Subject: [PATCH 197/378] Adds some minor style improvements --- .../knarcraft/stargate/config/StargateConfig.java | 6 +++--- .../net/knarcraft/stargate/utility/EntityHelper.java | 2 +- .../net/knarcraft/stargate/utility/FileHelper.java | 2 +- .../knarcraft/stargate/utility/PermissionHelper.java | 12 ++++++------ .../stargate/utility/MaterialHelperTest.java | 12 ++++++------ 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 5ec3ee9..ecfc21d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -124,7 +124,7 @@ public final class StargateConfig { public void reload(CommandSender sender) { //Unload all saved data unload(); - + //Perform all block change requests to prevent mismatch if a gate's open-material changes. Changing the // closed-material still requires a restart. BlockChangeRequest firstElement = Stargate.blockChangeRequestQueue.peek(); @@ -132,7 +132,7 @@ public final class StargateConfig { BlockChangeThread.pollQueue(); firstElement = Stargate.blockChangeRequestQueue.peek(); } - + //Store the old enable bungee state in case it changes boolean oldEnableBungee = stargateGateConfig.enableBungee(); @@ -158,7 +158,7 @@ public final class StargateConfig { //Force all portals to close closeAllOpenPortals(); PortalHandler.closeAllPortals(); - + //Clear queues and lists activePortalsQueue.clear(); openPortalsQueue.clear(); diff --git a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java index 2888443..04ed19f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java @@ -15,7 +15,7 @@ public final class EntityHelper { * Gets the max size of an entity along its x and z axis * *

This function gets the ceiling of the max size of an entity, thus calculating the smallest box, using whole - * blocks as unit, needed to contain the entity. Assuming n is returned, an (n x n) box is needed to contain the + * blocks as unit, needed to contain the entity. Assuming n is returned, an (n x n) box is needed to contain the * entity.

* * @param entity

The entity to get max size for

diff --git a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java index a893946..c0be420 100644 --- a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java @@ -26,7 +26,7 @@ public final class FileHelper { /** * Gets an input stream from a string pointing to an internal file - * + * *

This is used for getting an input stream for reading a file contained within the compiled .jar file. The file * should be in the resources directory, and the file path should start with a forward slash ("/") character.

* diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 47d0e0a..d647224 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -47,7 +47,7 @@ public final class PermissionHelper { } //Deny access if another player has activated the portal, and it's still in use - if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && + if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && portal.getActivePlayer() != player) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; @@ -95,7 +95,7 @@ public final class PermissionHelper { */ public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { boolean deny = false; - + if (entrancePortal.getOptions().isBungee()) { if (!PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { //If the portal is a bungee portal, and the player cannot access the server, deny @@ -135,7 +135,7 @@ public final class PermissionHelper { /** * Check if a player has been given a permission implicitly * - *

This should be run if a player has a parent permission to check for the child permission. It is assumed the + *

This should be run if a player has a parent permission to check for the child permission. It is assumed the * player has the child permission unless it's explicitly set to false.

* * @param player

The player to check

@@ -150,7 +150,7 @@ public final class PermissionHelper { return true; } if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { - Stargate.debug("hasPermissionImplicit::Permission", permission + " => " + + Stargate.debug("hasPermissionImplicit::Permission", permission + " => " + player.hasPermission(permission)); } return player.hasPermission(permission); @@ -338,12 +338,12 @@ public final class PermissionHelper { */ public static boolean canDestroyPortal(Player player, Portal portal) { String network = portal.getNetwork(); - + //Use a special check for bungee portals if (portal.getOptions().isBungee()) { return hasPermission(player, "stargate.admin.bungee"); } - + //Check if the player is allowed to destroy on all networks if (hasPermission(player, "stargate.destroy.network")) { //Check if the network has been explicitly denied diff --git a/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java b/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java index c5edb92..f8481b2 100644 --- a/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java +++ b/src/test/java/net/knarcraft/stargate/utility/MaterialHelperTest.java @@ -13,12 +13,12 @@ public class MaterialHelperTest { public static void setUp() { MockBukkit.mock(); } - + @AfterAll public static void tearDown() { MockBukkit.unmock(); } - + @Test public void isWallCoralTest() { Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_BRAIN_CORAL_WALL_FAN)); @@ -31,12 +31,12 @@ public class MaterialHelperTest { Assertions.assertTrue(MaterialHelper.isWallCoral(Material.HORN_CORAL_WALL_FAN)); Assertions.assertTrue(MaterialHelper.isWallCoral(Material.DEAD_TUBE_CORAL_WALL_FAN)); Assertions.assertTrue(MaterialHelper.isWallCoral(Material.TUBE_CORAL_WALL_FAN)); - + Assertions.assertFalse(MaterialHelper.isWallCoral(Material.DEAD_TUBE_CORAL)); Assertions.assertFalse(MaterialHelper.isWallCoral(Material.TUBE_CORAL)); Assertions.assertFalse(MaterialHelper.isWallCoral(Material.TUBE_CORAL_BLOCK)); } - + @Test public void isButtonCompatibleTest() { Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.DEAD_BRAIN_CORAL_WALL_FAN)); @@ -82,9 +82,9 @@ public class MaterialHelperTest { Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.CHEST)); Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.ENDER_CHEST)); Assertions.assertTrue(MaterialHelper.isButtonCompatible(Material.TRAPPED_CHEST)); - + //Chek something random to make sure isButtonCompatible is not just "return true;" Assertions.assertFalse(MaterialHelper.isButtonCompatible(Material.OAK_LOG)); } - + } From 945798916b42af8f76af8209bef7c62646f79e69 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 15:07:45 +0200 Subject: [PATCH 198/378] Removes an unnecessary portal close statement after teleporting a player through BungeeCord --- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index b0df9ce..4816eb2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -331,15 +331,13 @@ public class PlayerEventListener implements Listener { return false; } - // Connect player to new server + //Send the connect-message to make the player change server if (!BungeeHelper.changeServer(player, entrancePortal)) { Stargate.debug("bungeeTeleport", "Unable to change server"); return false; } - // Close portal if required (Should never be) Stargate.debug("bungeeTeleport", "Teleported player to another server"); - entrancePortal.getPortalOpener().closePortal(false); return true; } From f52ba79ae9f6295589b58bbc71edcb1817f1845b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 15:08:44 +0200 Subject: [PATCH 199/378] Splits the preventExitSuffocation method and improves some more comments --- .../stargate/portal/PortalCreator.java | 8 ++-- .../stargate/portal/PortalRegistry.java | 4 +- .../knarcraft/stargate/portal/Teleporter.java | 48 +++++++++++++------ 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index e5c06e7..7d26981 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -223,28 +223,29 @@ public class PortalCreator { * @return

True if the portal is completely valid

*/ private boolean checkIfNewPortalIsValid(int cost, String portalName) { - // Name & Network can be changed in the event, so do these checks here. + //Check if the portal name can fit on the sign with padding (>name<) if (portal.getName().length() < 1 || portal.getName().length() > 11) { Stargate.debug("createPortal", "Name length error"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength")); return false; } - //Don't do network checks for bungee portals if (portal.getOptions().isBungee()) { + //Check if the bungee portal's name has been duplicated if (PortalHandler.getBungeePortals().get(portal.getName().toLowerCase()) != null) { Stargate.debug("createPortal::Bungee", "Gate name duplicate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); return false; } } else { + //Check if the portal name has been duplicated on the network if (PortalHandler.getByName(portal.getName(), portal.getNetwork()) != null) { Stargate.debug("createPortal", "Gate name duplicate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); return false; } - //Check if there are too many gates in this network + //Check if the number of portals in the network has been surpassed List networkList = PortalHandler.getAllPortalNetworks().get(portal.getNetwork().toLowerCase()); int maxGates = Stargate.getGateConfig().maxGatesEachNetwork(); if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) { @@ -254,6 +255,7 @@ public class PortalCreator { } if (cost > 0) { + //Deduct the required fee from the player if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) { EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); Stargate.debug("createPortal", "Insufficient Funds"); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index da9476a..7a557bc 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -267,8 +267,8 @@ public class PortalRegistry { if (!allPortalNetworks.get(networkName).contains(portalName)) { allPortalNetworks.get(networkName).add(portalName); } else { - Stargate.logSevere(String.format("Portal %s was registered twice. Check your portal database for " + - "duplicates.", portal)); + Stargate.logSevere(String.format("Portal %s on network %s was registered twice. Check your portal " + + "database for duplicates.", portal.getName(), portal.getNetwork())); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index 2e11a83..5002150 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -62,10 +62,11 @@ public abstract class Teleporter { */ public Location getExit(Entity entity, Location traveller) { Location exitLocation = null; - // Check if the gate has an exit block RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); if (relativeExit != null) { BlockLocation exit = portal.getBlockAt(relativeExit); + + //Move one block out to prevent exiting inside the portal float portalYaw = portal.getYaw(); if (portal.getOptions().isBackwards()) { portalYaw += 180; @@ -74,6 +75,7 @@ public abstract class Teleporter { if (entity != null) { double entitySize = EntityHelper.getEntityMaxSize(entity); + //Prevent exit suffocation for players riding horses or similar if (entitySize > 1) { exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); } @@ -83,6 +85,7 @@ public abstract class Teleporter { portal.getGate().getFilename())); } + //Adjust pitch and height return adjustExitLocation(traveller, exitLocation); } @@ -112,25 +115,34 @@ public abstract class Teleporter { } exitLocation = DirectionHelper.moveLocation(exitLocation, newOffset, 0, 0, portal.getYaw()); - //Move large entities further from the portal, especially if this teleporter's portal will teleport them at once + //Move large entities further from the portal + return moveExitLocationOutwards(exitLocation, entity); + } + + /** + * Moves the exit location out from the portal to prevent the entity from entering a teleportation loop + * + * @param exitLocation

The current exit location to adjust

+ * @param entity

The entity to adjust the exit location for

+ * @return

The adjusted exit location

+ */ + private Location moveExitLocationOutwards(Location exitLocation, Entity entity) { double entitySize = EntityHelper.getEntityMaxSize(entity); int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); if (entitySize > 1) { + double entityOffset; if (portal.getOptions().isAlwaysOn()) { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, (entityBoxSize / 2D), - portal.getYaw()); + entityOffset = entityBoxSize / 2D; } else { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, - (entitySize / 2D) - 1, portal.getYaw()); + entityOffset = (entitySize / 2D) - 1; } + //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's + // moved one block out. + if (entity instanceof AbstractHorse) { + entityOffset += 1; + } + exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, entityOffset, portal.getYaw()); } - - //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's - //moved one block out. - if (entity instanceof AbstractHorse) { - exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, 1, portal.getYaw()); - } - return exitLocation; } @@ -143,6 +155,7 @@ public abstract class Teleporter { */ private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { RelativeBlockVector openingEdge = relativeExit; + do { RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, openingEdge.getDown(), openingEdge.getOut()); @@ -152,11 +165,16 @@ public abstract class Teleporter { break; } } while (true); + return openingEdge; } /** - * Adjusts an exit location with rotation and slab height incrementation + * Adjusts an exit location by setting pitch and adjusting height + * + *

If the exit location is a slab or water, the exit location will be changed to arrive one block above. The + * slab check is necessary to prevent the player from clipping through the slab and spawning beneath it. The water + * check is necessary when teleporting boats to prevent it from becoming a submarine.

* * @param traveller

The location of the travelling entity

* @param exitLocation

The exit location generated

@@ -180,8 +198,8 @@ public abstract class Teleporter { return exitLocation; } else { Stargate.logWarning("Unable to generate exit location"); + return traveller; } - return traveller; } /** From 5d84e1d78ac4897bf00217790e2fcb44aca67227 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 16:05:23 +0200 Subject: [PATCH 200/378] Changes some sign coloring and adds some missing info to the readme Makes the Disconnected message red Makes the highlighting characters (><) white when cycling stargate destinations Moves markPortalWithInvalidGate to PortalSignDrawer Adds missing translation strings for reloaded and signInvalidGate to the readme Moves some extra spacing around the >< characters --- README.md | 9 +++++ .../stargate/portal/PortalSignDrawer.java | 34 ++++++++++++++----- .../stargate/utility/PortalFileHelper.java | 19 ++--------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 6d96651..29ffbb8 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,7 @@ invalidMsg=Invalid Destination blockMsg=Destination Blocked destEmpty=Destination List Empty denyMsg=Access Denied +reloaded=Stargate Reloaded ecoDeduct=Deducted %cost% ecoRefund=Refunded %cost% @@ -332,6 +333,7 @@ signRightClick=Right click signToUse=to use gate signRandom=Random signDisconnected=Disconnected +signInvalidGate=Invalid gate bungeeDisabled=BungeeCord support is disabled. bungeeDeny=You do not have permission to create BungeeCord gates. @@ -376,6 +378,13 @@ bungeeSign=Teleport to - Adds missing permissions to plugin.yml and simplifies permission checks by specifying default values for child permissions - Renames stargate.reload to stargate.admin.reload to maintain consistency +- Marks stargates which cannot be loaded because of the gate layout not having been loaded +- Uses white for the "-" characters on the side of each stargate name when drawing signs to increase readability +- Uses white to mark the selected destination when cycling through stargate destinations +- Uses dark red to mark portals which are inactive (missing destination or invalid gate type) +- Re-draws signs on startup in case they change +- Fixes some bugs preventing changing the portal-open block on the fly +- Adds a translate-able string for when the plugin has been reloaded #### \[Version 0.8.0.3] PseudoKnight fork diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 43d51f1..353bb98 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -13,6 +13,9 @@ import org.bukkit.block.Sign; public class PortalSignDrawer { private final Portal portal; + private final static ChatColor highlightColor = ChatColor.WHITE; + private final static ChatColor errorColor = ChatColor.DARK_RED; + private final static ChatColor freeColor = ChatColor.DARK_GREEN; /** * Instantiates a new portal sign drawer @@ -49,8 +52,8 @@ public class PortalSignDrawer { for (int index = 0; index <= 3; index++) { sign.setLine(index, ""); } - setLine(sign, 0, ChatColor.WHITE + "-" + Stargate.getGateConfig().getSignColor() + - portal.getName() + ChatColor.WHITE + "-"); + setLine(sign, 0, highlightColor + "-" + Stargate.getGateConfig().getSignColor() + + portal.getName() + highlightColor + "-"); if (!portal.getPortalActivator().isActive()) { //Default sign text @@ -115,11 +118,11 @@ public class PortalSignDrawer { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + ">" + - portal.getDestinationName() + (green ? ChatColor.DARK_GREEN : "") + "<"); + setLine(sign, signLineIndex, (green ? freeColor : "") + ">" + + portal.getDestinationName() + (green ? freeColor : "") + "<"); } else { - setLine(sign, signLineIndex, Stargate.getGateConfig().getSignColor() + " >" + - portal.getDestinationName() + Stargate.getGateConfig().getSignColor() + "< "); + setLine(sign, signLineIndex, highlightColor + ">" + Stargate.getGateConfig().getSignColor() + + portal.getDestinationName() + highlightColor + "<"); } } @@ -148,7 +151,7 @@ public class PortalSignDrawer { Portal destination = PortalHandler.getByName(destinations.getDestinations().get(destinationIndex), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (green ? ChatColor.DARK_GREEN : "") + + setLine(sign, signLineIndex, (green ? freeColor : "") + destinations.getDestinations().get(destinationIndex)); } else { setLine(sign, signLineIndex, destinations.getDestinations().get(destinationIndex)); @@ -199,10 +202,25 @@ public class PortalSignDrawer { } Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { - setLine(sign, 3, Stargate.getString("signDisconnected")); + setLine(sign, 3, errorColor + Stargate.getString("signDisconnected")); } else { setLine(sign, 3, ""); } } + /** + * Marks a portal with an invalid gate by changing its sign and writing to the console + * + * @param portalLocation

The location of the portal with an invalid gate

+ * @param gateName

The name of the invalid gate type

+ * @param lineIndex

The index of the line the invalid portal was found at

+ */ + public static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) { + Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); + sign.setLine(3, errorColor + Stargate.getString("signInvalidGate")); + sign.update(); + + Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName)); + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index d9763f2..6ce60e2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -10,9 +10,7 @@ import net.knarcraft.stargate.portal.PortalLocation; import net.knarcraft.stargate.portal.PortalOptions; import net.knarcraft.stargate.portal.PortalOwner; import net.knarcraft.stargate.portal.PortalRegistry; -import org.bukkit.ChatColor; import org.bukkit.World; -import org.bukkit.block.Sign; import java.io.BufferedWriter; import java.io.File; @@ -20,6 +18,8 @@ import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; +import static net.knarcraft.stargate.portal.PortalSignDrawer.markPortalWithInvalidGate; + /** * Helper class for saving and loading portal save files */ @@ -257,19 +257,4 @@ public final class PortalFileHelper { portal.getPortalOpener().closePortal(true); } - /** - * Marks a portal with an invalid gate by changing its sign and writing to the console - * - * @param portalLocation

The location of the portal with an invalid gate

- * @param gateName

The name of the invalid gate type

- * @param lineIndex

The index of the line the invalid portal was found at

- */ - private static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) { - Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); - sign.setLine(3, ChatColor.DARK_RED + Stargate.getString("signInvalidGate")); - sign.update(); - - Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName)); - } - } From 0237f45046d57ea68e5e2a02b4136b1b0b73015b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 17:22:58 +0200 Subject: [PATCH 201/378] Renames activatedTime to triggeredTime and makes some public fields private Makes the active portals queue and open portals queue and languageLoader fields private Cleans the StargateThread a bit Renames activatedTime to triggeredTime as the dual use (open and activate) made the name confusing --- .../java/net/knarcraft/stargate/Stargate.java | 29 +++++++++-- .../stargate/config/StargateConfig.java | 33 ++++++++++-- .../net/knarcraft/stargate/portal/Portal.java | 10 ++-- .../stargate/portal/PortalActivator.java | 8 +-- .../stargate/portal/PortalOpener.java | 32 ++++++------ .../stargate/thread/BlockChangeThread.java | 2 +- .../stargate/thread/StarGateThread.java | 50 ++++++++++++++----- 7 files changed, 116 insertions(+), 48 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 5a6ad8e..ebef327 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -16,7 +16,6 @@ import net.knarcraft.stargate.listener.PortalEventListener; import net.knarcraft.stargate.listener.TeleportEventListener; import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.WorldEventListener; -import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.thread.BlockChangeThread; @@ -35,17 +34,17 @@ import java.io.File; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; import java.util.logging.Logger; +/** + * The main class of the Stargate plugin + */ @SuppressWarnings("unused") public class Stargate extends JavaPlugin { //Used for changing gate open/closed material. - public static final Queue blockChangeRequestQueue = new LinkedList<>(); - public static final ConcurrentLinkedQueue openPortalsQueue = new ConcurrentLinkedQueue<>(); - public static final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); + private static final Queue blockChangeRequestQueue = new LinkedList<>(); private static final Queue chunkUnloadQueue = new PriorityQueue<>(); private static Logger logger; @@ -76,6 +75,26 @@ public class Stargate extends JavaPlugin { super(loader, descriptionFile, dataFolder, file); } + /** + * Adds a block change request to the request queue + * + * @param request

The request to add

+ */ + public static void addBlockChangeRequest(BlockChangeRequest request) { + if (request != null) { + blockChangeRequestQueue.add(request); + } + } + + /** + * Gets the queue containing block change requests + * + * @return

A block change request queue

+ */ + public static Queue getBlockChangeRequestQueue() { + return blockChangeRequestQueue; + } + /** * Gets the sender for sending messages to players * diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index ecfc21d..e71ec41 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Map; +import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Logger; @@ -29,13 +30,13 @@ import java.util.logging.Logger; */ public final class StargateConfig { - public final ConcurrentLinkedQueue activePortalsQueue = new ConcurrentLinkedQueue<>(); - public final ConcurrentLinkedQueue openPortalsQueue = new ConcurrentLinkedQueue<>(); + private final Queue activePortalsQueue = new ConcurrentLinkedQueue<>(); + private final Queue openPortalsQueue = new ConcurrentLinkedQueue<>(); private final HashSet managedWorlds = new HashSet<>(); private StargateGateConfig stargateGateConfig; private MessageSender messageSender; - public final LanguageLoader languageLoader; + private final LanguageLoader languageLoader; private EconomyConfig economyConfig; private final Logger logger; @@ -89,6 +90,28 @@ public final class StargateConfig { setupVaultEconomy(); } + /** + * Gets the queue of open portals + * + *

The open portals queue is used to close open portals after some time has passed

+ * + * @return

The open portals queue

+ */ + public Queue getOpenPortalsQueue() { + return openPortalsQueue; + } + + /** + * Gets the queue of active portals + * + *

The active portals queue is used to de-activate portals after some time has passed

+ * + * @return

The active portals queue

+ */ + public Queue getActivePortalsQueue() { + return activePortalsQueue; + } + /** * Gets whether debugging is enabled * @@ -127,10 +150,10 @@ public final class StargateConfig { //Perform all block change requests to prevent mismatch if a gate's open-material changes. Changing the // closed-material still requires a restart. - BlockChangeRequest firstElement = Stargate.blockChangeRequestQueue.peek(); + BlockChangeRequest firstElement = Stargate.getBlockChangeRequestQueue().peek(); while (firstElement != null) { BlockChangeThread.pollQueue(); - firstElement = Stargate.blockChangeRequestQueue.peek(); + firstElement = Stargate.getBlockChangeRequestQueue().peek(); } //Store the old enable bungee state in case it changes diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 3299240..d26e99a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -125,15 +125,15 @@ public class Portal { } /** - * Gets the time this portal was activated/opened + * Gets the time this portal was triggered (activated/opened) * *

The time is given in the equivalent of a Unix timestamp. It's used to decide when a portal times out and - * automatically closes.

+ * automatically closes/deactivates.

* - * @return

The time this portal was activated/opened

+ * @return

The time this portal was triggered (activated/opened)

*/ - public long getActivatedTime() { - return portalOpener.getActivatedTime(); + public long getTriggeredTime() { + return portalOpener.getTriggeredTime(); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 4848717..97f35d4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -131,7 +131,7 @@ public class PortalActivator { this.destinations.clear(); //Adds the active gate to the active queue to allow it to be remotely deactivated - Stargate.activePortalsQueue.add(portal); + Stargate.getStargateConfig().getActivePortalsQueue().add(portal); //Set the given player as the active player activePlayer = player; @@ -166,7 +166,7 @@ public class PortalActivator { StargateActivateEvent event = new StargateActivateEvent(portal, player, destinations, destination); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { - Stargate.activePortalsQueue.remove(portal); + Stargate.getStargateConfig().getActivePortalsQueue().remove(portal); return false; } @@ -189,7 +189,7 @@ public class PortalActivator { } //Un-mark the portal as activated - Stargate.activePortalsQueue.remove(portal); + Stargate.getStargateConfig().getActivePortalsQueue().remove(portal); //For a fixed gate, the destinations and the sign never really change, but at the same time, fixed gates are // never really activated, so in theory, this check should be redundant. @@ -261,7 +261,7 @@ public class PortalActivator { //Update the activated time to allow it to be deactivated after a timeout, and re-draw the sign to show the // selected destination - opener.setActivatedTime(System.currentTimeMillis() / 1000); + opener.setTriggeredTime(System.currentTimeMillis() / 1000); portal.drawSign(); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 9dd3612..635360d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -17,7 +17,7 @@ public class PortalOpener { private boolean isOpen = false; private final Portal portal; - private long activatedTime; + private long triggeredTime; private Player player; private final PortalActivator portalActivator; @@ -42,12 +42,12 @@ public class PortalOpener { } /** - * Sets the time when this portal was activated/opened + * Sets the time when this portal was triggered (activated/opened) * - * @param activatedTime

Unix timestamp when portal was activated/opened

+ * @param triggeredTime

Unix timestamp when portal was triggered

*/ - public void setActivatedTime(long activatedTime) { - this.activatedTime = activatedTime; + public void setTriggeredTime(long triggeredTime) { + this.triggeredTime = triggeredTime; } /** @@ -88,7 +88,7 @@ public class PortalOpener { //Change the entrance blocks to the correct type for (BlockLocation inside : portal.getStructure().getEntrances()) { - Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(inside, openType, axis)); + Stargate.addBlockChangeRequest(new BlockChangeRequest(inside, openType, axis)); } //Update the portal state to make is actually open @@ -103,11 +103,11 @@ public class PortalOpener { private void updatePortalOpenState(Player openFor) { //Update the open state of this portal isOpen = true; - activatedTime = System.currentTimeMillis() / 1000; + triggeredTime = System.currentTimeMillis() / 1000; //Change state from active to open - Stargate.openPortalsQueue.add(portal); - Stargate.activePortalsQueue.remove(portal); + Stargate.getStargateConfig().getOpenPortalsQueue().add(portal); + Stargate.getStargateConfig().getActivePortalsQueue().remove(portal); PortalOptions options = portal.getOptions(); @@ -165,7 +165,7 @@ public class PortalOpener { //Close the portal by requesting the opening blocks to change Material closedType = portal.getGate().getPortalClosedBlock(); for (BlockLocation entrance : portal.getStructure().getEntrances()) { - Stargate.blockChangeRequestQueue.add(new BlockChangeRequest(entrance, closedType, null)); + Stargate.addBlockChangeRequest(new BlockChangeRequest(entrance, closedType, null)); } //Update the portal state to make it actually closed @@ -184,8 +184,8 @@ public class PortalOpener { isOpen = false; //Un-mark the portal as active and open - Stargate.openPortalsQueue.remove(portal); - Stargate.activePortalsQueue.remove(portal); + Stargate.getStargateConfig().getOpenPortalsQueue().remove(portal); + Stargate.getStargateConfig().getActivePortalsQueue().remove(portal); //Close the destination portal if not always open if (!portal.getOptions().isAlwaysOn()) { @@ -219,12 +219,12 @@ public class PortalOpener { } /** - * Gets the time this portal opener's portal was activated/opened + * Gets the time this portal opener's portal was triggered (activated/opened) * - * @return

The time this portal opener's portal was activated/opened

+ * @return

The time this portal opener's portal was triggered

*/ - public long getActivatedTime() { - return activatedTime; + public long getTriggeredTime() { + return triggeredTime; } } diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index 27f75b4..ebc2026 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -30,7 +30,7 @@ public class BlockChangeThread implements Runnable { */ public static void pollQueue() { //Abort if there's no work to be done - BlockChangeRequest blockChangeRequest = Stargate.blockChangeRequestQueue.poll(); + BlockChangeRequest blockChangeRequest = Stargate.getBlockChangeRequestQueue().poll(); if (blockChangeRequest == null) { return; } diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index ac734eb..e4e70aa 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -3,7 +3,9 @@ package net.knarcraft.stargate.thread; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; /** * This class contains the function used to close servers which should no longer be open/active @@ -13,29 +15,53 @@ public class StarGateThread implements Runnable { @Override public void run() { long time = System.currentTimeMillis() / 1000; - //Close open portals - for (Iterator iterator = Stargate.openPortalsQueue.iterator(); iterator.hasNext(); ) { - Portal portal = iterator.next(); + closeOpenPortals(time); + deactivateActivePortals(time); + } + + /** + * Closes portals which are open and have timed out + * + * @param time

The current time

+ */ + private void closeOpenPortals(long time) { + List closedPortals = new ArrayList<>(); + Queue openPortalsQueue = Stargate.getStargateConfig().getOpenPortalsQueue(); + + for (Portal portal : openPortalsQueue) { //Skip always open and non-open gates - if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) { + if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee() || + !portal.isOpen()) { continue; } - if (time > portal.getActivatedTime() + Stargate.getGateConfig().getOpenTime()) { + if (time > portal.getTriggeredTime() + Stargate.getGateConfig().getOpenTime()) { portal.getPortalOpener().closePortal(false); - iterator.remove(); + closedPortals.add(portal); } } - //Deactivate active portals - for (Iterator iterator = Stargate.activePortalsQueue.iterator(); iterator.hasNext(); ) { - Portal portal = iterator.next(); + openPortalsQueue.removeAll(closedPortals); + } + + /** + * De-activates portals which are active and have timed out + * + * @param time

The current time

+ */ + private void deactivateActivePortals(long time) { + List deactivatedPortals = new ArrayList<>(); + Queue activePortalsQueue = Stargate.getStargateConfig().getActivePortalsQueue(); + + for (Portal portal : activePortalsQueue) { + //Skip portals which aren't active if (!portal.getPortalActivator().isActive()) { continue; } - if (time > portal.getActivatedTime() + Stargate.getGateConfig().getActiveTime()) { + if (time > portal.getTriggeredTime() + Stargate.getGateConfig().getActiveTime()) { portal.getPortalActivator().deactivate(); - iterator.remove(); + deactivatedPortals.add(portal); } } + activePortalsQueue.removeAll(deactivatedPortals); } } From 56ed0495b0d39a5844be94d4f2f759513be646d0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 18:35:20 +0200 Subject: [PATCH 202/378] Removes the last of the unprotected variables from Stargate Makes all classes use getInstance() to get a Stargate instance Removes the server variable as it's not needed --- .../java/net/knarcraft/stargate/Stargate.java | 14 ++++++++++--- .../stargate/config/EconomyConfig.java | 2 +- .../stargate/config/StargateConfig.java | 21 ++++++++++--------- .../stargate/listener/BlockEventListener.java | 5 +++-- .../stargate/portal/PlayerTeleporter.java | 2 +- .../stargate/portal/PortalActivator.java | 4 ++-- .../stargate/portal/PortalCreator.java | 2 +- .../stargate/portal/PortalOpener.java | 4 ++-- .../knarcraft/stargate/portal/Teleporter.java | 4 ++-- .../stargate/portal/VehicleTeleporter.java | 10 +++++---- .../stargate/thread/ChunkUnloadThread.java | 2 +- .../stargate/utility/BungeeHelper.java | 6 +++--- .../stargate/utility/EconomyHelper.java | 4 ++-- .../stargate/utility/PermissionHelper.java | 2 +- 14 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index ebef327..1b4039a 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -48,8 +48,7 @@ public class Stargate extends JavaPlugin { private static final Queue chunkUnloadQueue = new PriorityQueue<>(); private static Logger logger; - public static Server server; - public static Stargate stargate; + private static Stargate stargate; private static String pluginVersion; @@ -75,6 +74,15 @@ public class Stargate extends JavaPlugin { super(loader, descriptionFile, dataFolder, file); } + /** + * Gets an instance of this plugin + * + * @return

An instance of this plugin, or null if not instantiated

+ */ + public static Stargate getInstance() { + return stargate; + } + /** * Adds a block change request to the request queue * @@ -299,7 +307,7 @@ public class Stargate extends JavaPlugin { pluginManager = getServer().getPluginManager(); FileConfiguration newConfig = this.getConfig(); logger = Logger.getLogger("Minecraft"); - server = getServer(); + Server server = getServer(); stargate = this; stargateConfig = new StargateConfig(logger); diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 8c6e233..bd2a6c4 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -235,7 +235,7 @@ public final class EconomyConfig { //Check if vault is loaded Plugin vault = pluginManager.getPlugin("Vault"); if (vault != null && vault.isEnabled()) { - ServicesManager servicesManager = Stargate.server.getServicesManager(); + ServicesManager servicesManager = Stargate.getInstance().getServer().getServicesManager(); RegisteredServiceProvider economyProvider = servicesManager.getRegistration(Economy.class); if (economyProvider != null) { economy = economyProvider.getProvider(); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index e71ec41..7dfef4f 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -56,7 +56,7 @@ public final class StargateConfig { public StargateConfig(Logger logger) { this.logger = logger; - dataFolderPath = Stargate.stargate.getDataFolder().getPath().replaceAll("\\\\", "/"); + dataFolderPath = Stargate.getInstance().getDataFolder().getPath().replaceAll("\\\\", "/"); portalFolder = dataFolderPath + "/portals/"; gateFolder = dataFolderPath + "/gates/"; languageLoader = new LanguageLoader(dataFolderPath + "/lang/"); @@ -260,11 +260,11 @@ public final class StargateConfig { String bungeeChannel = "BungeeCord"; if (start) { - messenger.registerOutgoingPluginChannel(Stargate.stargate, bungeeChannel); - messenger.registerIncomingPluginChannel(Stargate.stargate, bungeeChannel, new BungeeCordListener()); + messenger.registerOutgoingPluginChannel(Stargate.getInstance(), bungeeChannel); + messenger.registerIncomingPluginChannel(Stargate.getInstance(), bungeeChannel, new BungeeCordListener()); } else { - messenger.unregisterIncomingPluginChannel(Stargate.stargate, bungeeChannel); - messenger.unregisterOutgoingPluginChannel(Stargate.stargate, bungeeChannel); + messenger.unregisterIncomingPluginChannel(Stargate.getInstance(), bungeeChannel); + messenger.unregisterOutgoingPluginChannel(Stargate.getInstance(), bungeeChannel); } } @@ -293,8 +293,8 @@ public final class StargateConfig { * Loads all config values */ public void loadConfig() { - Stargate.stargate.reloadConfig(); - FileConfiguration newConfig = Stargate.stargate.getConfig(); + Stargate.getInstance().reloadConfig(); + FileConfiguration newConfig = Stargate.getInstance().getConfig(); boolean isMigrating = false; if (newConfig.getString("lang") != null || @@ -329,7 +329,7 @@ public final class StargateConfig { //Load all economy config values economyConfig = new EconomyConfig(newConfig); - Stargate.stargate.saveConfig(); + Stargate.getInstance().saveConfig(); } /** @@ -403,7 +403,7 @@ public final class StargateConfig { * Loads all portals in all un-managed worlds */ public void loadAllPortals() { - for (World world : Stargate.stargate.getServer().getWorlds()) { + for (World world : Stargate.getInstance().getServer().getWorlds()) { if (!managedWorlds.contains(world.getName())) { PortalFileHelper.loadAllPortals(world); managedWorlds.add(world.getName()); @@ -421,7 +421,8 @@ public final class StargateConfig { logger.severe("Unable to create portal directory"); } } - File newFile = new File(portalFolder, Stargate.stargate.getServer().getWorlds().get(0).getName() + ".db"); + File newFile = new File(portalFolder, Stargate.getInstance().getServer().getWorlds().get(0).getName() + + ".db"); if (!newFile.exists() && !newFile.getParentFile().exists()) { if (!newFile.getParentFile().mkdirs()) { logger.severe("Unable to create portal database folder: " + newFile.getParentFile().getPath()); diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 730632f..cc762ca 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -83,7 +83,8 @@ public class BlockEventListener implements Listener { Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("createMsg")); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); - Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, portal::drawSign, 1); + Stargate.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), + portal::drawSign, 1); } /** @@ -122,7 +123,7 @@ public class BlockEventListener implements Listener { //Create and call a StarGateDestroyEvent StargateDestroyEvent destroyEvent = new StargateDestroyEvent(portal, player, deny, denyMessage, cost); - Stargate.server.getPluginManager().callEvent(destroyEvent); + Stargate.getInstance().getServer().getPluginManager().callEvent(destroyEvent); if (destroyEvent.isCancelled()) { event.setCancelled(true); return; diff --git a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java index e71ec4d..8bf1191 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java @@ -67,7 +67,7 @@ public class PlayerTeleporter extends Teleporter { */ private Location triggerPlayerPortalEvent(Portal origin, Location exit, PlayerMoveEvent event) { StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, portal, exit); - Stargate.server.getPluginManager().callEvent(stargatePlayerPortalEvent); + Stargate.getInstance().getServer().getPluginManager().callEvent(stargatePlayerPortalEvent); //Teleport is cancelled. Teleport the player back to where it came from if (stargatePlayerPortalEvent.isCancelled()) { new PlayerTeleporter(origin, player).teleport(origin, event); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 97f35d4..3e3dd4d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -164,7 +164,7 @@ public class PortalActivator { */ private boolean triggerStargateActivationEvent(Player player) { StargateActivateEvent event = new StargateActivateEvent(portal, player, destinations, destination); - Stargate.server.getPluginManager().callEvent(event); + Stargate.getInstance().getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { Stargate.getStargateConfig().getActivePortalsQueue().remove(portal); return false; @@ -183,7 +183,7 @@ public class PortalActivator { public void deactivate() { //Trigger a stargate deactivate event to allow other plugins to cancel the event StargateDeactivateEvent event = new StargateDeactivateEvent(portal); - Stargate.server.getPluginManager().callEvent(event); + Stargate.getInstance().getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 7d26981..faf9b60 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -177,7 +177,7 @@ public class PortalCreator { //Call StargateCreateEvent to let other plugins cancel or overwrite denial StargateCreateEvent stargateCreateEvent = new StargateCreateEvent(player, portal, lines, deny, denyMessage, createCost); - Stargate.server.getPluginManager().callEvent(stargateCreateEvent); + Stargate.getInstance().getServer().getPluginManager().callEvent(stargateCreateEvent); if (stargateCreateEvent.isCancelled()) { return null; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 635360d..1695c05 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -76,7 +76,7 @@ public class PortalOpener { public void openPortal(Player openFor, boolean force) { //Call the StargateOpenEvent to allow the opening to be cancelled StargateOpenEvent event = new StargateOpenEvent(openFor, portal, force); - Stargate.server.getPluginManager().callEvent(event); + Stargate.getInstance().getServer().getPluginManager().callEvent(event); if (event.isCancelled() || (isOpen() && !event.getForce())) { return; } @@ -152,7 +152,7 @@ public class PortalOpener { //Call the StargateCloseEvent to allow other plugins to cancel the closing, or change whether to force it closed StargateCloseEvent event = new StargateCloseEvent(portal, force); - Stargate.server.getPluginManager().callEvent(event); + Stargate.getInstance().getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index 5002150..c668c29 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -34,7 +34,7 @@ public abstract class Teleporter { */ public Teleporter(Portal portal) { this.portal = portal; - this.scheduler = Stargate.server.getScheduler(); + this.scheduler = Stargate.getInstance().getServer().getScheduler(); } @@ -207,7 +207,7 @@ public abstract class Teleporter { */ protected void loadChunks() { for (Chunk chunk : getChunksToLoad()) { - chunk.addPluginChunkTicket(Stargate.stargate); + chunk.addPluginChunkTicket(Stargate.getInstance()); //Allow the chunk to unload after 3 seconds Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); } diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java index 689cce8..34ee9d3 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -88,7 +88,8 @@ public class VehicleTeleporter extends Teleporter { } else { //Teleport an empty vehicle teleportingVehicle.teleport(exit); - scheduler.scheduleSyncDelayedTask(Stargate.stargate, () -> teleportingVehicle.setVelocity(newVelocity), 1); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), + () -> teleportingVehicle.setVelocity(newVelocity), 1); } } @@ -102,7 +103,7 @@ public class VehicleTeleporter extends Teleporter { private Location triggerEntityPortalEvent(Portal origin, Location exit) { StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingVehicle, origin, portal, exit); - Stargate.server.getPluginManager().callEvent(stargateEntityPortalEvent); + Stargate.getInstance().getServer().getPluginManager().callEvent(stargateEntityPortalEvent); //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake if (stargateEntityPortalEvent.isCancelled()) { new VehicleTeleporter(origin, teleportingVehicle).teleport(origin); @@ -149,7 +150,7 @@ public class VehicleTeleporter extends Teleporter { //Set rotation, add passengers and restore velocity newVehicle.setRotation(exit.getYaw(), exit.getPitch()); handleVehiclePassengers(passengers, newVehicle, 1); - scheduler.scheduleSyncDelayedTask(Stargate.stargate, () -> newVehicle.setVelocity(newVelocity), 1); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> newVehicle.setVelocity(newVelocity), 1); } /** @@ -162,7 +163,8 @@ public class VehicleTeleporter extends Teleporter { private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay) { for (Entity passenger : passengers) { passenger.eject(); - scheduler.scheduleSyncDelayedTask(Stargate.stargate, () -> teleportAndAddPassenger(vehicle, passenger), delay); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> teleportAndAddPassenger(vehicle, passenger), + delay); } } diff --git a/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java b/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java index 2c89db9..598a191 100644 --- a/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/ChunkUnloadThread.java @@ -23,7 +23,7 @@ public class ChunkUnloadThread implements Runnable { unloadQueue.remove(); Chunk chunkToUnload = firstElement.getChunkToUnload(); //Allow the chunk to be unloaded - chunkToUnload.removePluginChunkTicket(Stargate.stargate); + chunkToUnload.removePluginChunkTicket(Stargate.getInstance()); firstElement = unloadQueue.peek(); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 6f62234..81f608e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -78,7 +78,7 @@ public final class BungeeHelper { //Write the actual message dataOutputStream.writeBytes(message); //Send the plugin message - player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); + player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { Stargate.logSevere("Error sending BungeeCord teleport packet"); ex.printStackTrace(); @@ -104,7 +104,7 @@ public final class BungeeHelper { dataOutputStream.writeUTF(entrancePortal.getNetwork()); //Send the plugin message - player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); + player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { Stargate.logSevere("Error sending BungeeCord connect packet"); ex.printStackTrace(); @@ -155,7 +155,7 @@ public final class BungeeHelper { String destination = messageParts[1]; //Check if the player is online, if so, teleport, otherwise, queue - Player player = Stargate.server.getPlayer(playerUUID); + Player player = Stargate.getInstance().getServer().getPlayer(playerUUID); if (player == null) { bungeeQueue.put(playerUUID, destination); } else { diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 880c878..3a4d84f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -53,9 +53,9 @@ public final class EconomyHelper { PortalOwner owner = entrancePortal.getOwner(); Player portalOwner; if (owner.getUUID() != null) { - portalOwner = Stargate.server.getPlayer(owner.getUUID()); + portalOwner = Stargate.getInstance().getServer().getPlayer(owner.getUUID()); } else { - portalOwner = Stargate.server.getPlayer(owner.getName()); + portalOwner = Stargate.getInstance().getServer().getPlayer(owner.getName()); } //Notify the gate owner of received payment diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index d647224..2b395f3 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -81,7 +81,7 @@ public final class PermissionHelper { */ public static boolean portalAccessDenied(Player player, Portal portal, boolean deny) { StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); - Stargate.server.getPluginManager().callEvent(event); + Stargate.getInstance().getServer().getPluginManager().callEvent(event); return event.getDeny(); } From 56bf51f370abb2591eee9c89081115b6330484f3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 18:43:22 +0200 Subject: [PATCH 203/378] Adds missing JavaDoc --- .../container/RelativeBlockVector.java | 18 +++++++++++++++++- .../event/StargateEntityPortalEvent.java | 2 ++ .../event/StargatePlayerPortalEvent.java | 2 ++ .../stargate/portal/PortalOpener.java | 3 ++- .../knarcraft/stargate/portal/Teleporter.java | 6 ++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 932ee84..925764d 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -14,7 +14,23 @@ public class RelativeBlockVector { private final int down; private final int out; - public enum Property {RIGHT, DOWN, OUT} + /** + * A specifier for one of the relative block vector's three properties + */ + public enum Property { + /** + * Specifies the relative block vector's right property + */ + RIGHT, + /** + * Specifies the relative block vector's down property + */ + DOWN, + /** + * Specifies the relative block vector's out property + */ + OUT + } /** * Instantiates a new relative block vector diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java index b392ee8..0cf3448 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java @@ -64,6 +64,8 @@ public class StargateEntityPortalEvent extends StargateEvent { /** * Set the location of the entity's exit point + * + * @param location

The new location of the entity's exit point

*/ public void setExit(Location location) { this.exit = location; diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java index 95b6939..05d474b 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java @@ -53,6 +53,8 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent { /** * Set the location of the player's exit point + * + * @param location

The new location of the player's exit point

*/ public void setExit(Location location) { this.exit = location; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 1695c05..21484af 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -71,7 +71,8 @@ public class PortalOpener { /** * Open this portal opener's portal * - * @param force

Whether to force the portal open, even if it's already open for some player

+ * @param openFor

The player to open the portal for

+ * @param force

Whether to force the portal open, even if it's already open for some player

*/ public void openPortal(Player openFor, boolean force) { //Call the StargateOpenEvent to allow the opening to be cancelled diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index c668c29..30ffecb 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -24,7 +24,13 @@ import java.util.List; */ public abstract class Teleporter { + /** + * The portal the entity is teleporting to + */ protected final Portal portal; + /** + * The scheduler to use for delaying tasks + */ protected final BukkitScheduler scheduler; /** From 50c446f9d94f96bc9dd26d6060eb3fccaf2b5d57 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 21:19:24 +0200 Subject: [PATCH 204/378] Adds package JavaDoc to help anyone who wants to use the Stargate API --- .../stargate/event/StargateAccessEvent.java | 3 ++- .../stargate/event/StargateDestroyEvent.java | 2 +- .../stargate/event/package-info.java | 25 +++++++++++++++++++ .../net/knarcraft/stargate/package-info.java | 4 +++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/event/package-info.java create mode 100644 src/main/java/net/knarcraft/stargate/package-info.java diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 843b3d6..3f70dec 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -8,7 +8,8 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a player attempts to access a stargate * - *

This event can be used to override whether the player should be allowed to access the stargate.

+ *

This event is triggered whenever a player enters or activates a stargate. This event can be used to override + * whether the player should be allowed to access the stargate.

*/ @SuppressWarnings("unused") public class StargateAccessEvent extends StargatePlayerEvent { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index 84bc981..bfcc606 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -6,7 +6,7 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; /** - * This event represents an event where a star gate is destroyed or attempted to be destroyed + * This event should be called whenever a stargate is destroyed * *

This event can be used to deny or change the cost of a stargate destruction.

*/ diff --git a/src/main/java/net/knarcraft/stargate/event/package-info.java b/src/main/java/net/knarcraft/stargate/event/package-info.java new file mode 100644 index 0000000..abebf8b --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/package-info.java @@ -0,0 +1,25 @@ +/** + * Events for any plugins wanting to interact with the Stargate plugin + * + *

This package contains several events used for interactions with Stargate. All events can be cancelled. For + * several of the events, it is possible to overrule permissions. A general overview of the events' usage:

+ * + *
    + *
  • The StargateAccessEvent is called whenever a player clicks a stargate's sign, and when a player enters a + * Stargate. It can be used to override whether the access should be allowed or denied.
  • + *
  • The StargateActivateEvent is called whenever a player activates a stargate (uses the stargate's sign). It + * can be used to override which destinations are available to the player.
  • + *
  • The StargateCloseEvent is called whenever a stargate is closed. Forcing the stargate closed can be toggled.
  • + *
  • The StargateCreateEvent is called whenever a new stargate is created. Its deny value can be overridden, the + * cost can be changed
  • + *
  • The StargateDeactivateEvent is called whenever a stargate is deactivated.
  • + *
  • The StargateDestroyEvent is called whenever a stargate is destroyed. Its deny value can be overridden or the + * cost can be changed.
  • + *
  • The StargateEntityPortalEvent is called whenever an entity teleports through a stargate. The exit location + * can be changed.
  • + *
  • The StargateOpenEvent is called whenever a stargate is opened. Forcing the stargate open can be toggled.
  • + *
  • The StargatePlayerPortalEvent is called whenever a player teleports through a stargate. The exit location can + * be changed.
  • + *
+ */ +package net.knarcraft.stargate.event; \ No newline at end of file diff --git a/src/main/java/net/knarcraft/stargate/package-info.java b/src/main/java/net/knarcraft/stargate/package-info.java new file mode 100644 index 0000000..c0f22f3 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/package-info.java @@ -0,0 +1,4 @@ +/** + * The root package of the Stargate plugin. Contains the main Stargate.java file + */ +package net.knarcraft.stargate; \ No newline at end of file From 5d41b2114b447454f8179dcf31f4bf0140409795 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 29 Oct 2021 22:08:54 +0200 Subject: [PATCH 205/378] Adds migration information and some missing information to the description --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 29ffbb8..4610bab 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,14 @@ can share a network or be split into clusters; they can be hidden on a network o - Player permissions -- let players build their own networks. - Vault economy support -- can add costs for create, destroy and use. -- Multiple custom gate configurations +- Ability to create custom gate configurations. Three different default gate configurations are available. - Message customization +- Multiple built-in languages (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) - Teleport across worlds or servers (BungeeCord supported) - Vehicle teleportation -- teleport minecarts, boats, horses, pigs and striders +- Underwater portals -- portals can be placed underwater as long as a waterproof button is used +- API available -- using the API, a lot of behavior can be changed +- Button customization -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) ## Background @@ -16,6 +20,20 @@ This was originally TheDgtl's Bukkit port of the Stargate plugin for hMod by Din of [PseudoKnight's fork](https://github.com/PseudoKnight/Stargate-Bukkit). This fork's main purpose is to create a clean version of Stargate compliant with Spigot 1.17, even if it means changing the entire project's previous structure. +## Migration + +This plugin should be compatible with configurations from the Stargate plugin all the way back. The nethergate.gate +file, the endgate.gate file and the watergate.gate file will be overwritten if they exist. Take a backup of the files +and overwrite the files after the first startup if you want to keep your custom gates. + +If you have legacy gate files using the old numeric material ids, you need to change them to the new format manually. +Use F3 + H to see material ids. Use them exactly as written after "minecraft:". +The configuration will be updated to a more easily readable format, but the old configuration will be saved in case you +want to change back right away. + +Permissions have had a few changes, so you should check the permissions section for any differences since you set up +permissions. + # Permissions ``` From 260211b67769fad7de3be0c1ea0e7f65e878c057 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 30 Oct 2021 05:59:12 +0200 Subject: [PATCH 206/378] Adds missing chest buttons to the readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4610bab..4cead8e 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,8 @@ WARPED_BUTTON POLISHED_BLACKSTONE_BUTTON CHEST +TRAPPED_CHEST +ENDER_CHEST SHULKER_BOX WHITE_SHULKER_BOX ORANGE_SHULKER_BOX From a4075363ec702da93e0bc507f0881c02b3303e5c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 30 Oct 2021 06:14:24 +0200 Subject: [PATCH 207/378] Fixes some slightly incorrect information about economy gate configuration --- README.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4cead8e..3a8b5fe 100644 --- a/README.md +++ b/README.md @@ -155,22 +155,6 @@ The options are the single letter, not the word. So to make a private hidden gat - Right-click the button to open up a portal. - Step through. -## Economy Support: - -The latest version of Stargate has support for Vault. Gate creation, destruction and use can all have different costs -associated with them. You can also define per-gate layout costs. The default cost is assigned in the config.yml file, -while the per-gate costs re defined in the .gate files. To define a certain cost to a gate just add these lines to your -.gate file: - -``` -economy: - useEconomy: true - createCost: 5 - destroyCost: 5 - useCost: 5 - toOwner: true -``` - # Custom Gate Layout You can create as many gate formats as you want, the gate layouts are stored in `plugins/Stargate/gates/`. @@ -276,6 +260,20 @@ Using `AIR` for a closed underwater gate looks weird, so `WATER` might be better you need to make sure it actually contains air when creating it. For partially submerged portals, like ones used for boat teleportation, you need to keep water away from the portal entrance/opening until it's been created. +## Economy Support: + +The latest version of Stargate has support for Vault. Gate creation, destruction and use can all have different costs +associated with them. You can also define per-gate layout costs. The default cost is assigned in the config.yml file, +while the per-gate costs re defined in the .gate files. To define a certain cost to a gate just add these lines to your +.gate file: + +``` + createCost: 5 -- Will cost 5 currency to create + destroyCost: 5 -- Will clost 5 currency to destroy (negative to get back the spent money) + useCost: 5 -- Will cost 5 currency to use the stargate + toOwner: true -- Will send any fees to the gate's owner +``` + # Configuration ``` @@ -298,7 +296,7 @@ gates: enableBungee - Enable this for BungeeCord support. This allows portals across Bungee servers. handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. economy: - useEconomy - Whether or not to use Economy + useEconomy - Whether or not to enable Economy using Vault (must have the Vault plugin) createCost - The cost to create a stargate destroyCost - The cost to destroy a stargate (Can be negative for a "refund" useCost - The cost to use a stargate From 8fa0cca5ce5675a71410d6c1cfe62a2ee0304745 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 30 Oct 2021 14:48:11 +0200 Subject: [PATCH 208/378] Adds Jenkinsfile for automated building --- Jenkinsfile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..48e21a5 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,24 @@ +pipeline { + agent any + stages { + stage('Build') { + steps { + echo 'Building...' + sh 'mvn clean & mvn validate & mvn compile' + } + } + stage('Test') { + steps { + echo 'Testing...' + sh 'mvn test' + } + } + stage('Deploy') { + steps { + echo 'Deploying...' + sh 'mvn verify -Dmaven.test.skip=true' + archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true + } + } + } +} \ No newline at end of file From 40f0a99e5a42b960c97dd6bac2678f368d6f6896 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 30 Oct 2021 15:17:15 +0200 Subject: [PATCH 209/378] Forces Jenkins to use a compatible JDK --- Jenkinsfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 48e21a5..5a47c8f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,8 @@ pipeline { agent any + tools { + jdk 'JDK17' + } stages { stage('Build') { steps { From 1f1fef3054367cc78bc0fb353ddd61f707843054 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 30 Oct 2021 15:33:58 +0200 Subject: [PATCH 210/378] Changes Jenkins to JDK 16 as Maven doesn't like Java 17. Ugh. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5a47c8f..b17f9a7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ pipeline { agent any tools { - jdk 'JDK17' + jdk 'JDK16' } stages { stage('Build') { From d754247455c0f7ef75e2333066ca461aeaa23520 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 31 Oct 2021 14:05:06 +0100 Subject: [PATCH 211/378] Makes some smaller changes Replaces the mystery code in sendMessage with translateAlternateColorCodes and removes the TODO Removes the TODO in deactivate() as it is actually necessary because fixed portals are always active Moves conflictsWithExistingGate to PortalCreator and removes the TODO for now Removes the extra spaces in >Random< Adjusts some comments Adds missing information about Economy and the requirement of UUIDs --- README.md | 19 ++++++++----- .../stargate/config/MessageSender.java | 4 +-- .../stargate/event/StargateAccessEvent.java | 2 +- .../stargate/portal/PortalActivator.java | 4 +-- .../stargate/portal/PortalCreator.java | 23 ++++++++++++++- .../stargate/portal/PortalHandler.java | 28 ++----------------- .../stargate/portal/PortalSignDrawer.java | 2 +- 7 files changed, 40 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 3a8b5fe..c4f108d 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,23 @@ version of Stargate compliant with Spigot 1.17, even if it means changing the en ## Migration -This plugin should be compatible with configurations from the Stargate plugin all the way back. The nethergate.gate -file, the endgate.gate file and the watergate.gate file will be overwritten if they exist. Take a backup of the files +This plugin should be compatible with configurations from the Stargate plugin all the way back. The nethergate.gate +file, the endgate.gate file and the watergate.gate file will be overwritten if they exist. Take a backup of the files and overwrite the files after the first startup if you want to keep your custom gates. -If you have legacy gate files using the old numeric material ids, you need to change them to the new format manually. -Use F3 + H to see material ids. Use them exactly as written after "minecraft:". -The configuration will be updated to a more easily readable format, but the old configuration will be saved in case you -want to change back right away. +If you have legacy gate files using the old numeric material ids, you need to change them to the new format manually. +Use F3 + H to see material ids. Use them exactly as written after "minecraft:". The configuration will be updated to a +more easily readable format, but the old configuration will be saved in case you want to change back right away. -Permissions have had a few changes, so you should check the permissions section for any differences since you set up +Permissions have had a few changes, so you should check the permissions section for any differences since you set up permissions. +Payment to owner using Economy, through Vault, is only possible if the portal owner in the portal database is defined by +a UUID, and not a username. Right now, there is no automatic upgrade from usernames to UUID. You must either make the +stargate owner re-create the stargate or edit the file in the portals folder in a text editor. There are various ways to +find the UUID of players. You may look in the usercache.json file in the server directory or search for the username on +various websites. + # Permissions ``` diff --git a/src/main/java/net/knarcraft/stargate/config/MessageSender.java b/src/main/java/net/knarcraft/stargate/config/MessageSender.java index 2ada1f4..1507dd7 100644 --- a/src/main/java/net/knarcraft/stargate/config/MessageSender.java +++ b/src/main/java/net/knarcraft/stargate/config/MessageSender.java @@ -50,9 +50,7 @@ public final class MessageSender { if (message.isEmpty()) { return; } - //Replace color codes with green? What's the deal with the dollar sign? - //TODO: Figure out what this is actually supposed to do and do it in a better way - message = message.replaceAll("(&([a-f0-9]))", "\u00A7$2"); + message = ChatColor.translateAlternateColorCodes('&', message); if (error) { sender.sendMessage(ChatColor.RED + languageLoader.getString("prefix") + ChatColor.WHITE + message); } else { diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 3f70dec..5b64a14 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull; /** * This event should be called whenever a player attempts to access a stargate * - *

This event is triggered whenever a player enters or activates a stargate. This event can be used to override + *

This event is triggered whenever a player enters or activates a stargate. This event can be used to override * whether the player should be allowed to access the stargate.

*/ @SuppressWarnings("unused") diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 3e3dd4d..481ca52 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -191,9 +191,7 @@ public class PortalActivator { //Un-mark the portal as activated Stargate.getStargateConfig().getActivePortalsQueue().remove(portal); - //For a fixed gate, the destinations and the sign never really change, but at the same time, fixed gates are - // never really activated, so in theory, this check should be redundant. - //TODO: Decide if this check is really useless + //Fixed portals are active by definition, but should never be de-activated if (portal.getOptions().isFixed()) { return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index faf9b60..f041e02 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -147,7 +147,7 @@ public class PortalCreator { } //Check if a conflict exists - if (PortalHandler.conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), yaw, player)) { + if (conflictsWithExistingPortal(gate, portalLocation.getTopLeft(), yaw, player)) { return null; } @@ -312,4 +312,25 @@ public class PortalCreator { } } + /** + * Checks whether the new portal conflicts with an existing portal + * + * @param gate

The gate type of the new portal

+ * @param topLeft

The top-left block of the new portal

+ * @param yaw

The yaw when looking directly outwards from the portal

+ * @param player

The player creating the new portal

+ * @return

True if a conflict was found. False otherwise

+ */ + private static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, double yaw, Player player) { + for (RelativeBlockVector borderVector : gate.getLayout().getBorder()) { + BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); + if (PortalHandler.getByBlock(borderBlockLocation.getBlock()) != null) { + Stargate.debug("createPortal", "Gate conflicts with existing gate"); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createConflict")); + return true; + } + } + return false; + } + } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 8d536b5..15592b8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -86,11 +86,11 @@ public class PortalHandler { destinations.add(portal.getName()); continue; } - //Check if this player can access the dest world + //Check if this player can access the destination world if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { continue; } - //Visible to this player. + //The portal is visible to the player if (PermissionHelper.canSeePortal(player, portal)) { destinations.add(portal.getName()); } @@ -170,30 +170,6 @@ public class PortalHandler { return gate; } - /** - * Checks whether the new portal conflicts with an existing portal - * - * @param gate

The gate type of the new portal

- * @param topLeft

The top-left block of the new portal

- * @param yaw

The yaw when looking directly outwards from the portal

- * @param player

The player creating the new portal

- * @return

True if a conflict was found. False otherwise

- */ - static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, double yaw, Player player) { - //TODO: Make a quicker check. Could just check for control block conflicts if all code is changed to account for - // getting several hits at a single location when checking for the existence of a portal. May make - // everything slower overall? Would make for cooler gates though. - for (RelativeBlockVector borderVector : gate.getLayout().getBorder()) { - BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); - if (getByBlock(borderBlockLocation.getBlock()) != null) { - Stargate.debug("createPortal", "Gate conflicts with existing gate"); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createConflict")); - return true; - } - } - return false; - } - /** * Updates the sign and open state of portals pointing at the newly created portal * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 353bb98..a79cdb0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -191,7 +191,7 @@ public class PortalSignDrawer { */ private void drawFixedSign(Sign sign) { if (portal.getOptions().isRandom()) { - setLine(sign, 1, "> " + Stargate.getString("signRandom") + " <"); + setLine(sign, 1, ">" + Stargate.getString("signRandom") + "<"); } else { setLine(sign, 1, ">" + portal.getDestinationName() + "<"); } From 01df8db0bfde4e9644667cb9d79d0d7021896dcf Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 31 Oct 2021 18:05:04 +0100 Subject: [PATCH 212/378] Moves config loading to finisSetup() to prevent a NullPointerException --- .../knarcraft/stargate/config/StargateConfig.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 7dfef4f..f072efd 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -60,19 +60,19 @@ public final class StargateConfig { portalFolder = dataFolderPath + "/portals/"; gateFolder = dataFolderPath + "/gates/"; languageLoader = new LanguageLoader(dataFolderPath + "/lang/"); - - this.loadConfig(); - - //Enable the required channels for Bungee support - if (stargateGateConfig.enableBungee()) { - startStopBungeeListener(true); - } } /** * Finish the config setup by loading languages, gates and portals, and loading economy if vault is loaded */ public void finishSetup() { + this.loadConfig(); + + //Enable the required channels for Bungee support + if (stargateGateConfig.enableBungee()) { + startStopBungeeListener(true); + } + //Set the chosen language and reload the language loader languageLoader.setChosenLanguage(languageName); languageLoader.reload(); From 99f8a9285756e7339edc6b1d4dcc28775c38870f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 31 Oct 2021 18:08:58 +0100 Subject: [PATCH 213/378] Adds a highlightSignColor option and fixes some color inconsistencies Makes all characters used for highlighting/marking use the highlighting color Adds a new config option for highlighting color Renames signColor to mainSignColor and adds the change to the config-migrations.txt file --- .../stargate/config/StargateGateConfig.java | 29 ++++------ .../stargate/portal/PortalSignDrawer.java | 58 ++++++++++++------- src/main/resources/config-migrations.txt | 1 + src/main/resources/config.yml | 6 +- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index da38bfc..917f91b 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.PortalSignDrawer; import org.bukkit.ChatColor; import org.bukkit.configuration.file.FileConfiguration; @@ -17,7 +18,6 @@ public final class StargateGateConfig { private boolean enableBungee = true; private boolean verifyPortals = true; private boolean destroyExplosion = false; - private ChatColor signColor; private String defaultGateNetwork = "central"; private static final int activeTime = 10; private static final int openTime = 10; @@ -121,17 +121,6 @@ public final class StargateGateConfig { return destroyExplosion; } - /** - * Gets the color to use for drawing signs - * - *

Highlighting may use other colors. This is just the base color for portal names and such.

- * - * @return

The color to use for drawing signs

- */ - public ChatColor getSignColor() { - return signColor; - } - /** * Gets the default portal network to use if no other network is given * @@ -163,24 +152,26 @@ public final class StargateGateConfig { //Cosmetic sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); - loadSignColor(newConfig.getString("gates.cosmetic.signColor")); + loadSignColor(newConfig.getString("gates.cosmetic.mainSignColor"), + newConfig.getString("gates.cosmetic.highlightSignColor")); } /** * Loads the correct sign color given a sign color string * - * @param signColor

A string representing a sign color

+ * @param mainSignColor

A string representing the main sign color

*/ - private void loadSignColor(String signColor) { - if (signColor != null) { + private void loadSignColor(String mainSignColor, String highlightSignColor) { + if (mainSignColor != null) { try { - this.signColor = ChatColor.valueOf(signColor.toUpperCase()); + PortalSignDrawer.setColors(ChatColor.valueOf(mainSignColor.toUpperCase()), + ChatColor.valueOf(highlightSignColor.toUpperCase())); return; } catch (IllegalArgumentException | NullPointerException ignored) { } } - Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK"); - this.signColor = ChatColor.BLACK; + Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); + PortalSignDrawer.setColors(ChatColor.BLACK, ChatColor.WHITE); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index a79cdb0..abad04b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -13,9 +13,10 @@ import org.bukkit.block.Sign; public class PortalSignDrawer { private final Portal portal; - private final static ChatColor highlightColor = ChatColor.WHITE; private final static ChatColor errorColor = ChatColor.DARK_RED; private final static ChatColor freeColor = ChatColor.DARK_GREEN; + private static ChatColor mainColor; + private static ChatColor highlightColor; /** * Instantiates a new portal sign drawer @@ -26,6 +27,20 @@ public class PortalSignDrawer { this.portal = portal; } + /** + * Sets the main sign color + * + *

The main sign color is used for most text on the sign, while the highlighting color is used for the markings + * around portal names and network names ('>','<','-',')','(')

+ * + * @param newMainColor

The new main sign color

+ * @param newHighlightColor

The new highlight color

+ */ + public static void setColors(ChatColor newMainColor, ChatColor newHighlightColor) { + mainColor = newMainColor; + highlightColor = newHighlightColor; + } + /** * Draws the sign of the portal this sign drawer is responsible for */ @@ -47,12 +62,12 @@ public class PortalSignDrawer { * * @param sign

The sign re-draw

*/ - public void drawSign(Sign sign) { + private void drawSign(Sign sign) { //Clear sign for (int index = 0; index <= 3; index++) { sign.setLine(index, ""); } - setLine(sign, 0, highlightColor + "-" + Stargate.getGateConfig().getSignColor() + + setLine(sign, 0, highlightColor + "-" + mainColor + portal.getName() + highlightColor + "-"); if (!portal.getPortalActivator().isActive()) { @@ -118,11 +133,12 @@ public class PortalSignDrawer { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (green ? freeColor : "") + ">" + - portal.getDestinationName() + (green ? freeColor : "") + "<"); + ChatColor nameColor = (green ? freeColor : highlightColor); + setLine(sign, signLineIndex, nameColor + ">" + (green ? freeColor : mainColor) + + portal.getDestinationName() + nameColor + "<"); } else { - setLine(sign, signLineIndex, highlightColor + ">" + Stargate.getGateConfig().getSignColor() + - portal.getDestinationName() + highlightColor + "<"); + setLine(sign, signLineIndex, highlightColor + ">" + mainColor + portal.getDestinationName() + + highlightColor + "<"); } } @@ -134,7 +150,7 @@ public class PortalSignDrawer { * @param text

The new text on the sign

*/ public void setLine(Sign sign, int index, String text) { - sign.setLine(index, Stargate.getGateConfig().getSignColor() + text); + sign.setLine(index, mainColor + text); } /** @@ -147,14 +163,13 @@ public class PortalSignDrawer { */ private void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex) { PortalActivator destinations = portal.getPortalActivator(); + String destinationName = destinations.getDestinations().get(destinationIndex); if (freeGatesGreen) { - Portal destination = PortalHandler.getByName(destinations.getDestinations().get(destinationIndex), - portal.getNetwork()); + Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (green ? freeColor : "") + - destinations.getDestinations().get(destinationIndex)); + setLine(sign, signLineIndex, (green ? freeColor : mainColor) + destinationName); } else { - setLine(sign, signLineIndex, destinations.getDestinations().get(destinationIndex)); + setLine(sign, signLineIndex, mainColor + destinationName); } } @@ -165,8 +180,8 @@ public class PortalSignDrawer { */ private void drawBungeeSign(Sign sign) { setLine(sign, 1, Stargate.getString("bungeeSign")); - setLine(sign, 2, ">" + portal.getDestinationName() + "<"); - setLine(sign, 3, "[" + portal.getNetwork() + "]"); + setLine(sign, 2, highlightColor + ">" + mainColor + portal.getDestinationName() + highlightColor + "<"); + setLine(sign, 3, highlightColor + "[" + mainColor + portal.getNetwork() + highlightColor + "]"); } /** @@ -178,7 +193,7 @@ public class PortalSignDrawer { setLine(sign, 1, Stargate.getString("signRightClick")); setLine(sign, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { - setLine(sign, 3, "(" + portal.getNetwork() + ")"); + setLine(sign, 3, highlightColor + "(" + mainColor + portal.getNetwork() + highlightColor + ")"); } else { setLine(sign, 3, ""); } @@ -190,15 +205,14 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawFixedSign(Sign sign) { - if (portal.getOptions().isRandom()) { - setLine(sign, 1, ">" + Stargate.getString("signRandom") + "<"); - } else { - setLine(sign, 1, ">" + portal.getDestinationName() + "<"); - } + String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : + portal.getDestinationName(); + setLine(sign, 1, highlightColor + ">" + mainColor + destinationName + highlightColor + "<"); + if (portal.getOptions().isNoNetwork()) { setLine(sign, 2, ""); } else { - setLine(sign, 2, "(" + portal.getNetwork() + ")"); + setLine(sign, 2, highlightColor + "(" + mainColor + portal.getNetwork() + highlightColor + ")"); } Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { diff --git a/src/main/resources/config-migrations.txt b/src/main/resources/config-migrations.txt index 9326497..2de4df7 100644 --- a/src/main/resources/config-migrations.txt +++ b/src/main/resources/config-migrations.txt @@ -13,6 +13,7 @@ protectEntrance=gates.integrity.protectEntrance enableBungee=gates.functionality.enableBungee verifyPortals=gates.integrity.verifyPortals signColor=gates.cosmetic.signColor +gates.cosmetic.signColor=gates.cosmetic.mainSignColor debug=debugging.debug permdebug=debugging.permissionDebug useiconomy=economy.useEconomy diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9c53803..eac074b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -11,7 +11,8 @@ # handleVehicles - Whether to allow vehicles through gates # sortNetworkDestinations - Whether to sort network lists alphabetically # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) -# signColor - The color used for drawing signs (Default: BLACK). +# mainSignColor - The color used for drawing signs (Default: BLACK). +# highlightSignColor - The color used for sign markings (Default: WHITE) # verifyPortals - Whether all the non-sign blocks are checked to match the gate layout when a stargate is loaded. # I------------I-------------I # # stargate economy options # @@ -39,7 +40,8 @@ gates: cosmetic: rememberDestination: false sortNetworkDestinations: false - signColor: BLACK + mainSignColor: BLACK + highlightSignColor: WHITE integrity: destroyedByExplosion: false verifyPortals: false From 06cb99de444debaa4e0031a22bc2aedc13bf0bf6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 31 Oct 2021 18:09:56 +0100 Subject: [PATCH 214/378] Bumps version to 0.9.0.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33b927f..45ad153 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.0 + 0.9.0.1 From 0655d8535632d1a2cc877945d91fd457724f3523 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 31 Oct 2021 18:10:19 +0100 Subject: [PATCH 215/378] Updates README with the changes in 0.9.0.1 --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4f108d..ec39a93 100644 --- a/README.md +++ b/README.md @@ -292,7 +292,8 @@ gates: cosmetic: rememberDestination - Whether to set the first destination as the last used destination for all gates sortNetworkDestinations - If true, network lists will be sorted alphabetically. - signColor - This allows you to specify the color of the gate signs. + mainSignColor - This allows you to specify the color of the gate signs. + highlightSignColor - This allows you to specify the color of the sign markings. integrity: destroyedByExplosion - Whether to destroy a stargate with explosions, or stop an explosion if it contains a gates controls. verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when an old stargate is loaded at startup. @@ -366,6 +367,13 @@ bungeeSign=Teleport to # Changes +#### \[Version 0.9.0.1] EpicKnarvik97 fork + +- Adds the highlightSignColor option and renames the signColor option to mainSignColor +- Fixes some inconsistencies in sign coloring by using the highlight color for all markings +- Fixes the order in which configs are loaded to prevent an exception +- Adds migrations for the config change + #### \[Version 0.9.0.0] EpicKnarvik97 fork - Changes entire path structure to a more modern and maven-compliant one From 89956cf3597e94dc57021d899635b85c59aff11f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 31 Oct 2021 19:51:33 +0100 Subject: [PATCH 216/378] Updates the plugin version in plugin.yml --- src/main/resources/plugin.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1f4abd2..71c9ebf 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,10 +1,10 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.0 -description: Stargate mod for Bukkit +version: 0.9.0.1 +description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] -website: https://knarcraft.net +website: https://git.knarcraft.net/EpicKnarvik97/Stargate api-version: 1.17 softdepend: [ Vault ] commands: From b98aec4a20efbbb9ac695c8951733a52b2686f24 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 00:38:36 +0100 Subject: [PATCH 217/378] 0.9.0.2 Fixes a bug in the code to prevent nether portals from generating in the nether --- README.md | 4 ++++ pom.xml | 2 +- .../stargate/listener/PortalEventListener.java | 13 ++++++++----- src/main/resources/plugin.yml | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ec39a93..b8c7f5d 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,10 @@ bungeeSign=Teleport to # Changes +#### \[Version 0.9.0.2] EpicKnarvik97 fork + +- Fixes a bug causing Stargates using NETHER_PORTAL blocks to generate nether portals in the nether. + #### \[Version 0.9.0.1] EpicKnarvik97 fork - Adds the highlightSignColor option and renames the signColor option to mainSignColor diff --git a/pom.xml b/pom.xml index 45ad153..4e11f14 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.1 + 0.9.0.2 diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index d739e2c..203f2e8 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.FromTheEndTeleportation; import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; @@ -8,7 +9,6 @@ import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -37,11 +37,14 @@ public class PortalEventListener implements Listener { if (event.isCancelled()) { return; } - //Cancel nether portal creation when the portal is a StarGate portal - for (BlockState block : event.getBlocks()) { - if (PortalHandler.getByBlock(block.getBlock()) != null) { + //Unnecessary nether portal creation is only triggered by nether pairing + if (event.getReason() == PortalCreateEvent.CreateReason.NETHER_PAIR) { + //If an entity is standing in a Stargate entrance, it can be assumed that the creation is a mistake + Entity entity = event.getEntity(); + if (entity != null && PortalHandler.getByAdjacentEntrance(entity.getLocation()) != null) { + Stargate.debug("PortalEventListener::onPortalCreation", + "Cancelled nether portal create event"); event.setCancelled(true); - return; } } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 71c9ebf..d25782d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.1 +version: 0.9.0.2 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 91a0316e6ec311b040093371a46f6ec93be7e663 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 13:54:31 +0100 Subject: [PATCH 218/378] Adds a missing insufficient funds message when checking if vehicle passengers can pay for the teleportation --- .../knarcraft/stargate/listener/VehicleEventListener.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 6793abc..43e7f38 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -154,9 +154,13 @@ public class VehicleEventListener implements Listener { return false; } - //Transfer payment if necessary + //Check if the player is able to afford the teleport fee int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal); - return cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); + boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); + if (!canAffordFee) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); + } + return canAffordFee; } } From 2a6148068415f4441887670dc74eb733a6dd5013 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 15:13:22 +0100 Subject: [PATCH 219/378] Adds UUID fetching on player join. See #12 Whenever a player joins, their names will be checked against a map containing all names which need to be migrated to UUID. All portals the player has created which still use the player name will be updated. --- .../listener/PlayerEventListener.java | 41 +------ .../stargate/portal/PortalOwner.java | 16 +++ .../stargate/utility/BungeeHelper.java | 36 ++++++ .../stargate/utility/UUIDMigrationHelper.java | 111 ++++++++++++++++++ 4 files changed, 168 insertions(+), 36 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 4816eb2..f428ac2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.portal.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.UUIDMigrationHelper; import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -42,6 +43,9 @@ public class PlayerEventListener implements Listener { */ @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { + //Migrate player name to UUID if necessary + UUIDMigrationHelper.migrateUUID(event.getPlayer()); + if (!Stargate.getGateConfig().enableBungee()) { return; } @@ -154,7 +158,7 @@ public class PlayerEventListener implements Listener { //Decide if the user should be teleported to another bungee server if (entrancePortal.getOptions().isBungee()) { - if (bungeeTeleport(player, entrancePortal, event)) { + if (BungeeHelper.bungeeTeleport(player, entrancePortal, event)) { Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); } return false; @@ -306,39 +310,4 @@ public class PlayerEventListener implements Listener { return false; } - /** - * Teleports a player to a bungee gate - * - * @param player

The player to teleport

- * @param entrancePortal

The gate the player is entering from

- * @param event

The event causing the teleportation

- * @return

True if the teleportation was successful

- */ - private boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { - //Check if bungee is actually enabled - if (!Stargate.getGateConfig().enableBungee()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); - entrancePortal.getPortalOpener().closePortal(false); - return false; - } - - //Teleport the player back to this gate, for sanity's sake - new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); - - //Send the SGBungee packet first, it will be queued by BC if required - if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { - Stargate.debug("bungeeTeleport", "Unable to send teleportation message"); - return false; - } - - //Send the connect-message to make the player change server - if (!BungeeHelper.changeServer(player, entrancePortal)) { - Stargate.debug("bungeeTeleport", "Unable to change server"); - return false; - } - - Stargate.debug("bungeeTeleport", "Teleported player to another server"); - return true; - } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java b/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java index 019f57d..eb92fe8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java @@ -43,6 +43,22 @@ public class PortalOwner { return ownerUUID; } + /** + * Sets the unique id for a portal owner without one + * + *

This method is only meant to be used to set the unique id for an owner without one. If the owner already has + * an unique id, an exception will be thrown.

+ * + * @param uniqueId

The new unique id for the portal owner

+ */ + public void setUUID(UUID uniqueId) { + if (ownerUUID == null) { + ownerUUID = uniqueId; + } else { + throw new IllegalArgumentException("An existing UUID cannot be overwritten."); + } + } + /** * Gets the name of this owner * diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 81f608e..35229c2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerMoveEvent; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -169,4 +170,39 @@ public final class BungeeHelper { } } + /** + * Teleports a player to a bungee gate + * + * @param player

The player to teleport

+ * @param entrancePortal

The gate the player is entering from

+ * @param event

The event causing the teleportation

+ * @return

True if the teleportation was successful

+ */ + public static boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { + //Check if bungee is actually enabled + if (!Stargate.getGateConfig().enableBungee()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + entrancePortal.getPortalOpener().closePortal(false); + return false; + } + + //Teleport the player back to this gate, for sanity's sake + new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); + + //Send the SGBungee packet first, it will be queued by BC if required + if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { + Stargate.debug("bungeeTeleport", "Unable to send teleportation message"); + return false; + } + + //Send the connect-message to make the player change server + if (!BungeeHelper.changeServer(player, entrancePortal)) { + Stargate.debug("bungeeTeleport", "Unable to change server"); + return false; + } + + Stargate.debug("bungeeTeleport", "Teleported player to another server"); + return true; + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java new file mode 100644 index 0000000..e58141c --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -0,0 +1,111 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalOwner; +import net.knarcraft.stargate.portal.PortalRegistry; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +/** + * Helps migrate player names to UUID where necessary + */ +public class UUIDMigrationHelper { + + private static Map> playerNamesToMigrate; + + /** + * Migrates the player's name to a UUID + * + *

If any portals are missing a UUID for their owner, and the given player is the owner of those portals, the + * given player's UUID will be used as UUID for the portals' owner.

+ * + * @param player

The player to migrate

+ */ + public static void migrateUUID(OfflinePlayer player) { + Map> playersToMigrate = getPlayersToMigrate(); + String playerName = player.getName(); + + //Nothing to do + if (!playersToMigrate.containsKey(playerName)) { + return; + } + + Stargate.debug("PlayerEventListener::migrateUUID", String.format("Migrating name to UUID for player %s", + playerName)); + List portalsOwned = playersToMigrate.get(playerName); + if (portalsOwned == null) { + return; + } + + migratePortalsToUUID(portalsOwned, player.getUniqueId()); + + //Remove the player to prevent the migration to happen every time the player joins + playersToMigrate.remove(playerName); + } + + /** + * Migrates a list of portals to use UUID instead of only player name + * + * @param portals

The portals to migrate

+ * @param uniqueId

The unique ID of the portals' owner

+ */ + private static void migratePortalsToUUID(List portals, UUID uniqueId) { + Set worldsToSave = new HashSet<>(); + + //Get the real portal from the copy and set UUID + for (Portal portalCopy : portals) { + Portal portal = PortalHandler.getByName(portalCopy.getName(), portalCopy.getNetwork()); + if (portal != null) { + portal.getOwner().setUUID(uniqueId); + worldsToSave.add(portal.getWorld()); + } + } + + //Need to make sure the changes are saved + for (World world : worldsToSave) { + PortalFileHelper.saveAllPortals(world); + } + } + + /** + * Gets all player names which need to be migrated to UUIDs + * + * @return

The player names to migrate

+ */ + private static Map> getPlayersToMigrate() { + //Make sure to only go through portals once + if (playerNamesToMigrate != null) { + return playerNamesToMigrate; + } + + playerNamesToMigrate = new HashMap<>(); + for (Portal portal : PortalRegistry.getAllPortals()) { + PortalOwner owner = portal.getOwner(); + String ownerName = owner.getName(); + + //If a UUID is missing, add the portal to the list owned by the player + if (owner.getUUID() == null) { + List portalList = playerNamesToMigrate.get(ownerName); + if (portalList == null) { + List newList = new ArrayList<>(); + newList.add(portal); + playerNamesToMigrate.put(ownerName, newList); + } else { + portalList.add(portal); + } + } + } + return playerNamesToMigrate; + } + +} From 2b5d79158191abaeaac8407877bcd8ec26edc112 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 16:26:46 +0100 Subject: [PATCH 220/378] Adds the EntityTeleporter for generic teleportation of entities --- .../stargate/portal/EntityTeleporter.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java diff --git a/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java new file mode 100644 index 0000000..c14bce4 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java @@ -0,0 +1,69 @@ +package net.knarcraft.stargate.portal; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.event.StargateEntityPortalEvent; +import org.bukkit.Location; +import org.bukkit.entity.Entity; + +/** + * The portal teleporter takes care of the actual portal teleportation for any entities + */ +public class EntityTeleporter extends Teleporter { + + private final Entity teleportingEntity; + + /** + * Instantiates a new portal teleporter + * + * @param portal

The portal which is the target of the teleportation

+ */ + public EntityTeleporter(Portal portal, Entity teleportingEntity) { + super(portal); + this.teleportingEntity = teleportingEntity; + } + + /** + * Teleports an entity to this teleporter's portal + * + * @param origin

The portal the entity is teleporting from

+ */ + public void teleport(Portal origin) { + Location traveller = teleportingEntity.getLocation(); + Location exit = getExit(teleportingEntity, traveller); + + //Rotate the entity to face out from the portal + adjustRotation(exit); + + //Call the StargateEntityPortalEvent to allow plugins to change destination + if (!origin.equals(portal)) { + exit = triggerEntityPortalEvent(origin, exit); + if (exit == null) { + return; + } + } + + //Load chunks to make sure not to teleport to the void + loadChunks(); + + teleportingEntity.teleport(exit); + } + + /** + * Triggers the entity portal event to allow plugins to change the exit location + * + * @param origin

The origin portal teleported from

+ * @param exit

The exit location to teleport the entity to

+ * @return

The location the entity should be teleported to, or null if the event was cancelled

+ */ + protected Location triggerEntityPortalEvent(Portal origin, Location exit) { + StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingEntity, origin, + portal, exit); + Stargate.getInstance().getServer().getPluginManager().callEvent(stargateEntityPortalEvent); + //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake + if (stargateEntityPortalEvent.isCancelled()) { + new EntityTeleporter(origin, teleportingEntity).teleport(origin); + return null; + } + return stargateEntityPortalEvent.getExit(); + } +} From 8bb9c464d65963f2c36c1dfc29cb7322de942735 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 16:27:29 +0100 Subject: [PATCH 221/378] Adds some code for teleporting creatures leashed by a player --- .../knarcraft/stargate/portal/Teleporter.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index 30ffecb..c3e02cb 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -13,7 +13,9 @@ import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Slab; import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitScheduler; import java.util.ArrayList; @@ -247,4 +249,21 @@ public abstract class Teleporter { return chunksToLoad; } + /** + * Teleports any creatures leashed by the player + * + * @param player

The player which is teleported

+ * @param origin

The portal the player is teleporting from

+ */ + protected void teleportLeashedCreatures(Player player, Portal origin) { + //Find any nearby leashed entities to teleport with the player + List nearbyEntities = player.getNearbyEntities(15, 15, 15); + for (Entity entity : nearbyEntities) { + //Teleport all creatures leashed by the player to the portal the player is to exit from + if (entity instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder() == player) { + new EntityTeleporter(portal, creature).teleport(origin); + } + } + } + } From b8d98c26d4f0002658c50c5f0989ddfaae5944ff Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 16:28:13 +0100 Subject: [PATCH 222/378] Adds triggers for teleporting leashed entities --- .../stargate/portal/PlayerTeleporter.java | 3 + .../stargate/portal/VehicleTeleporter.java | 58 ++++++++----------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java index 8bf1191..611d6e4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java @@ -48,6 +48,9 @@ public class PlayerTeleporter extends Teleporter { //Load chunks to make sure not to teleport to the void loadChunks(); + //Teleport any creatures leashed by the player in a 10-block range + teleportLeashedCreatures(player, origin); + //If no event is passed in, assume it's a teleport, and act as such if (event == null) { player.teleport(exit); diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java index 34ee9d3..100926d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -1,12 +1,12 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.event.StargateEntityPortalEvent; import net.knarcraft.stargate.utility.DirectionHelper; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; import org.bukkit.util.Vector; @@ -15,7 +15,7 @@ import java.util.List; /** * The portal teleporter takes care of the actual portal teleportation for any vehicles */ -public class VehicleTeleporter extends Teleporter { +public class VehicleTeleporter extends EntityTeleporter { private final Vehicle teleportingVehicle; @@ -26,7 +26,7 @@ public class VehicleTeleporter extends Teleporter { * @param teleportingVehicle

The teleporting vehicle

*/ public VehicleTeleporter(Portal portal, Vehicle teleportingVehicle) { - super(portal); + super(portal, teleportingVehicle); this.teleportingVehicle = teleportingVehicle; } @@ -36,8 +36,9 @@ public class VehicleTeleporter extends Teleporter { *

It is assumed that if a vehicle contains any players, their permissions have already been validated before * calling this method.

* - * @param origin

The portal the vehicle teleports from

+ * @param origin

The portal the vehicle is teleporting from

*/ + @Override public void teleport(Portal origin) { Location traveller = teleportingVehicle.getLocation(); Location exit = getExit(teleportingVehicle, traveller); @@ -63,7 +64,7 @@ public class VehicleTeleporter extends Teleporter { } //Teleport the vehicle - teleportVehicle(exit, newVelocity); + teleportVehicle(exit, newVelocity, origin); } /** @@ -71,8 +72,9 @@ public class VehicleTeleporter extends Teleporter { * * @param exit

The location the vehicle should be teleported to

* @param newVelocity

The velocity to give the vehicle right after teleportation

+ * @param origin

The portal the vehicle teleported from

*/ - private void teleportVehicle(Location exit, Vector newVelocity) { + private void teleportVehicle(Location exit, Vector newVelocity, Portal origin) { //Load chunks to make sure not to teleport to the void loadChunks(); @@ -80,10 +82,10 @@ public class VehicleTeleporter extends Teleporter { if (!passengers.isEmpty()) { if (!(teleportingVehicle instanceof LivingEntity)) { //Teleport a normal vehicle with passengers (minecart or boat) - putPassengersInNewVehicle(passengers, exit, newVelocity); + putPassengersInNewVehicle(passengers, exit, newVelocity, origin); } else { //Teleport a living vehicle with passengers (pig, horse, donkey, strider) - teleportLivingVehicle(exit, passengers); + teleportLivingVehicle(exit, passengers, origin); } } else { //Teleport an empty vehicle @@ -93,35 +95,17 @@ public class VehicleTeleporter extends Teleporter { } } - /** - * Triggers the entity portal event to allow plugins to change the exit location - * - * @param origin

The origin portal teleported from

- * @param exit

The exit location to teleport the vehicle to

- * @return

The location the vehicle should be teleported to, or null if the event was cancelled

- */ - private Location triggerEntityPortalEvent(Portal origin, Location exit) { - StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingVehicle, origin, - portal, exit); - Stargate.getInstance().getServer().getPluginManager().callEvent(stargateEntityPortalEvent); - //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake - if (stargateEntityPortalEvent.isCancelled()) { - new VehicleTeleporter(origin, teleportingVehicle).teleport(origin); - return null; - } - return stargateEntityPortalEvent.getExit(); - } - /** * Teleport a vehicle which is not a minecart or a boat * * @param exit

The location the vehicle will exit

* @param passengers

The passengers of the vehicle

+ * @param origin

The portal the vehicle teleported from

*/ - private void teleportLivingVehicle(Location exit, List passengers) { + private void teleportLivingVehicle(Location exit, List passengers, Portal origin) { teleportingVehicle.eject(); teleportingVehicle.teleport(exit); - handleVehiclePassengers(passengers, teleportingVehicle, 2); + handleVehiclePassengers(passengers, teleportingVehicle, 2, origin); } /** @@ -134,9 +118,10 @@ public class VehicleTeleporter extends Teleporter { * @param passengers

A list of all passengers in the vehicle

* @param exit

The exit location to spawn the new vehicle on

* @param newVelocity

The new velocity of the new vehicle

+ * @param origin

The portal the vehicle teleported from

*/ private void putPassengersInNewVehicle(List passengers, Location exit, - Vector newVelocity) { + Vector newVelocity, Portal origin) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { Stargate.logWarning("Unable to get the world to teleport the vehicle to"); @@ -149,7 +134,7 @@ public class VehicleTeleporter extends Teleporter { teleportingVehicle.remove(); //Set rotation, add passengers and restore velocity newVehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle, 1); + handleVehiclePassengers(passengers, newVehicle, 1, origin); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> newVehicle.setVelocity(newVelocity), 1); } @@ -159,12 +144,17 @@ public class VehicleTeleporter extends Teleporter { * @param passengers

The passengers to handle

* @param vehicle

The vehicle the passengers should be put into

* @param delay

The amount of milliseconds to wait before adding the vehicle passengers

+ * @param origin

The portal the vehicle teleported from

*/ - private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay) { + private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay, Portal origin) { for (Entity passenger : passengers) { passenger.eject(); - scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> teleportAndAddPassenger(vehicle, passenger), - delay); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { + if (passenger instanceof Player player) { + teleportLeashedCreatures(player, origin); + } + teleportAndAddPassenger(vehicle, passenger); + }, delay); } } From 62661f65f4b2403d06966795ccde11aeeb016d8d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 16:32:56 +0100 Subject: [PATCH 223/378] Updates info and version to 0.9.0.3 --- README.md | 5 +++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b8c7f5d..26619c0 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,11 @@ bungeeSign=Teleport to # Changes +#### \[Version 0.9.0.3] EpicKnarvik97 fork + +- Adds a missing error message when a player in a vehicle cannot pay the teleportation fee +- Adds UUID migration to automatically update player names to UUID when possible + #### \[Version 0.9.0.2] EpicKnarvik97 fork - Fixes a bug causing Stargates using NETHER_PORTAL blocks to generate nether portals in the nether. diff --git a/pom.xml b/pom.xml index 4e11f14..c274170 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.2 + 0.9.0.3 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d25782d..2505b3b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.2 +version: 0.9.0.3 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 20c3c93c06a6ac9ca6579d06163d44703759f27d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 17:54:38 +0100 Subject: [PATCH 224/378] Adds a few fixes which seem to make leash teleportation work as expected Un-leashes and re-leashes teleported leashed entities Delays leashed creature teleportation and the re-leashing to prevent odd behavior such as infinite leash or no-ai creature --- .../stargate/portal/PlayerTeleporter.java | 2 +- .../knarcraft/stargate/portal/Teleporter.java | 31 ++++++++++++++++--- .../stargate/portal/VehicleTeleporter.java | 1 + 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java index 611d6e4..542fc78 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java @@ -48,7 +48,7 @@ public class PlayerTeleporter extends Teleporter { //Load chunks to make sure not to teleport to the void loadChunks(); - //Teleport any creatures leashed by the player in a 10-block range + //Teleport any creatures leashed by the player in a 15-block range teleportLeashedCreatures(player, origin); //If no event is passed in, assume it's a teleport, and act as such diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index c3e02cb..2160e74 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -257,13 +257,34 @@ public abstract class Teleporter { */ protected void teleportLeashedCreatures(Player player, Portal origin) { //Find any nearby leashed entities to teleport with the player - List nearbyEntities = player.getNearbyEntities(15, 15, 15); - for (Entity entity : nearbyEntities) { - //Teleport all creatures leashed by the player to the portal the player is to exit from - if (entity instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder() == player) { + List nearbyEntities = getLeashedCreatures(player); + //Teleport all creatures leashed by the player to the portal the player is to exit from + for (Creature creature : nearbyEntities) { + creature.setLeashHolder(null); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { new EntityTeleporter(portal, creature).teleport(origin); - } + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 3); + }, 2); } } + /** + * Gets all creatures leashed by a player within the given range + * + * @param player

The player to check

+ * @return

A list of all creatures the player is holding in a leash (lead)

+ */ + protected List getLeashedCreatures(Player player) { + List leashedCreatures = new ArrayList<>(); + //Find any nearby leashed entities to teleport with the player + List nearbyEntities = player.getNearbyEntities(15, 15, 15); + //Teleport all creatures leashed by the player to the portal the player is to exit from + for (Entity entity : nearbyEntities) { + if (entity instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder() == player) { + leashedCreatures.add(creature); + } + } + return leashedCreatures; + } + } diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java index 100926d..aee44fc 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -151,6 +151,7 @@ public class VehicleTeleporter extends EntityTeleporter { passenger.eject(); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { if (passenger instanceof Player player) { + //Teleport any creatures leashed by the player in a 15-block range teleportLeashedCreatures(player, origin); } teleportAndAddPassenger(vehicle, passenger); From aff00829062a5efd522e7b8c0c1b561f5f6ff9f3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 18:44:10 +0100 Subject: [PATCH 225/378] Adds a config option to disable leashed creatures from teleporting with a player --- .../stargate/config/StargateGateConfig.java | 12 +++++++++++- .../net/knarcraft/stargate/portal/Teleporter.java | 5 +++++ src/main/resources/config.yml | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 917f91b..f8da09e 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -13,6 +13,7 @@ public final class StargateGateConfig { private int maxGatesEachNetwork = 0; private boolean rememberDestination = false; private boolean handleVehicles = true; + private boolean handleLeashedCreatures = true; private boolean sortNetworkDestinations = false; private boolean protectEntrance = false; private boolean enableBungee = true; @@ -76,6 +77,15 @@ public final class StargateGateConfig { return handleVehicles; } + /** + * Gets whether leashed creatures should be teleported with a teleporting player + * + * @return

Whether leashed creatures should be handled

+ */ + public boolean handleLeashedCreatures() { + return handleLeashedCreatures; + } + /** * Gets whether the list of destinations within a network should be sorted * @@ -142,6 +152,7 @@ public final class StargateGateConfig { //Functionality handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); + handleLeashedCreatures = newConfig.getBoolean("gates.functionality.handleLeashedCreatures"); enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); //Integrity @@ -173,5 +184,4 @@ public final class StargateGateConfig { Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); PortalSignDrawer.setColors(ChatColor.BLACK, ChatColor.WHITE); } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java index 2160e74..1cf8364 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/Teleporter.java @@ -256,6 +256,11 @@ public abstract class Teleporter { * @param origin

The portal the player is teleporting from

*/ protected void teleportLeashedCreatures(Player player, Portal origin) { + //If this feature is disabled, just return + if (!Stargate.getGateConfig().handleLeashedCreatures()) { + return; + } + //Find any nearby leashed entities to teleport with the player List nearbyEntities = getLeashedCreatures(player); //Teleport all creatures leashed by the player to the portal the player is to exit from diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index eac074b..c67aa5a 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,6 +9,7 @@ # language - The language file to load for messages # rememberDestination - Whether to remember the cursor location between uses # handleVehicles - Whether to allow vehicles through gates +# handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player # sortNetworkDestinations - Whether to sort network lists alphabetically # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) # mainSignColor - The color used for drawing signs (Default: BLACK). @@ -49,6 +50,7 @@ gates: functionality: enableBungee: false handleVehicles: true + handleLeashedCreatures: true economy: useEconomy: false createCost: 0 From 3c4d10ae3fd259023cadb3e3b55a8ab62a90072c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 18:49:05 +0100 Subject: [PATCH 226/378] Updates changelog and version to 0.9.0.4 --- README.md | 7 +++++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26619c0..af949eb 100644 --- a/README.md +++ b/README.md @@ -301,6 +301,7 @@ gates: functionality: enableBungee - Enable this for BungeeCord support. This allows portals across Bungee servers. handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. + handleLeashedCreatures - Whether or not to handle creatures leashed by a player going through gates. Set to false to disallow leashed creatures going through gates. economy: useEconomy - Whether or not to enable Economy using Vault (must have the Vault plugin) createCost - The cost to create a stargate @@ -367,6 +368,12 @@ bungeeSign=Teleport to # Changes +#### \[Version 0.9.0.4] EpicKnarvik97 fork + +- Adds teleportation of leashed creatures. By default, any creature connected to a player by a lead will be teleported + with the player through stargates, even if the player is in a vehicle. This behavior can be disabled in the config + file. + #### \[Version 0.9.0.3] EpicKnarvik97 fork - Adds a missing error message when a player in a vehicle cannot pay the teleportation fee diff --git a/pom.xml b/pom.xml index c274170..f10ab1c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.3 + 0.9.0.4 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2505b3b..6867590 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.3 +version: 0.9.0.4 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From cab99e11b0059719d7c2a74db69520941ab9b78d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 1 Nov 2021 19:25:52 +0100 Subject: [PATCH 227/378] Adds leashed teleportation as a feature to the README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index af949eb..9be727a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ can share a network or be split into clusters; they can be hidden on a network o - Multiple built-in languages (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) - Teleport across worlds or servers (BungeeCord supported) - Vehicle teleportation -- teleport minecarts, boats, horses, pigs and striders +- Leashed teleportation -- teleport any creature in a leash with the player - Underwater portals -- portals can be placed underwater as long as a waterproof button is used - API available -- using the API, a lot of behavior can be changed - Button customization -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) From e5c1ad1f3a40c61e31bd84a795e965d47bb62f74 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 3 Nov 2021 15:55:56 +0100 Subject: [PATCH 228/378] 0.9.0.5 - Adds three new options to disable features of vehicle teleportation with more granularity #9 --- README.md | 11 +++ pom.xml | 2 +- .../stargate/config/StargateGateConfig.java | 47 +++++++++++++ .../listener/PlayerEventListener.java | 3 +- .../listener/VehicleEventListener.java | 9 ++- .../stargate/portal/EntityTeleporter.java | 6 +- .../stargate/portal/VehicleTeleporter.java | 67 +++++++++++++++++-- src/main/resources/config.yml | 8 ++- src/main/resources/plugin.yml | 2 +- 9 files changed, 142 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9be727a..2c36786 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,9 @@ gates: functionality: enableBungee - Enable this for BungeeCord support. This allows portals across Bungee servers. handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates. + handleEmptyVehicles - Whether or not to handle empty vehicles going through gates (chest/hopper/tnt/furnace minecarts included). + handleCreatureTransportation - Whether or not to handle players that transport creatures by sending vehicles (minecarts, boats) through gates. + handleNonPlayerVehicles - Whether or not to handle vehicles with a passenger which is not a player going through gates (pigs, horses, villagers, creepers, etc.). handleCreatureTransportation must be enabled. handleLeashedCreatures - Whether or not to handle creatures leashed by a player going through gates. Set to false to disallow leashed creatures going through gates. economy: useEconomy - Whether or not to enable Economy using Vault (must have the Vault plugin) @@ -369,6 +372,14 @@ bungeeSign=Teleport to # Changes +#### \[Version 0.9.0.5] EpicKnarvik97 fork + +- Adds an option to stargate functionality to disable all teleportation of creatures +- Adds an option to stargate functionality to disable all teleportation of empty minecarts +- Adds an option to stargate functionality to disable teleportation of creatures if no player is present in the vehicle +- Prevents a player in a vehicle from teleporting without the vehicle if vehicle teleportation is disabled +- Prevents an infinite number of teleportation messages if vehicle teleportation is detected but denied + #### \[Version 0.9.0.4] EpicKnarvik97 fork - Adds teleportation of leashed creatures. By default, any creature connected to a player by a lead will be teleported diff --git a/pom.xml b/pom.xml index f10ab1c..ab6bb5f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.4 + 0.9.0.5 diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index f8da09e..be13cdc 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -13,6 +13,9 @@ public final class StargateGateConfig { private int maxGatesEachNetwork = 0; private boolean rememberDestination = false; private boolean handleVehicles = true; + private boolean handleEmptyVehicles = true; + private boolean handleCreatureTransportation = true; + private boolean handleNonPlayerVehicles = true; private boolean handleLeashedCreatures = true; private boolean sortNetworkDestinations = false; private boolean protectEntrance = false; @@ -77,6 +80,47 @@ public final class StargateGateConfig { return handleVehicles; } + /** + * Gets whether vehicles with no passengers should be handled + * + *

The handle vehicles option overrides this option if disabled. This option allows empty passenger + * minecarts/boats, but also chest/tnt/hopper/furnace minecarts to teleport through stargates.

+ * + * @return

Whether vehicles without passengers should be handled

+ */ + public boolean handleEmptyVehicles() { + return handleEmptyVehicles; + } + + /** + * Gets whether vehicles containing creatures should be handled + * + *

The handle vehicles option overrides this option if disabled. This option allows creatures (pigs, pandas, + * zombies, etc.) to teleport through stargates if in a vehicle.

+ * + * @return

Whether vehicles with creatures should be handled

+ */ + public boolean handleCreatureTransportation() { + return handleCreatureTransportation; + } + + /** + * Gets whether vehicles containing a creature, but not a player should be handled + * + *

The handle vehicles option, and the handle creature transportation option, override this option if disabled. + * This option allows creatures (pigs, pandas, zombies, etc.) to teleport through stargates if in a vehicle, even + * if no player is in the vehicle. + * As it is not possible to check if a creature is allowed through a stargate, they will be able to go through + * regardless of whether the initiating player is allowed to enter the stargate. Enabling this is necessary to + * teleport creatures using minecarts, but only handleCreatureTransportation is required to teleport creatures + * using a boat manned by a player.

+ * + * @return

Whether non-empty vehicles without a player should be handled

+ */ + public boolean handleNonPlayerVehicles() { + return handleNonPlayerVehicles; + } + /** * Gets whether leashed creatures should be teleported with a teleporting player * @@ -152,6 +196,9 @@ public final class StargateGateConfig { //Functionality handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); + handleEmptyVehicles = newConfig.getBoolean("gates.functionality.handleEmptyVehicles"); + handleCreatureTransportation = newConfig.getBoolean("gates.functionality.handleCreatureTransportation"); + handleNonPlayerVehicles = newConfig.getBoolean("gates.functionality.handleNonPlayerVehicles"); handleLeashedCreatures = newConfig.getBoolean("gates.functionality.handleLeashedCreatures"); enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index f428ac2..42bb9ee 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -90,7 +90,8 @@ public class PlayerEventListener implements Listener { Entity playerVehicle = player.getVehicle(); //If the player is in a vehicle, but vehicle handling is disabled, just ignore the player - if (playerVehicle == null || Stargate.getGateConfig().handleVehicles()) { + if (playerVehicle == null || (playerVehicle instanceof LivingEntity && + Stargate.getGateConfig().handleVehicles())) { teleportPlayer(playerVehicle, player, entrancePortal, destination, event); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 43e7f38..5fb2f3f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -115,9 +115,12 @@ public class VehicleEventListener implements Listener { } } - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); - new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); - entrancePortal.getPortalOpener().closePortal(false); + //Teleport the vehicle and inform the user if the vehicle was teleported + boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); + if (teleported) { + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + entrancePortal.getPortalOpener().closePortal(false); + } } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java index c14bce4..ba067a8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java @@ -26,8 +26,9 @@ public class EntityTeleporter extends Teleporter { * Teleports an entity to this teleporter's portal * * @param origin

The portal the entity is teleporting from

+ * @return

True if the entity was teleported. False otherwise

*/ - public void teleport(Portal origin) { + public boolean teleport(Portal origin) { Location traveller = teleportingEntity.getLocation(); Location exit = getExit(teleportingEntity, traveller); @@ -38,7 +39,7 @@ public class EntityTeleporter extends Teleporter { if (!origin.equals(portal)) { exit = triggerEntityPortalEvent(origin, exit); if (exit == null) { - return; + return false; } } @@ -46,6 +47,7 @@ public class EntityTeleporter extends Teleporter { loadChunks(); teleportingEntity.teleport(exit); + return true; } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java index aee44fc..07ad185 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.StargateGateConfig; import net.knarcraft.stargate.utility.DirectionHelper; import org.bukkit.Location; import org.bukkit.World; @@ -37,9 +38,10 @@ public class VehicleTeleporter extends EntityTeleporter { * calling this method.

* * @param origin

The portal the vehicle is teleporting from

+ * @return

True if the vehicle was teleported. False otherwise

*/ @Override - public void teleport(Portal origin) { + public boolean teleport(Portal origin) { Location traveller = teleportingVehicle.getLocation(); Location exit = getExit(teleportingVehicle, traveller); @@ -59,12 +61,12 @@ public class VehicleTeleporter extends EntityTeleporter { if (!origin.equals(portal)) { exit = triggerEntityPortalEvent(origin, exit); if (exit == null) { - return; + return false; } } //Teleport the vehicle - teleportVehicle(exit, newVelocity, origin); + return teleportVehicle(exit, newVelocity, origin); } /** @@ -73,13 +75,19 @@ public class VehicleTeleporter extends EntityTeleporter { * @param exit

The location the vehicle should be teleported to

* @param newVelocity

The velocity to give the vehicle right after teleportation

* @param origin

The portal the vehicle teleported from

+ * @return

True if the vehicle was teleported. False otherwise

*/ - private void teleportVehicle(Location exit, Vector newVelocity, Portal origin) { + private boolean teleportVehicle(Location exit, Vector newVelocity, Portal origin) { //Load chunks to make sure not to teleport to the void loadChunks(); List passengers = teleportingVehicle.getPassengers(); if (!passengers.isEmpty()) { + //Check if the passengers are allowed according to current config settings + if (!vehiclePassengersAllowed(passengers)) { + return false; + } + if (!(teleportingVehicle instanceof LivingEntity)) { //Teleport a normal vehicle with passengers (minecart or boat) putPassengersInNewVehicle(passengers, exit, newVelocity, origin); @@ -88,11 +96,62 @@ public class VehicleTeleporter extends EntityTeleporter { teleportLivingVehicle(exit, passengers, origin); } } else { + //Check if teleportation of empty vehicles is enabled + if (!Stargate.getGateConfig().handleEmptyVehicles()) { + return false; + } //Teleport an empty vehicle teleportingVehicle.teleport(exit); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> teleportingVehicle.setVelocity(newVelocity), 1); } + return true; + } + + /** + * Checks whether current config values allow the teleportation of the given passengers + * + * @param passengers

The passengers to teleport

+ * @return

True if the passengers are allowed to teleport

+ */ + private boolean vehiclePassengersAllowed(List passengers) { + StargateGateConfig config = Stargate.getGateConfig(); + //Don't teleport if the vehicle contains a creature and creature transportation is disabled + if (containsNonPlayer(passengers) && !config.handleCreatureTransportation()) { + return false; + } + //Don't teleport if the player does not contain a player and non-player vehicles is disabled + return containsPlayer(passengers) || config.handleNonPlayerVehicles(); + } + + /** + * Checks whether a list of entities contains any non-players + * + * @param entities

The list of entities to check

+ * @return

True if at least one entity is not a player

+ */ + private boolean containsNonPlayer(List entities) { + for (Entity entity : entities) { + if (!(entity instanceof Player)) { + return true; + } + } + return false; + } + + /** + * Checks whether a list of entities contains at least one player + * + * @param entities

The list of entities to check

+ * @return

True if at least one player is present among the passengers

+ */ + private boolean containsPlayer(List entities) { + for (Entity entity : entities) { + if (entity instanceof Player) { + return true; + } + } + return false; } /** diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c67aa5a..aa6aec7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -8,7 +8,10 @@ # maxGatesEachNetwork - The maximum number of gates allowed on a network - 0 for unlimited # language - The language file to load for messages # rememberDestination - Whether to remember the cursor location between uses -# handleVehicles - Whether to allow vehicles through gates +# handleVehicles - Whether to allow vehicles through gates. This overrides other vehicle settings +# handleEmptyVehicles - Whether to allow empty vehicles through gates (chest/hopper/tnt/furnace minecarts included) +# handleCreatureTransportation - Whether to allow players to transport creatures by sending vehicles (minecarts, boats) through gates +# handleNonPlayerVehicles - Whether to allow vehicles with a passenger which is not a player through gates. handleCreatureTransportation must be enabled # handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player # sortNetworkDestinations - Whether to sort network lists alphabetically # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) @@ -50,6 +53,9 @@ gates: functionality: enableBungee: false handleVehicles: true + handleEmptyVehicles: true + handleCreatureTransportation: true + handleNonPlayerVehicles: true handleLeashedCreatures: true economy: useEconomy: false diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6867590..f4c8259 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.4 +version: 0.9.0.5 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From e0ac9b41e76d0f278c91585494f4f008137c2fa6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 4 Nov 2021 00:07:03 +0100 Subject: [PATCH 229/378] Adds some sub-packages to the portal package to improve logical structure --- .../net/knarcraft/stargate/config/EconomyConfig.java | 2 +- .../net/knarcraft/stargate/config/StargateConfig.java | 2 +- .../stargate/listener/PlayerEventListener.java | 4 ++-- .../stargate/listener/PortalEventListener.java | 2 +- .../stargate/listener/VehicleEventListener.java | 2 +- .../java/net/knarcraft/stargate/portal/Portal.java | 6 ++++++ .../net/knarcraft/stargate/portal/PortalCreator.java | 6 ++++++ .../net/knarcraft/stargate/portal/PortalHandler.java | 5 +++++ .../net/knarcraft/stargate/portal/PortalOpener.java | 1 + .../knarcraft/stargate/portal/PortalSignDrawer.java | 1 + .../stargate/portal/{ => property}/PortalLocation.java | 2 +- .../stargate/portal/{ => property}/PortalOption.java | 2 +- .../stargate/portal/{ => property}/PortalOptions.java | 2 +- .../stargate/portal/{ => property}/PortalOwner.java | 2 +- .../portal/{ => property}/PortalStructure.java | 4 +++- .../stargate/portal/{ => property/gate}/Gate.java | 2 +- .../portal/{ => property/gate}/GateHandler.java | 2 +- .../portal/{ => property/gate}/GateLayout.java | 2 +- .../portal/{ => teleporter}/EntityTeleporter.java | 3 ++- .../portal/{ => teleporter}/PlayerTeleporter.java | 3 ++- .../stargate/portal/{ => teleporter}/Teleporter.java | 3 ++- .../portal/{ => teleporter}/VehicleTeleporter.java | 3 ++- .../net/knarcraft/stargate/utility/BungeeHelper.java | 2 +- .../net/knarcraft/stargate/utility/EconomyHelper.java | 2 +- .../knarcraft/stargate/utility/PermissionHelper.java | 4 ++-- .../knarcraft/stargate/utility/PortalFileHelper.java | 10 +++++----- .../stargate/utility/UUIDMigrationHelper.java | 2 +- .../net/knarcraft/stargate/portal/GateLayoutTest.java | 2 ++ 28 files changed, 55 insertions(+), 28 deletions(-) rename src/main/java/net/knarcraft/stargate/portal/{ => property}/PortalLocation.java (98%) rename src/main/java/net/knarcraft/stargate/portal/{ => property}/PortalOption.java (98%) rename src/main/java/net/knarcraft/stargate/portal/{ => property}/PortalOptions.java (99%) rename src/main/java/net/knarcraft/stargate/portal/{ => property}/PortalOwner.java (98%) rename src/main/java/net/knarcraft/stargate/portal/{ => property}/PortalStructure.java (96%) rename src/main/java/net/knarcraft/stargate/portal/{ => property/gate}/Gate.java (99%) rename src/main/java/net/knarcraft/stargate/portal/{ => property/gate}/GateHandler.java (99%) rename src/main/java/net/knarcraft/stargate/portal/{ => property/gate}/GateLayout.java (99%) rename src/main/java/net/knarcraft/stargate/portal/{ => teleporter}/EntityTeleporter.java (96%) rename src/main/java/net/knarcraft/stargate/portal/{ => teleporter}/PlayerTeleporter.java (96%) rename src/main/java/net/knarcraft/stargate/portal/{ => teleporter}/Teleporter.java (99%) rename src/main/java/net/knarcraft/stargate/portal/{ => teleporter}/VehicleTeleporter.java (99%) diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index bd2a6c4..10cf01b 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.portal.Gate; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.utility.PermissionHelper; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index f072efd..5b13fe3 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -3,10 +3,10 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.listener.BungeeCordListener; -import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.utility.FileHelper; import net.knarcraft.stargate.utility.PortalFileHelper; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 42bb9ee..a169446 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -2,11 +2,11 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalActivator; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.VehicleTeleporter; +import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; +import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 203f2e8..8510b9e 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -2,9 +2,9 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.FromTheEndTeleportation; -import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 5fb2f3f..2cd7b94 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,7 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.VehicleTeleporter; +import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.PermissionHelper; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index d26e99a..ab5b4ad 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -2,6 +2,12 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.PortalLocation; +import net.knarcraft.stargate.portal.property.PortalOption; +import net.knarcraft.stargate.portal.property.PortalOptions; +import net.knarcraft.stargate.portal.property.PortalOwner; +import net.knarcraft.stargate.portal.property.PortalStructure; import org.bukkit.World; import org.bukkit.entity.Player; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index f041e02..79e8b0b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -4,6 +4,12 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateCreateEvent; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.gate.GateHandler; +import net.knarcraft.stargate.portal.property.PortalLocation; +import net.knarcraft.stargate.portal.property.PortalOption; +import net.knarcraft.stargate.portal.property.PortalOptions; +import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 15592b8..a1bdf08 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -3,6 +3,11 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.gate.GateHandler; +import net.knarcraft.stargate.portal.property.PortalLocation; +import net.knarcraft.stargate.portal.property.PortalOption; +import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.block.Block; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 21484af..448537e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateOpenEvent; +import net.knarcraft.stargate.portal.property.PortalOptions; import org.bukkit.Axis; import org.bukkit.Material; import org.bukkit.block.data.Orientable; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index abad04b..b4117c3 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.ChatColor; import org.bukkit.block.Block; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/portal/PortalLocation.java rename to src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java index 32d5e51..49c09ff 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalLocation.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOption.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/portal/PortalOption.java rename to src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java index 6b68418..fa7365c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOption.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property; /** * Each enum value represents one option a portal can have/use diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/portal/PortalOptions.java rename to src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java index 221fed7..cc1ceb6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOptions.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property; import net.knarcraft.stargate.Stargate; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java similarity index 98% rename from src/main/java/net/knarcraft/stargate/portal/PortalOwner.java rename to src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java index eb92fe8..307621e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property; import net.knarcraft.stargate.Stargate; import org.bukkit.Bukkit; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java similarity index 96% rename from src/main/java/net/knarcraft/stargate/portal/PortalStructure.java rename to src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java index bd97be5..c5c2986 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalStructure.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java @@ -1,8 +1,10 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.property.gate.Gate; /** * The portal structure is responsible for the physical properties of a portal diff --git a/src/main/java/net/knarcraft/stargate/portal/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/portal/Gate.java rename to src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index dd25a9b..18cbf12 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property.gate; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; diff --git a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/portal/GateHandler.java rename to src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index b7a4eb0..ebe3a41 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property.gate; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.utility.GateReader; diff --git a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/portal/GateLayout.java rename to src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java index b2583d7..540983e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java @@ -1,4 +1,4 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.property.gate; import net.knarcraft.stargate.container.RelativeBlockVector; diff --git a/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java similarity index 96% rename from src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java rename to src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java index ba067a8..df12f74 100644 --- a/src/main/java/net/knarcraft/stargate/portal/EntityTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java @@ -1,7 +1,8 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateEntityPortalEvent; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.Location; import org.bukkit.entity.Entity; diff --git a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java similarity index 96% rename from src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java rename to src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index 542fc78..e8232bb 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -1,7 +1,8 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargatePlayerPortalEvent; +import net.knarcraft.stargate.portal.Portal; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; diff --git a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/portal/Teleporter.java rename to src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 1cf8364..a6214cd 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -1,9 +1,10 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EntityHelper; import org.bukkit.Chunk; diff --git a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java similarity index 99% rename from src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java rename to src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 07ad185..87c3288 100644 --- a/src/main/java/net/knarcraft/stargate/portal/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -1,7 +1,8 @@ -package net.knarcraft.stargate.portal; +package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.StargateGateConfig; +import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.utility.DirectionHelper; import org.bukkit.Location; import org.bukkit.World; diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 35229c2..08ce61e 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -1,9 +1,9 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 3a4d84f..d1dc0e4 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -2,7 +2,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; -import net.knarcraft.stargate.portal.PortalOwner; +import net.knarcraft.stargate.portal.property.PortalOwner; import org.bukkit.entity.Player; import java.util.UUID; diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 2b395f3..ab83f53 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -2,9 +2,9 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateAccessEvent; -import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; -import net.knarcraft.stargate.portal.PortalOption; +import net.knarcraft.stargate.portal.property.PortalOption; +import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 6ce60e2..cbf4a16 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -2,14 +2,14 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; -import net.knarcraft.stargate.portal.Gate; -import net.knarcraft.stargate.portal.GateHandler; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalLocation; -import net.knarcraft.stargate.portal.PortalOptions; -import net.knarcraft.stargate.portal.PortalOwner; import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.gate.GateHandler; +import net.knarcraft.stargate.portal.property.PortalLocation; +import net.knarcraft.stargate.portal.property.PortalOptions; +import net.knarcraft.stargate.portal.property.PortalOwner; import org.bukkit.World; import java.io.BufferedWriter; diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java index e58141c..4e33457 100644 --- a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -3,8 +3,8 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.PortalOwner; import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.portal.property.PortalOwner; import org.bukkit.OfflinePlayer; import org.bukkit.World; diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 72c2517..5f85dbe 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -5,6 +5,8 @@ import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.WorldMock; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.portal.property.gate.GateHandler; +import net.knarcraft.stargate.portal.property.gate.GateLayout; import org.bukkit.Material; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; From 8c37b11484fe6328d1897fd89dc017fa3b857154 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Nov 2021 14:04:24 +0100 Subject: [PATCH 230/378] Increases the delay before setting the leash holder for teleported creatures as they sometimes got stuck --- .../net/knarcraft/stargate/portal/teleporter/Teleporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index a6214cd..8cc3e6f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -269,7 +269,7 @@ public abstract class Teleporter { creature.setLeashHolder(null); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { new EntityTeleporter(portal, creature).teleport(origin); - scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 3); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 6); }, 2); } } From f3292cff99b103fdae42681842fa05775484c052 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Nov 2021 19:21:27 +0100 Subject: [PATCH 231/378] Makes containers used as buttons no longer open when right-clicked --- .../stargate/listener/PlayerEventListener.java | 2 +- .../knarcraft/stargate/utility/MaterialHelper.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index a169446..656c173 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -281,7 +281,7 @@ public class PlayerEventListener implements Listener { } PermissionHelper.openPortal(player, portal); - if (portal.getPortalOpener().isOpenFor(player)) { + if (portal.getPortalOpener().isOpenFor(player) && !MaterialHelper.isContainer(block.getType())) { event.setUseInteractedBlock(Event.Result.ALLOW); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 0a84791..18c2ce3 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -28,6 +28,17 @@ public final class MaterialHelper { material.equals(Material.DEAD_TUBE_CORAL_WALL_FAN); } + /** + * Checks whether the given material is a container + * + * @param material

The material to check

+ * @return

True if the material is a container

+ */ + public static boolean isContainer(Material material) { + return Tag.SHULKER_BOXES.isTagged(material) || material == Material.CHEST || + material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST; + } + /** * Checks whether the given material can be used as a button * @@ -35,8 +46,7 @@ public final class MaterialHelper { * @return

True if the material can be used as a button

*/ public static boolean isButtonCompatible(Material material) { - return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || Tag.SHULKER_BOXES.isTagged(material) || - material == Material.CHEST || material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST; + return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || isContainer(material); } } From 80ff241d4b08098a8a4bb55455040afbd3f5ba67 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Nov 2021 21:38:33 +0100 Subject: [PATCH 232/378] Makes stargates' buttons update when portals are loaded #14 --- .../stargate/portal/PortalCreator.java | 41 +++------ .../stargate/utility/PortalFileHelper.java | 83 ++++++++++++++++++- 2 files changed, 91 insertions(+), 33 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 79e8b0b..bf41a76 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -4,20 +4,18 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateCreateEvent; -import net.knarcraft.stargate.portal.property.gate.Gate; -import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.PortalFileHelper; -import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.block.data.Directional; import org.bukkit.entity.Player; import org.bukkit.event.block.SignChangeEvent; @@ -51,16 +49,16 @@ public class PortalCreator { */ public Portal createPortal() { BlockLocation signLocation = new BlockLocation(event.getBlock()); - Block idParent = signLocation.getParent(); + Block signControlBlock = signLocation.getParent(); //Return early if the sign is not placed on a block, or the block is not a control block - if (idParent == null || GateHandler.getGatesByControlBlock(idParent).length == 0) { + if (signControlBlock == null || GateHandler.getGatesByControlBlock(signControlBlock).length == 0) { Stargate.debug("createPortal", "Control block not registered"); return null; } //The control block is already part of another portal - if (PortalHandler.getByBlock(idParent) != null) { + if (PortalHandler.getByBlock(signControlBlock) != null) { Stargate.debug("createPortal", "idParent belongs to existing stargate"); return null; } @@ -75,7 +73,8 @@ public class PortalCreator { Map portalOptions = PortalHandler.getPortalOptions(player, destinationName, options); //Get the yaw - float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), signLocation.getLocation()); + float yaw = DirectionHelper.getYawFromLocationDifference(signControlBlock.getLocation(), + signLocation.getLocation()); //Get the direction the button should be facing BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw); @@ -86,7 +85,7 @@ public class PortalCreator { Stargate.debug("createPortal", "Finished getting all portal info"); //Try and find a gate matching the new portal - Gate gate = PortalHandler.findMatchingGate(portalLocation, player); + Gate gate = PortalHandler.findMatchingGate(portalLocation, player.getWorld()); if ((gate == null) || (portalLocation.getButtonVector() == null)) { Stargate.debug("createPortal", "Could not find matching gate layout"); return null; @@ -202,9 +201,8 @@ public class PortalCreator { } //Add button if the portal is not always on - if (!portalOptions.isAlwaysOn() && !portalOptions.isBungee()) { - generatePortalButton(portalLocation.getTopLeft(), portalLocation.getButtonVector(), - portalLocation.getButtonFacing()); + if (!portalOptions.isAlwaysOn()) { + PortalFileHelper.generatePortalButton(portal, portalLocation.getButtonFacing()); } //Register the new portal @@ -273,25 +271,6 @@ public class PortalCreator { return true; } - /** - * Generates a button for a portal - * - * @param topLeft

The top-left block of the portal

- * @param buttonVector

A relative vector pointing at the button

- * @param buttonFacing

The direction the button should be facing

- */ - private void generatePortalButton(BlockLocation topLeft, RelativeBlockVector buttonVector, - BlockFace buttonFacing) { - //Go one block outwards to find the button's location rather than the control block's location - BlockLocation button = topLeft.getRelativeLocation(buttonVector.addToVector( - RelativeBlockVector.Property.OUT, 1), portal.getYaw()); - - Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); - buttonData.setFacing(buttonFacing); - button.getBlock().setBlockData(buttonData); - portal.getStructure().setButton(button); - } - /** * Updates the open state of the newly created portal * diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index cbf4a16..6e99c94 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -1,16 +1,23 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.BlockLocation; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; -import net.knarcraft.stargate.portal.property.gate.Gate; -import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.gate.GateHandler; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; import java.io.BufferedWriter; import java.io.File; @@ -255,6 +262,78 @@ public final class PortalFileHelper { //Register the portal, and close it in case it wasn't properly closed when the server stopped PortalHandler.registerPortal(portal); portal.getPortalOpener().closePortal(true); + + //Update the portal's button if it's the wrong material + updatePortalButton(portal); + } + + /** + * Updates a portal's button if it does not match the correct material + * + * @param portal

The portal update the button of

+ */ + private static void updatePortalButton(Portal portal) { + setButtonVector(portal); + BlockLocation buttonLocation = getButtonLocation(portal); + BlockData buttonData = buttonLocation.getBlock().getBlockData(); + if (portal.getOptions().isAlwaysOn()) { + //Clear button if not already air + if (buttonData.getMaterial() != Material.AIR) { + Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, Material.AIR, null)); + } + } else { + //Replace button if the material does not match + if (buttonData.getMaterial() != portal.getGate().getPortalButton()) { + generatePortalButton(portal, DirectionHelper.getBlockFaceFromYaw(portal.getYaw())); + } + } + } + + /** + * Sets the button vector for the given portal + * + *

As the button vector isn't saved, it is null when the portal is loaded. This method allows it to be + * explicitly set when necessary.

+ * + * @param portal

The portal to set button vector for

+ */ + private static void setButtonVector(Portal portal) { + for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { + BlockLocation controlLocation = portal.getLocation().getTopLeft().getRelativeLocation(control, + portal.getYaw()); + if (controlLocation != portal.getLocation().getSignLocation()) { + portal.getLocation().setButtonVector(control); + } + } + } + + /** + * Generates a button for a portal + * + * @param portal

The portal to generate button for

+ * @param buttonFacing

The direction the button should be facing

+ */ + public static void generatePortalButton(Portal portal, BlockFace buttonFacing) { + //Go one block outwards to find the button's location rather than the control block's location + BlockLocation button = getButtonLocation(portal); + + Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); + buttonData.setFacing(buttonFacing); + button.getBlock().setBlockData(buttonData); + portal.getStructure().setButton(button); + } + + /** + * Gets the location of a portal's button + * + * @param portal

The portal to find the button for

+ * @return

The location of the portal's button

+ */ + private static BlockLocation getButtonLocation(Portal portal) { + BlockLocation topLeft = portal.getTopLeft(); + RelativeBlockVector buttonVector = portal.getLocation().getButtonVector(); + return topLeft.getRelativeLocation(buttonVector.addToVector(RelativeBlockVector.Property.OUT, 1), + portal.getYaw()); } } From 0297d62d6d2d7c5c0b0ad80ae16deb3e85f37dc7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Nov 2021 21:40:06 +0100 Subject: [PATCH 233/378] Sets the always on option to true for bungee portals and removes some unnecessary checks --- .../java/net/knarcraft/stargate/portal/Portal.java | 2 +- .../net/knarcraft/stargate/portal/PortalHandler.java | 11 ++++++----- .../stargate/portal/property/PortalOptions.java | 4 ++-- .../net/knarcraft/stargate/thread/StarGateThread.java | 3 +-- .../knarcraft/stargate/utility/MaterialHelper.java | 4 ++-- .../knarcraft/stargate/utility/PermissionHelper.java | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index ab5b4ad..6447baf 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -2,12 +2,12 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.portal.property.PortalStructure; +import net.knarcraft.stargate.portal.property.gate.Gate; import org.bukkit.World; import org.bukkit.entity.Player; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index a1bdf08..c75b6da 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -3,13 +3,14 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; -import net.knarcraft.stargate.portal.property.gate.Gate; -import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.property.PortalStructure; +import net.knarcraft.stargate.portal.property.gate.Gate; +import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -142,12 +143,12 @@ public class PortalHandler { * Tries to find a gate matching the portal the user is trying to create * * @param portalLocation

The location data for the new portal

- * @param player

The player trying to create the new portal

+ * @param world

The world the player is located in

* @return

The matching gate type, or null if no such gate could be found

*/ - static Gate findMatchingGate(PortalLocation portalLocation, Player player) { + static Gate findMatchingGate(PortalLocation portalLocation, World world) { Block signParent = portalLocation.getSignLocation().getParent(); - BlockLocation parent = new BlockLocation(player.getWorld(), signParent.getX(), signParent.getY(), + BlockLocation parent = new BlockLocation(world, signParent.getX(), signParent.getY(), signParent.getZ()); //Get all gates with the used type of control blocks diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java index cc1ceb6..cf9b279 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java @@ -28,9 +28,9 @@ public class PortalOptions { Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); } - if (this.isRandom() && !this.isAlwaysOn()) { + if ((this.isRandom() || this.isBungee()) && !this.isAlwaysOn()) { this.options.put(PortalOption.ALWAYS_ON, true); - Stargate.debug("Portal", "Gate marked as random, set to always-on"); + Stargate.debug("Portal", "Gate marked as random or bungee, set to always-on"); } } diff --git a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java index e4e70aa..0c02f50 100644 --- a/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/StarGateThread.java @@ -30,8 +30,7 @@ public class StarGateThread implements Runnable { for (Portal portal : openPortalsQueue) { //Skip always open and non-open gates - if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee() || - !portal.isOpen()) { + if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) { continue; } if (time > portal.getTriggeredTime() + Stargate.getGateConfig().getOpenTime()) { diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 18c2ce3..1d00239 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -30,12 +30,12 @@ public final class MaterialHelper { /** * Checks whether the given material is a container - * + * * @param material

The material to check

* @return

True if the material is a container

*/ public static boolean isContainer(Material material) { - return Tag.SHULKER_BOXES.isTagged(material) || material == Material.CHEST || + return Tag.SHULKER_BOXES.isTagged(material) || material == Material.CHEST || material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST; } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index ab83f53..baaf46f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -27,7 +27,7 @@ public final class PermissionHelper { Portal destination = portal.getPortalActivator().getDestination(); //For an always open portal, no action is necessary - if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee()) { + if (portal.getOptions().isAlwaysOn()) { return; } From 4566c15350abebaeecfd3ff52fbc3258fc4744df Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Nov 2021 21:43:38 +0100 Subject: [PATCH 234/378] Updates version to 0.9.0.6 and updates README --- README.md | 5 +++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c36786..690e3f4 100644 --- a/README.md +++ b/README.md @@ -372,6 +372,11 @@ bungeeSign=Teleport to # Changes +#### \[Version 0.9.0.6] EpicKnarvik97 fork + +- Makes containers no longer open when used as buttons +- Validates and updates stargate buttons when the plugin is loaded or reloaded + #### \[Version 0.9.0.5] EpicKnarvik97 fork - Adds an option to stargate functionality to disable all teleportation of creatures diff --git a/pom.xml b/pom.xml index ab6bb5f..956e937 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.5 + 0.9.0.6 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f4c8259..05140a6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.5 +version: 0.9.0.6 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 8c4cf1637599357d7941fabc016156d1885932ee Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Nov 2021 23:39:18 +0100 Subject: [PATCH 235/378] Adds an option for silent stargates which don't print teleportation messages or errors to the player's chat #7 --- README.md | 5 +++- .../listener/PlayerEventListener.java | 10 +++++--- .../listener/VehicleEventListener.java | 14 +++++++---- .../stargate/portal/PortalActivator.java | 4 +++- .../portal/property/PortalOption.java | 7 +++++- .../portal/property/PortalOptions.java | 12 ++++++++++ .../stargate/utility/BungeeHelper.java | 4 +++- .../stargate/utility/PermissionHelper.java | 24 ++++++++++++++----- .../stargate/utility/PortalFileHelper.java | 6 +++-- src/main/resources/plugin.yml | 4 ++++ 10 files changed, 71 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 690e3f4..1242aa2 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ stargate.option -- Allow use of all options stargate.option.backwards -- Allow use of 'B'ackwards stargate.option.show -- Allow use of 'S'how stargate.option.nonetwork -- Allow use of 'N'oNetwork - stargate.option.random -- Allow use of 'Random' stargates + stargate.option.random -- Allow use of 'R'andom stargates + stargate.option.silent -- Allow use of S'i'lent stargates stargate.create -- Allow creating Stargates on any network (Override all create permissions) stargate.create.personal -- Allow creating Stargates on network {playername} @@ -129,6 +130,7 @@ section). See the Custom Gate Layout section to learn how to add custom gates. - 'R' is for random gates. These follow standard permissions of gates, but have a random exit location every time a player enters. - 'U' is for a gate connecting to another through bungee + - 'I' is for a silent gate, which does not output anything to the chat while teleporting. Increases immersion The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. @@ -376,6 +378,7 @@ bungeeSign=Teleport to - Makes containers no longer open when used as buttons - Validates and updates stargate buttons when the plugin is loaded or reloaded +- Adds an option to make a stargate silent (no text in chat when teleporting) for better immersion on RP servers #### \[Version 0.9.0.5] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 656c173..76ab312 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -119,7 +119,9 @@ public class PlayerEventListener implements Listener { //Just teleport the player like normal new PlayerTeleporter(destination, player).teleport(entrancePortal, event); } - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + } entrancePortal.getPortalOpener().closePortal(false); } @@ -159,7 +161,7 @@ public class PlayerEventListener implements Listener { //Decide if the user should be teleported to another bungee server if (entrancePortal.getOptions().isBungee()) { - if (BungeeHelper.bungeeTeleport(player, entrancePortal, event)) { + if (BungeeHelper.bungeeTeleport(player, entrancePortal, event) && !entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); } return false; @@ -241,7 +243,9 @@ public class PlayerEventListener implements Listener { boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); if (PermissionHelper.portalAccessDenied(player, portal, deny)) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!portal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } return true; } return false; diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 2cd7b94..79947b0 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -89,7 +89,9 @@ public class VehicleEventListener implements Listener { //On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open // to one player at a time, we only need to check if the portal is open to the driver. if (!entrancePortal.getPortalOpener().isOpenFor(player)) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } return; } @@ -118,7 +120,9 @@ public class VehicleEventListener implements Listener { //Teleport the vehicle and inform the user if the vehicle was teleported boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); if (teleported) { - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + } entrancePortal.getPortalOpener().closePortal(false); } } @@ -152,7 +156,9 @@ public class VehicleEventListener implements Listener { private static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { //Make sure the user can access the portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } entrancePortal.getPortalOpener().closePortal(false); return false; } @@ -160,7 +166,7 @@ public class VehicleEventListener implements Listener { //Check if the player is able to afford the teleport fee int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal); boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); - if (!canAffordFee) { + if (!canAffordFee && !entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); } return canAffordFee; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 481ca52..3f8f5be 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -248,7 +248,9 @@ public class PortalActivator { //If no destinations are available, just tell the player and quit if (destinations.size() == 0) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("destEmpty")); + if (!portal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("destEmpty")); + } return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java index fa7365c..438a5f1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java @@ -48,7 +48,12 @@ public enum PortalOption { /** * This option allows a portal to teleport to another server connected through BungeeCord */ - BUNGEE('u', "stargate.admin.bungee", 20); + BUNGEE('u', "stargate.admin.bungee", 20), + + /** + * This option allows a portal which does not display a teleportation message, for better immersion + */ + SILENT('i', "stargate.option.silent", 21); private final char characterRepresentation; private final String permissionString; diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java index cf9b279..5a3d892 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java @@ -165,4 +165,16 @@ public class PortalOptions { return this.options.get(PortalOption.BUNGEE); } + /** + * Gets whether this portal is silent + * + *

A silent portal does not output anything to the chat when teleporting. This option is mainly useful to keep + * the immersion during teleportation (for role-playing servers or similar).

+ * + * @return

Whether this portal is silent

+ */ + public boolean isSilent() { + return this.options.get(PortalOption.SILENT); + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 08ce61e..9a508b2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -181,7 +181,9 @@ public final class BungeeHelper { public static boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { //Check if bungee is actually enabled if (!Stargate.getGateConfig().enableBungee()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + } entrancePortal.getPortalOpener().closePortal(false); return false; } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index baaf46f..b8351fa 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -33,7 +33,9 @@ public final class PermissionHelper { //Destination is invalid or the same portal. Send an error message if (destination == null || destination == portal) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); + if (!portal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); + } return; } @@ -49,19 +51,25 @@ public final class PermissionHelper { //Deny access if another player has activated the portal, and it's still in use if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && portal.getActivePlayer() != player) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!portal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } return; } //Check if the player can use the private gate if (portal.getOptions().isPrivate() && !PermissionHelper.canUsePrivatePortal(player, portal)) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!portal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } return; } //Destination is currently in use by another player, blocking teleportation if (destination.isOpen() && !destination.getOptions().isAlwaysOn()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg")); + if (!portal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg")); + } return; } @@ -374,7 +382,9 @@ public final class PermissionHelper { //Not open for this player if (!entrancePortal.getPortalOpener().isOpenFor(player)) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); return true; } @@ -386,7 +396,9 @@ public final class PermissionHelper { //Player cannot access portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); entrancePortal.getPortalOpener().closePortal(false); return true; diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 6e99c94..720bdf2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -121,7 +121,8 @@ public final class PortalFileHelper { builder.append(options.isShown()).append(':'); builder.append(options.isNoNetwork()).append(':'); builder.append(options.isRandom()).append(':'); - builder.append(options.isBungee()); + builder.append(options.isBungee()).append(':'); + builder.append(options.isSilent()); } /** @@ -249,7 +250,8 @@ public final class PortalFileHelper { //Load extra portal data String destination = (portalData.length > 8) ? portalData[8] : ""; - String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : Stargate.getDefaultNetwork(); + String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : + Stargate.getDefaultNetwork(); String ownerString = (portalData.length > 10) ? portalData[10] : ""; //Get the owner from the owner string diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 05140a6..391d6d6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -97,6 +97,7 @@ permissions: stargate.option.show: true stargate.option.nonetwork: true stargate.option.random: true + stargate.option.silent: true stargate.option.hidden: description: Allows the creation of a hidden stargate default: false @@ -121,6 +122,9 @@ permissions: stargate.option.random: description: Allows the creation of a stargate with a random destination default: false + stargate.option.silent: + description: Allows the creation of a stargate which does not output anything to the chat + default: false stargate.admin.hidden: description: Allows this player to see all hidden stargates default: false From f90a09143f46222bc502ae65a5c94c6ea006de72 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 6 Nov 2021 04:10:15 +0100 Subject: [PATCH 236/378] Makes sure to also clear bungee portals when clearing portals --- src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 7a557bc..d8160c4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -37,6 +37,7 @@ public class PortalRegistry { lookupControls.clear(); allPortals.clear(); allPortalNetworks.clear(); + bungeePortals.clear(); } /** From ee0e66e9bef38f7546453727b83e2605d2a7b14b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 6 Nov 2021 14:49:56 +0100 Subject: [PATCH 237/378] Fixes the order in which the portal's button is updated to fix one of the bugs in #15 --- .../net/knarcraft/stargate/utility/PortalFileHelper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 720bdf2..40031e4 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -261,12 +261,12 @@ public final class PortalFileHelper { Portal portal = new Portal(portalLocation, button, destination, name, network, gate, owner, PortalHandler.getPortalOptions(portalData)); + //Update the portal's button if it's the wrong material + updatePortalButton(portal); + //Register the portal, and close it in case it wasn't properly closed when the server stopped PortalHandler.registerPortal(portal); portal.getPortalOpener().closePortal(true); - - //Update the portal's button if it's the wrong material - updatePortalButton(portal); } /** From aa3bb58b33855e6e5e17fafc27e2de708c3359d3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 6 Nov 2021 15:33:06 +0100 Subject: [PATCH 238/378] Fixes some bugs regarding sign drawing and button updating Fixes a bug displaying a portal as usable even if it's been unregistered Fixes a bug which causes the portal button to be re-generated, even if the portal has been unregistered --- .../net/knarcraft/stargate/portal/Portal.java | 19 +++++++++++++++++++ .../stargate/portal/PortalRegistry.java | 2 ++ .../stargate/utility/PortalFileHelper.java | 15 +++++++++------ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 6447baf..9b5449b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -21,6 +21,7 @@ public class Portal { private final String name; private final String network; private final PortalOwner portalOwner; + private boolean isRegistered; private final PortalOptions options; private final PortalOpener portalOpener; @@ -54,6 +55,24 @@ public class Portal { this.portalActivator = portalOpener.getPortalActivator(); } + /** + * Checks if this portal is registered + * + * @return

True if this portal is registered

+ */ + public boolean isRegistered() { + return isRegistered; + } + + /** + * Sets whether this portal is registered + * + * @param isRegistered

True if this portal is registered

+ */ + public void setRegistered(boolean isRegistered) { + this.isRegistered = isRegistered; + } + /** * Gets the location data for this portal * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index d8160c4..3311963 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -231,6 +231,7 @@ public class PortalRegistry { } PortalFileHelper.saveAllPortals(portal.getWorld()); + portal.setRegistered(false); } /** @@ -293,6 +294,7 @@ public class PortalRegistry { } allPortals.add(portal); + portal.setRegistered(true); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 40031e4..66ff996 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -218,7 +218,10 @@ public final class PortalFileHelper { //Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since for (Portal portal : PortalRegistry.getAllPortals()) { - portal.drawSign(); + if (portal.isRegistered()) { + portal.drawSign(); + updatePortalButton(portal); + } } } @@ -250,7 +253,7 @@ public final class PortalFileHelper { //Load extra portal data String destination = (portalData.length > 8) ? portalData[8] : ""; - String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : + String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : Stargate.getDefaultNetwork(); String ownerString = (portalData.length > 10) ? portalData[10] : ""; @@ -261,10 +264,8 @@ public final class PortalFileHelper { Portal portal = new Portal(portalLocation, button, destination, name, network, gate, owner, PortalHandler.getPortalOptions(portalData)); - //Update the portal's button if it's the wrong material - updatePortalButton(portal); - //Register the portal, and close it in case it wasn't properly closed when the server stopped + setButtonVector(portal); PortalHandler.registerPortal(portal); portal.getPortalOpener().closePortal(true); } @@ -275,7 +276,6 @@ public final class PortalFileHelper { * @param portal

The portal update the button of

*/ private static void updatePortalButton(Portal portal) { - setButtonVector(portal); BlockLocation buttonLocation = getButtonLocation(portal); BlockData buttonData = buttonLocation.getBlock().getBlockData(); if (portal.getOptions().isAlwaysOn()) { @@ -305,6 +305,9 @@ public final class PortalFileHelper { portal.getYaw()); if (controlLocation != portal.getLocation().getSignLocation()) { portal.getLocation().setButtonVector(control); + BlockLocation buttonLocation = controlLocation.getRelativeLocation( + new RelativeBlockVector(0, 0, 1), portal.getYaw()); + portal.getStructure().setButton(buttonLocation); } } } From ac25f2747fdf1518ba476e041337e0126f1ec5fb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 6 Nov 2021 18:06:00 +0100 Subject: [PATCH 239/378] Adds String.format to some debug strings --- .../net/knarcraft/stargate/portal/PortalRegistry.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 3311963..f463430 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -252,14 +252,14 @@ public class PortalRegistry { } else { //Check if network exists in the lookup list. If not, register the new network if (!portalLookupByNetwork.containsKey(networkName)) { - Stargate.debug("register", "Network " + portal.getNetwork() + - " not in lookupNamesNet, adding"); + Stargate.debug("register", String.format("Network %s not in lookupNamesNet, adding", + portal.getNetwork())); portalLookupByNetwork.put(networkName, new HashMap<>()); } //Check if this network exists in the network list. If not, register the network if (!allPortalNetworks.containsKey(networkName)) { - Stargate.debug("register", "Network " + portal.getNetwork() + - " not in allPortalsNet, adding"); + Stargate.debug("register", String.format("Network %s not in allPortalsNet, adding", + portal.getNetwork())); allPortalNetworks.put(networkName, new ArrayList<>()); } From 5f2d7988e20498a21d1b1fce8aac0e3735599f1d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 6 Nov 2021 18:08:01 +0100 Subject: [PATCH 240/378] Fixes button updating Fixes a bug causing signs to be removed Makes the old button properly disappear Saves the portal database(s) to store the new button location if necessary --- .../stargate/utility/PortalFileHelper.java | 54 +++++++++++++------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 66ff996..3ebf020 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -155,14 +155,17 @@ public final class PortalFileHelper { int lineIndex = 0; try { Scanner scanner = new Scanner(database); + boolean needsToSaveDatabase = false; while (scanner.hasNextLine()) { //Read the line and do whatever needs to be done - readPortalLine(scanner, ++lineIndex, world); + needsToSaveDatabase = readPortalLine(scanner, ++lineIndex, world) || needsToSaveDatabase; } scanner.close(); //Do necessary tasks after all portals have loaded - doPostLoadTasks(world); + Stargate.debug("PortalFileHelper::loadPortals", String.format("Finished loading portals for %s. " + + "Starting post loading tasks", world)); + doPostLoadTasks(world, needsToSaveDatabase); return true; } catch (Exception e) { Stargate.logSevere(String.format("Exception while reading stargates from %s: %d", database.getName(), @@ -178,24 +181,25 @@ public final class PortalFileHelper { * @param scanner

The scanner to read

* @param lineIndex

The index of the read line

* @param world

The world for which portals are currently being read

+ * @return

True if the read portal has changed and the world's database needs to be saved

*/ - private static void readPortalLine(Scanner scanner, int lineIndex, World world) { + private static boolean readPortalLine(Scanner scanner, int lineIndex, World world) { String line = scanner.nextLine().trim(); //Ignore empty and comment lines if (line.startsWith("#") || line.isEmpty()) { - return; + return false; } //Check if the min. required portal data is present String[] portalData = line.split(":"); if (portalData.length < 8) { Stargate.logInfo(String.format("Invalid line - %s", lineIndex)); - return; + return false; } //Load the portal defined in the current line - loadPortal(portalData, world, lineIndex); + return loadPortal(portalData, world, lineIndex); } /** @@ -205,8 +209,9 @@ public final class PortalFileHelper { * portals.

* * @param world

The world portals have been loaded for

+ * @param needsToSaveDatabase

Whether the portal database's file needs to be updated

*/ - private static void doPostLoadTasks(World world) { + private static void doPostLoadTasks(World world, boolean needsToSaveDatabase) { //Open any always-on portals. Do this here as it should be more efficient than in the loop. PortalHandler.verifyAllPortals(); int portalCount = PortalRegistry.getAllPortals().size(); @@ -223,6 +228,11 @@ public final class PortalFileHelper { updatePortalButton(portal); } } + //Save the portals to disk to update with any changes + Stargate.debug("PortalFileHelper::doPostLoadTasks", String.format("Saving database for world %s", world)); + if (needsToSaveDatabase) { + saveAllPortals(world); + } } /** @@ -231,8 +241,9 @@ public final class PortalFileHelper { * @param portalData

The array describing the portal

* @param world

The world to create the portal in

* @param lineIndex

The line index to report in case the user needs to fix an error

+ * @return

True if the portal's data has changed and its database needs to be updated

*/ - private static void loadPortal(String[] portalData, World world, int lineIndex) { + private static boolean loadPortal(String[] portalData, World world, int lineIndex) { //Load min. required portal data String name = portalData[0]; BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; @@ -248,7 +259,7 @@ public final class PortalFileHelper { if (gate == null) { //Mark the sign as invalid to reduce some player confusion markPortalWithInvalidGate(portalLocation, portalData[7], lineIndex); - return; + return false; } //Load extra portal data @@ -265,9 +276,10 @@ public final class PortalFileHelper { PortalHandler.getPortalOptions(portalData)); //Register the portal, and close it in case it wasn't properly closed when the server stopped - setButtonVector(portal); + boolean buttonLocationChanged = updateButtonVector(portal); PortalHandler.registerPortal(portal); portal.getPortalOpener().closePortal(true); + return buttonLocationChanged; } /** @@ -292,24 +304,32 @@ public final class PortalFileHelper { } /** - * Sets the button vector for the given portal + * Updates the button vector for the given portal * *

As the button vector isn't saved, it is null when the portal is loaded. This method allows it to be * explicitly set when necessary.

* - * @param portal

The portal to set button vector for

+ * @param portal

The portal to update the button vector for

+ * @return

True if the calculated button location is not the same as the one in the portal file

*/ - private static void setButtonVector(Portal portal) { + private static boolean updateButtonVector(Portal portal) { for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { BlockLocation controlLocation = portal.getLocation().getTopLeft().getRelativeLocation(control, portal.getYaw()); - if (controlLocation != portal.getLocation().getSignLocation()) { + BlockLocation buttonLocation = controlLocation.getRelativeLocation( + new RelativeBlockVector(0, 0, 1), portal.getYaw()); + if (!buttonLocation.equals(portal.getLocation().getSignLocation())) { portal.getLocation().setButtonVector(control); - BlockLocation buttonLocation = controlLocation.getRelativeLocation( - new RelativeBlockVector(0, 0, 1), portal.getYaw()); - portal.getStructure().setButton(buttonLocation); + + BlockLocation oldButtonLocation = portal.getStructure().getButton(); + if (oldButtonLocation != null && !oldButtonLocation.equals(buttonLocation)) { + Stargate.addBlockChangeRequest(new BlockChangeRequest(oldButtonLocation, Material.AIR, null)); + portal.getStructure().setButton(buttonLocation); + return true; + } } } + return false; } /** From 57ec7071cf8da565cab3561e462eb558fd472641 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 6 Nov 2021 18:12:47 +0100 Subject: [PATCH 241/378] Updates README changelog --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1242aa2..426677f 100644 --- a/README.md +++ b/README.md @@ -379,6 +379,7 @@ bungeeSign=Teleport to - Makes containers no longer open when used as buttons - Validates and updates stargate buttons when the plugin is loaded or reloaded - Adds an option to make a stargate silent (no text in chat when teleporting) for better immersion on RP servers +- Makes buttons update and/or remove themselves when their location or material changes #### \[Version 0.9.0.5] EpicKnarvik97 fork From 054049881820a6c1ca1ff4b7fdc2d21aed93b038 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 04:04:14 +0100 Subject: [PATCH 242/378] Moves the drawing of unregistered signs to the portal sign drawer --- .../stargate/portal/PortalRegistry.java | 13 +---- .../stargate/portal/PortalSignDrawer.java | 54 ++++++++++++++++--- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index f463430..60b705a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -4,8 +4,6 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.World; -import org.bukkit.block.Sign; -import org.bukkit.block.data.type.WallSign; import java.util.ArrayList; import java.util.HashMap; @@ -220,15 +218,8 @@ public class PortalRegistry { } } - //Clear sign data - if (portal.getSignLocation().getBlock().getBlockData() instanceof WallSign) { - Sign sign = (Sign) portal.getSignLocation().getBlock().getState(); - sign.setLine(0, portal.getName()); - sign.setLine(1, ""); - sign.setLine(2, ""); - sign.setLine(3, ""); - sign.update(); - } + //Mark the portal's sign as unregistered + new PortalSignDrawer(portal).drawUnregisteredSign(); PortalFileHelper.saveAllPortals(portal.getWorld()); portal.setRegistered(false); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index b4117c3..375b067 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -46,16 +46,29 @@ public class PortalSignDrawer { * Draws the sign of the portal this sign drawer is responsible for */ public void drawSign() { + Sign sign = getSign(); + if (sign == null) { + return; + } + + drawSign(sign); + } + + /** + * Gets the sign for this sign drawer's portal + * + * @return

The sign of this sign drawer's portal

+ */ + private Sign getSign() { Block signBlock = portal.getSignLocation().getBlock(); BlockState state = signBlock.getState(); if (!(state instanceof Sign sign)) { Stargate.logWarning("Sign block is not a Sign object"); Stargate.debug("Portal::drawSign", String.format("Block: %s @ %s", signBlock.getType(), signBlock.getLocation())); - return; + return null; } - - drawSign(sign); + return sign; } /** @@ -65,9 +78,7 @@ public class PortalSignDrawer { */ private void drawSign(Sign sign) { //Clear sign - for (int index = 0; index <= 3; index++) { - sign.setLine(index, ""); - } + clearSign(sign); setLine(sign, 0, highlightColor + "-" + mainColor + portal.getName() + highlightColor + "-"); @@ -90,6 +101,31 @@ public class PortalSignDrawer { sign.update(); } + /** + * Clears all lines of a sign, but does not update the sign + * + * @param sign

The sign to clear

+ */ + private void clearSign(Sign sign) { + for (int index = 0; index <= 3; index++) { + sign.setLine(index, ""); + } + } + + /** + * Marks this sign drawer's portal as unregistered + */ + public void drawUnregisteredSign() { + Sign sign = getSign(); + if (sign == null) { + return; + } + clearSign(sign); + sign.setLine(0, portal.getName()); + sign.setLine(3, errorColor + Stargate.getString("signInvalidGate")); + sign.update(); + } + /** * Draws a sign with choose-able network locations * @@ -175,7 +211,7 @@ public class PortalSignDrawer { } /** - * Draws a bungee sign + * Draws the sign of a BungeeCord portal * * @param sign

The sign to re-draw

*/ @@ -186,8 +222,10 @@ public class PortalSignDrawer { } /** - * Draws an inactive sign + * Draws the sign of an in-active portal * + *

The sign for an in-active portal should display the right-click prompt and the network.

+ * * @param sign

The sign to re-draw

*/ private void drawInactiveSign(Sign sign) { From 7f91808baf29554e6388ae7d07c0ac3f9d7a66a3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 04:26:23 +0100 Subject: [PATCH 243/378] Adds a new default stargate to display the possibility of using several border materials --- .../stargate/portal/property/gate/GateHandler.java | 1 + .../resources/gates/squarenetherglowstonegate.gate | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/main/resources/gates/squarenetherglowstonegate.gate diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index ebe3a41..4aec3b7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -243,6 +243,7 @@ public class GateHandler { loadGateFromJar("nethergate.gate", gateFolder); loadGateFromJar("watergate.gate", gateFolder); loadGateFromJar("endgate.gate", gateFolder); + loadGateFromJar("squarenetherglowstonegate.gate", gateFolder); } /** diff --git a/src/main/resources/gates/squarenetherglowstonegate.gate b/src/main/resources/gates/squarenetherglowstonegate.gate new file mode 100644 index 0000000..091dabc --- /dev/null +++ b/src/main/resources/gates/squarenetherglowstonegate.gate @@ -0,0 +1,13 @@ +portal-open=NETHER_PORTAL +portal-closed=AIR +button=OAK_BUTTON +toowner=false +X=OBSIDIAN +-=GLOWSTONE +A=GLOWSTONE + + XAX +X...X +-...- +X.*.X + XAX From 42e208402e45e12edb221edc7862431b4025dc24 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 04:27:39 +0100 Subject: [PATCH 244/378] Documents stargates using several border materials --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 426677f..7e32eca 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,11 @@ The key `button` is used to define the type of button that is generated for this a type of wall coral (dead or alive), a type of shulker box or a chest. `X` and `-` are used to define block types for the layout (Any single-character can be used, such as `#`). -In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. +In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are. + +For more complex gate designs, it is possible to add more materials. If you add something like a=GLOWSTONE, `a` can then +be used in the gate layout, just as `X` is used. See the `squarenetherglowstonegate.gate` file for an example. + You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will teleport in front of. @@ -380,6 +384,7 @@ bungeeSign=Teleport to - Validates and updates stargate buttons when the plugin is loaded or reloaded - Adds an option to make a stargate silent (no text in chat when teleporting) for better immersion on RP servers - Makes buttons update and/or remove themselves when their location or material changes +- Adds another default gate to show that it's possible to use any number of materials for a stargate's border #### \[Version 0.9.0.5] EpicKnarvik97 fork From 527562bc60f06d280b42122aabaf5dcd4b7114b2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 04:29:25 +0100 Subject: [PATCH 245/378] Fixes code formatting --- .../java/net/knarcraft/stargate/portal/PortalRegistry.java | 4 ++-- .../net/knarcraft/stargate/portal/PortalSignDrawer.java | 6 +++--- .../net/knarcraft/stargate/utility/PortalFileHelper.java | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 60b705a..331aaac 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -243,13 +243,13 @@ public class PortalRegistry { } else { //Check if network exists in the lookup list. If not, register the new network if (!portalLookupByNetwork.containsKey(networkName)) { - Stargate.debug("register", String.format("Network %s not in lookupNamesNet, adding", + Stargate.debug("register", String.format("Network %s not in lookupNamesNet, adding", portal.getNetwork())); portalLookupByNetwork.put(networkName, new HashMap<>()); } //Check if this network exists in the network list. If not, register the network if (!allPortalNetworks.containsKey(networkName)) { - Stargate.debug("register", String.format("Network %s not in allPortalsNet, adding", + Stargate.debug("register", String.format("Network %s not in allPortalsNet, adding", portal.getNetwork())); allPortalNetworks.put(networkName, new ArrayList<>()); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 375b067..b86b566 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -56,7 +56,7 @@ public class PortalSignDrawer { /** * Gets the sign for this sign drawer's portal - * + * * @return

The sign of this sign drawer's portal

*/ private Sign getSign() { @@ -103,7 +103,7 @@ public class PortalSignDrawer { /** * Clears all lines of a sign, but does not update the sign - * + * * @param sign

The sign to clear

*/ private void clearSign(Sign sign) { @@ -225,7 +225,7 @@ public class PortalSignDrawer { * Draws the sign of an in-active portal * *

The sign for an in-active portal should display the right-click prompt and the network.

- * + * * @param sign

The sign to re-draw

*/ private void drawInactiveSign(Sign sign) { diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 3ebf020..a283300 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -208,7 +208,7 @@ public final class PortalFileHelper { *

This will open always on portals, print info about loaded stargates and re-draw portal signs for loaded * portals.

* - * @param world

The world portals have been loaded for

+ * @param world

The world portals have been loaded for

* @param needsToSaveDatabase

Whether the portal database's file needs to be updated

*/ private static void doPostLoadTasks(World world, boolean needsToSaveDatabase) { @@ -320,7 +320,7 @@ public final class PortalFileHelper { new RelativeBlockVector(0, 0, 1), portal.getYaw()); if (!buttonLocation.equals(portal.getLocation().getSignLocation())) { portal.getLocation().setButtonVector(control); - + BlockLocation oldButtonLocation = portal.getStructure().getButton(); if (oldButtonLocation != null && !oldButtonLocation.equals(buttonLocation)) { Stargate.addBlockChangeRequest(new BlockChangeRequest(oldButtonLocation, Material.AIR, null)); From 1565707809ab7e9223bdb69a95d54f085b0fdaee Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 13:40:12 +0100 Subject: [PATCH 246/378] De-activates an unregistered portal to prevent its sign to be re-drawn if destroyed while activated --- src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 331aaac..a2e238f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -162,6 +162,7 @@ public class PortalRegistry { */ public static void unregisterPortal(Portal portal, boolean removeAll) { Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); + portal.getPortalActivator().deactivate(); portal.getPortalOpener().closePortal(true); String portalName = portal.getName().toLowerCase(); From fc744b04dc7edcc5e2e661781d17d3f9db7fa197 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 13:41:19 +0100 Subject: [PATCH 247/378] Adds an option for a stargate without a sign #10 --- README.md | 8 ++- .../stargate/listener/BlockEventListener.java | 7 +++ .../listener/PlayerEventListener.java | 61 ++++++++++++++----- .../stargate/portal/PortalSignDrawer.java | 9 +-- .../portal/property/PortalOption.java | 7 ++- .../portal/property/PortalOptions.java | 20 +++++- .../stargate/utility/PortalFileHelper.java | 3 +- src/main/resources/plugin.yml | 4 ++ 8 files changed, 93 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 7e32eca..69727d4 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ stargate.option -- Allow use of all options stargate.option.nonetwork -- Allow use of 'N'oNetwork stargate.option.random -- Allow use of 'R'andom stargates stargate.option.silent -- Allow use of S'i'lent stargates + stargate.option.nosign -- Allow use of 'E' (No sign) stargate.create -- Allow creating Stargates on any network (Override all create permissions) stargate.create.personal -- Allow creating Stargates on network {playername} @@ -128,9 +129,10 @@ section). See the Custom Gate Layout section to learn how to add custom gates. - 'S' is for showing an always-on gate in the network list - 'N' is for hiding the network name - 'R' is for random gates. These follow standard permissions of gates, but have a random exit location every time a - player enters. - - 'U' is for a gate connecting to another through bungee + player enters. (Implicitly always on) + - 'U' is for a gate connecting to another through bungee (Implicitly always on) - 'I' is for a silent gate, which does not output anything to the chat while teleporting. Increases immersion + - 'E' is for gate without a sign. Only for fixed stargates The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. @@ -385,6 +387,8 @@ bungeeSign=Teleport to - Adds an option to make a stargate silent (no text in chat when teleporting) for better immersion on RP servers - Makes buttons update and/or remove themselves when their location or material changes - Adds another default gate to show that it's possible to use any number of materials for a stargate's border +- Adds an option for stargates without a sign. Right-clicking such a stargate will display gate information +- Fixes a bug causing signs to be re-drawn after they're broken #### \[Version 0.9.0.5] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index cc762ca..d61ed84 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.event.StargateDestroyEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalCreator; @@ -81,6 +82,12 @@ public class BlockEventListener implements Listener { return; } + //Remove the sign if the no sign option is enabled + if (portal.getOptions().hasNoSign()) { + BlockChangeRequest request = new BlockChangeRequest(portal.getSignLocation(), Material.AIR, null); + Stargate.addBlockChangeRequest(request); + } + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("createMsg")); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); Stargate.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 76ab312..dfb8aae 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.MessageSender; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalActivator; @@ -11,6 +12,7 @@ import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.UUIDMigrationHelper; +import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -264,11 +266,12 @@ public class PlayerEventListener implements Listener { return; } + //Prevent a double click caused by a Spigot bug + if (clickIsBug(event, block)) { + return; + } + if (MaterialHelper.isButtonCompatible(block.getType())) { - //Prevent a double click caused by a Spigot bug - if (clickIsBug(event, block)) { - return; - } Portal portal = PortalHandler.getByBlock(block); if (portal == null) { @@ -288,30 +291,56 @@ public class PlayerEventListener implements Listener { if (portal.getPortalOpener().isOpenFor(player) && !MaterialHelper.isContainer(block.getType())) { event.setUseInteractedBlock(Event.Result.ALLOW); } + } else { + //Display information about the portal if it has no sign + displayPortalInfo(block, player); } } /** - * This function decides if a right click of a coral is caused by a Spigot bug + * Displays information about a clicked portal * - *

The Spigot bug currently makes every right click of a coral trigger twice, causing the portal to close - * immediately. This fix should detect the bug without breaking wall coral buttons once the bug is fixed.

+ *

This will only display portal info if the portal has no sign and is not silent.

+ * + * @param block

The clicked block

+ * @param player

The player that clicked the block

+ */ + private void displayPortalInfo(Block block, Player player) { + Portal portal = PortalHandler.getByBlock(block); + if (portal == null) { + return; + } + + //Display portal information as a portal without a sign does not display any + if (portal.getOptions().hasNoSign() && !portal.getOptions().isSilent()) { + MessageSender sender = Stargate.getMessageSender(); + sender.sendSuccessMessage(player, ChatColor.GOLD + "[PORTAL INFO]"); + sender.sendSuccessMessage(player, String.format("Portal name: %s", portal.getName())); + sender.sendSuccessMessage(player, String.format("Portal destination: %s", portal.getDestinationName())); + sender.sendSuccessMessage(player, String.format("Portal network: %s", portal.getNetwork())); + } + } + + /** + * This function decides if a right click of a block is caused by a Spigot bug + * + *

The Spigot bug currently makes every right click of some blocks trigger twice, causing the portal to close + * immediately, or causing portal information printing twice. This fix should detect the bug without breaking + * clicking once the bug is fixed.

* * @param event

The event causing the right click

* @param block

The block to check

* @return

True if the click is a bug and should be cancelled

*/ private boolean clickIsBug(PlayerInteractEvent event, Block block) { - if (MaterialHelper.isWallCoral(block.getType())) { - if (previousEvent != null && - event.getPlayer() == previousEvent.getPlayer() && eventTime + 15 > System.currentTimeMillis()) { - previousEvent = null; - eventTime = 0; - return true; - } - previousEvent = event; - eventTime = System.currentTimeMillis(); + if (previousEvent != null && + event.getPlayer() == previousEvent.getPlayer() && eventTime + 15 > System.currentTimeMillis()) { + previousEvent = null; + eventTime = 0; + return true; } + previousEvent = event; + eventTime = System.currentTimeMillis(); return false; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index b86b566..c84a1d1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -63,9 +63,11 @@ public class PortalSignDrawer { Block signBlock = portal.getSignLocation().getBlock(); BlockState state = signBlock.getState(); if (!(state instanceof Sign sign)) { - Stargate.logWarning("Sign block is not a Sign object"); - Stargate.debug("Portal::drawSign", String.format("Block: %s @ %s", signBlock.getType(), - signBlock.getLocation())); + if (!portal.getOptions().hasNoSign()) { + Stargate.logWarning("Sign block is not a Sign object"); + Stargate.debug("Portal::drawSign", String.format("Block: %s @ %s", signBlock.getType(), + signBlock.getLocation())); + } return null; } return sign; @@ -122,7 +124,6 @@ public class PortalSignDrawer { } clearSign(sign); sign.setLine(0, portal.getName()); - sign.setLine(3, errorColor + Stargate.getString("signInvalidGate")); sign.update(); } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java index 438a5f1..9b4cce3 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java @@ -53,7 +53,12 @@ public enum PortalOption { /** * This option allows a portal which does not display a teleportation message, for better immersion */ - SILENT('i', "stargate.option.silent", 21); + SILENT('i', "stargate.option.silent", 21), + + /** + * This option causes a fixed portal's sign to be removed after creation + */ + NO_SIGN('e', "stargate.option.nosign", 22); private final char characterRepresentation; private final String permissionString; diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java index 5a3d892..03cf40f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java @@ -25,12 +25,17 @@ public class PortalOptions { if (this.isAlwaysOn() && !isFixed) { this.options.put(PortalOption.ALWAYS_ON, false); - Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); + Stargate.debug("PortalOptions", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false"); } if ((this.isRandom() || this.isBungee()) && !this.isAlwaysOn()) { this.options.put(PortalOption.ALWAYS_ON, true); - Stargate.debug("Portal", "Gate marked as random or bungee, set to always-on"); + Stargate.debug("PortalOptions", "Gate marked as random or bungee, set to always-on"); + } + + if (this.hasNoSign() && !this.isFixed) { + this.options.put(PortalOption.NO_SIGN, false); + Stargate.debug("PortalOptions", "Gate marked with no sign, but not fixed. Setting NoSign = false"); } } @@ -177,4 +182,15 @@ public class PortalOptions { return this.options.get(PortalOption.SILENT); } + /** + * Gets whether this portal has no sign + * + *

An always-on portal is allowed to not have a sign as it will never be interacted with anyway.

+ * + * @return

Whether this portal has no sign

+ */ + public boolean hasNoSign() { + return this.options.get(PortalOption.NO_SIGN); + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index a283300..73d933b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -122,7 +122,8 @@ public final class PortalFileHelper { builder.append(options.isNoNetwork()).append(':'); builder.append(options.isRandom()).append(':'); builder.append(options.isBungee()).append(':'); - builder.append(options.isSilent()); + builder.append(options.isSilent()).append(':'); + builder.append(options.hasNoSign()); } /** diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 391d6d6..79570e2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -98,6 +98,7 @@ permissions: stargate.option.nonetwork: true stargate.option.random: true stargate.option.silent: true + stargate.option.nosign: true stargate.option.hidden: description: Allows the creation of a hidden stargate default: false @@ -125,6 +126,9 @@ permissions: stargate.option.silent: description: Allows the creation of a stargate which does not output anything to the chat default: false + stargate.option.nosign: + description: Allows the creation of a stargate which has no sign + default: false stargate.admin.hidden: description: Allows this player to see all hidden stargates default: false From 9c963c9e8c57b2e6da46c2897f56a1201225565c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 7 Nov 2021 14:02:33 +0100 Subject: [PATCH 248/378] Renames Portal to Stargate when displaying information about a clicked portal --- .../knarcraft/stargate/listener/PlayerEventListener.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index dfb8aae..a9e3c76 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -314,10 +314,10 @@ public class PlayerEventListener implements Listener { //Display portal information as a portal without a sign does not display any if (portal.getOptions().hasNoSign() && !portal.getOptions().isSilent()) { MessageSender sender = Stargate.getMessageSender(); - sender.sendSuccessMessage(player, ChatColor.GOLD + "[PORTAL INFO]"); - sender.sendSuccessMessage(player, String.format("Portal name: %s", portal.getName())); - sender.sendSuccessMessage(player, String.format("Portal destination: %s", portal.getDestinationName())); - sender.sendSuccessMessage(player, String.format("Portal network: %s", portal.getNetwork())); + sender.sendSuccessMessage(player, ChatColor.GOLD + "[STARGATE INFO]"); + sender.sendSuccessMessage(player, String.format("Stargate name: %s", portal.getName())); + sender.sendSuccessMessage(player, String.format("Stargate destination: %s", portal.getDestinationName())); + sender.sendSuccessMessage(player, String.format("Stargate network: %s", portal.getNetwork())); } } From 4db6274dc38edacc79a58bbb4d0a5813c51f9b3a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Nov 2021 01:34:18 +0100 Subject: [PATCH 249/378] Fixes underwater signs and buttons being replaced with AIR instead of water --- README.md | 1 + .../stargate/listener/BlockEventListener.java | 4 +- .../stargate/utility/PortalFileHelper.java | 43 +++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 69727d4..5cbd010 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,7 @@ bungeeSign=Teleport to - Adds another default gate to show that it's possible to use any number of materials for a stargate's border - Adds an option for stargates without a sign. Right-clicking such a stargate will display gate information - Fixes a bug causing signs to be re-drawn after they're broken +- Makes buttons and signs be replaced by water instead of air when underwater #### \[Version 0.9.0.5] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index d61ed84..1fa29a8 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -84,7 +85,8 @@ public class BlockEventListener implements Listener { //Remove the sign if the no sign option is enabled if (portal.getOptions().hasNoSign()) { - BlockChangeRequest request = new BlockChangeRequest(portal.getSignLocation(), Material.AIR, null); + Material replaceMaterial = PortalFileHelper.decideRemovalMaterial(portal.getSignLocation(), portal); + BlockChangeRequest request = new BlockChangeRequest(portal.getSignLocation(), replaceMaterial, null); Stargate.addBlockChangeRequest(request); } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 73d933b..088a5a1 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -13,11 +13,13 @@ import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.GateHandler; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Waterlogged; import java.io.BufferedWriter; import java.io.File; @@ -292,9 +294,10 @@ public final class PortalFileHelper { BlockLocation buttonLocation = getButtonLocation(portal); BlockData buttonData = buttonLocation.getBlock().getBlockData(); if (portal.getOptions().isAlwaysOn()) { - //Clear button if not already air - if (buttonData.getMaterial() != Material.AIR) { - Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, Material.AIR, null)); + //Clear button if not already air or water + if (buttonData.getMaterial() != Material.AIR && buttonData.getMaterial() != Material.WATER) { + Material newMaterial = decideRemovalMaterial(buttonLocation, portal); + Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, newMaterial, null)); } } else { //Replace button if the material does not match @@ -304,6 +307,40 @@ public final class PortalFileHelper { } } + /** + * Decides the material to use for removing a portal's button/sign + * + * @param location

The location of the button/sign to replace

+ * @param portal

The portal the button/sign belongs to

+ * @return

The material to use for removing the button/sign

+ */ + public static Material decideRemovalMaterial(BlockLocation location, Portal portal) { + //Get the blocks to each side of the location + Location leftLocation = location.getRelativeLocation(-1, 0, 0, portal.getYaw()); + Location rightLocation = location.getRelativeLocation(1, 0, 0, portal.getYaw()); + + //If the block is water or is waterlogged, assume the portal is underwater + if (isUnderwater(leftLocation) || isUnderwater(rightLocation)) { + return Material.WATER; + } else { + return Material.AIR; + } + } + + /** + * Checks whether the given location is underwater + * + *

If the location has a water block, or a block which is waterlogged, it will be considered underwater.

+ * + * @param location

The location to check

+ * @return

True if the location is underwater

+ */ + private static boolean isUnderwater(Location location) { + BlockData blockData = location.getBlock().getBlockData(); + return blockData.getMaterial() == Material.WATER || + (blockData instanceof Waterlogged waterlogged && waterlogged.isWaterlogged()); + } + /** * Updates the button vector for the given portal * From 88bb02dfbd9f33edf26266c493fa29f42f935e18 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Nov 2021 14:16:44 +0100 Subject: [PATCH 250/378] Adds translation for portal information shown when right-clicking Adds a distinction between network and server when displaying portal information Adds translated portal info strings for english and both flavors of Norwegian --- README.md | 7 +++++++ .../stargate/listener/PlayerEventListener.java | 16 ++++++++++++---- src/main/resources/lang/en.txt | 6 ++++++ src/main/resources/lang/nb-no.txt | 6 ++++++ src/main/resources/lang/nn-no.txt | 6 ++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5cbd010..3ca0207 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,12 @@ bungeeDisabled=BungeeCord support is disabled. bungeeDeny=You do not have permission to create BungeeCord gates. bungeeEmpty=BungeeCord gates require both a destination and network. bungeeSign=Teleport to + +portalInfoTitle=[STARGATE INFO] +portalInfoName=Name: %name% +portalInfoDestination=Destination: %destination% +portalInfoNetwork=Network: %network% +portalInfoServer=Server: %server% ``` # Changes @@ -390,6 +396,7 @@ bungeeSign=Teleport to - Adds an option for stargates without a sign. Right-clicking such a stargate will display gate information - Fixes a bug causing signs to be re-drawn after they're broken - Makes buttons and signs be replaced by water instead of air when underwater +- Makes portal info shown when right-clicking a stargate fully customizable #### \[Version 0.9.0.5] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index a9e3c76..845f02a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -314,10 +314,18 @@ public class PlayerEventListener implements Listener { //Display portal information as a portal without a sign does not display any if (portal.getOptions().hasNoSign() && !portal.getOptions().isSilent()) { MessageSender sender = Stargate.getMessageSender(); - sender.sendSuccessMessage(player, ChatColor.GOLD + "[STARGATE INFO]"); - sender.sendSuccessMessage(player, String.format("Stargate name: %s", portal.getName())); - sender.sendSuccessMessage(player, String.format("Stargate destination: %s", portal.getDestinationName())); - sender.sendSuccessMessage(player, String.format("Stargate network: %s", portal.getNetwork())); + sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString("portalInfoTitle")); + sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoName"), + "%name%", portal.getName())); + sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoDestination"), + "%destination%", portal.getDestinationName())); + if (portal.getOptions().isBungee()) { + sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoServer"), + "%server%", portal.getNetwork())); + } else { + sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoNetwork"), + "%network%", portal.getNetwork())); + } } } diff --git a/src/main/resources/lang/en.txt b/src/main/resources/lang/en.txt index 82f6c04..c27e099 100644 --- a/src/main/resources/lang/en.txt +++ b/src/main/resources/lang/en.txt @@ -35,3 +35,9 @@ bungeeDisabled=BungeeCord support is disabled. bungeeDeny=You do not have permission to create BungeeCord gates. bungeeEmpty=BungeeCord gates require both a destination and network. bungeeSign=Teleport to + +portalInfoTitle=[STARGATE INFO] +portalInfoName=Name: %name% +portalInfoDestination=Destination: %destination% +portalInfoNetwork=Network: %network% +portalInfoServer=Server: %server% \ No newline at end of file diff --git a/src/main/resources/lang/nb-no.txt b/src/main/resources/lang/nb-no.txt index 87907c6..0aff97f 100644 --- a/src/main/resources/lang/nb-no.txt +++ b/src/main/resources/lang/nb-no.txt @@ -35,3 +35,9 @@ bungeeDisabled=BungeeCord stรธtte er slรฅtt av. bungeeDeny=Du har ikke tillatelse til รฅ opprette BungeeCord porter. bungeeEmpty=BungeeCord porter behรธver bade en destinasjon og et nettverk. bungeeSign=Teleporter til + +portalInfoTitle=[STJERNEPORT INFO] +portalInfoName=Navn: %name% +portalInfoDestination=Destinasjon: %destination% +portalInfoNetwork=Nettverk: %network% +portalInfoServer=Server: %server% \ No newline at end of file diff --git a/src/main/resources/lang/nn-no.txt b/src/main/resources/lang/nn-no.txt index 4d8c541..7e07a23 100644 --- a/src/main/resources/lang/nn-no.txt +++ b/src/main/resources/lang/nn-no.txt @@ -35,3 +35,9 @@ bungeeDisabled=BungeeCord stรธtte er slรฅtt av. bungeeDeny=Du har ikkje lรธyve til รฅ opprette BungeeCord portar. bungeeEmpty=BungeeCord portar treng bade ein destinasjon og eit nettverk. bungeeSign=Teleporter til + +portalInfoTitle=[STJERNEPORT INFO] +portalInfoName=Namn: %name% +portalInfoDestination=Destinasjon: %destination% +portalInfoNetwork=Nettverk: %network% +portalInfoServer=Server: %server% \ No newline at end of file From 1efd89cdb0e674de36c8cb4a4ef712c5bef4fafe Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Nov 2021 15:14:21 +0100 Subject: [PATCH 251/378] Makes sure to not display portal information when placing a block --- .../stargate/listener/PlayerEventListener.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 845f02a..d38b117 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -28,6 +28,8 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; /** * This listener listens to any player-related events related to stargates @@ -186,7 +188,7 @@ public class PlayerEventListener implements Listener { } if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - handleRightClickBlock(event, player, block); + handleRightClickBlock(event, player, block, event.getHand()); } else if (event.getAction() == Action.LEFT_CLICK_BLOCK && block.getBlockData() instanceof WallSign) { //Handle left click of a wall sign handleSignClick(event, player, block, true); @@ -259,8 +261,9 @@ public class PlayerEventListener implements Listener { * @param event

The event triggering the right-click

* @param player

The player doing the right-click

* @param block

The block the player clicked

+ * @param hand

The hand the player used to interact with the stargate

*/ - private void handleRightClickBlock(PlayerInteractEvent event, Player player, Block block) { + private void handleRightClickBlock(PlayerInteractEvent event, Player player, Block block, EquipmentSlot hand) { if (block.getBlockData() instanceof WallSign) { handleSignClick(event, player, block, false); return; @@ -272,7 +275,6 @@ public class PlayerEventListener implements Listener { } if (MaterialHelper.isButtonCompatible(block.getType())) { - Portal portal = PortalHandler.getByBlock(block); if (portal == null) { return; @@ -293,7 +295,10 @@ public class PlayerEventListener implements Listener { } } else { //Display information about the portal if it has no sign - displayPortalInfo(block, player); + ItemStack heldItem = player.getInventory().getItem(hand); + if (heldItem.getType().isAir() || !heldItem.getType().isBlock()) { + displayPortalInfo(block, player); + } } } @@ -315,9 +320,9 @@ public class PlayerEventListener implements Listener { if (portal.getOptions().hasNoSign() && !portal.getOptions().isSilent()) { MessageSender sender = Stargate.getMessageSender(); sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString("portalInfoTitle")); - sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoName"), + sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoName"), "%name%", portal.getName())); - sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoDestination"), + sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoDestination"), "%destination%", portal.getDestinationName())); if (portal.getOptions().isBungee()) { sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoServer"), From 901f9c555c2e85408318bc936312b59794e364f3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Nov 2021 15:15:58 +0100 Subject: [PATCH 252/378] Prevents the sign location of a portal with no sing from being added to lookup blocks and controls --- .../java/net/knarcraft/stargate/portal/PortalRegistry.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index a2e238f..d58ae20 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -271,8 +271,10 @@ public class PortalRegistry { lookupBlocks.put(block, portal); } //Register the sign and button to the lookup lists - lookupBlocks.put(portal.getSignLocation(), portal); - lookupControls.put(portal.getSignLocation(), portal); + if (!portal.getOptions().hasNoSign()) { + lookupBlocks.put(portal.getSignLocation(), portal); + lookupControls.put(portal.getSignLocation(), portal); + } BlockLocation button = portal.getStructure().getButton(); if (button != null) { From 2a17714e8d5b7d041892fc07fcb5079185406388 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Nov 2021 15:16:51 +0100 Subject: [PATCH 253/378] Makes sure to only remove buttons from always-on portals if the block is a type of button --- .../java/net/knarcraft/stargate/utility/PortalFileHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 088a5a1..b2678a7 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -295,7 +295,7 @@ public final class PortalFileHelper { BlockData buttonData = buttonLocation.getBlock().getBlockData(); if (portal.getOptions().isAlwaysOn()) { //Clear button if not already air or water - if (buttonData.getMaterial() != Material.AIR && buttonData.getMaterial() != Material.WATER) { + if (MaterialHelper.isButtonCompatible(buttonData.getMaterial())) { Material newMaterial = decideRemovalMaterial(buttonLocation, portal); Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, newMaterial, null)); } From 94b9848b70ba0f01afa9fcc82f8dfe2b128ba433 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 Nov 2021 15:17:29 +0100 Subject: [PATCH 254/378] Updates version and README --- README.md | 6 ++++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ca0207..d027333 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,12 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.0.7] EpicKnarvik97 fork + +- Stops registering the sign as a lookup block for stargates without a sign +- Only removes a stargate's button if it's actually a button-compatible block +- Only displays portal info if not placing a block + #### \[Version 0.9.0.6] EpicKnarvik97 fork - Makes containers no longer open when used as buttons diff --git a/pom.xml b/pom.xml index 956e937..e20b239 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.6 + 0.9.0.7 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 79570e2..02d8e18 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.6 +version: 0.9.0.7 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 01b2907b01237f8692a233df7e9ed7860baf53de Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 01:59:54 +0100 Subject: [PATCH 255/378] Adds an enum containing information about all config options --- .../stargate/config/ConfigOption.java | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/config/ConfigOption.java diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java new file mode 100644 index 0000000..f497f98 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -0,0 +1,143 @@ +package net.knarcraft.stargate.config; + +/** + * A ConfigOption represents one of the available config options + */ +public enum ConfigOption { + + /** + * The language used for player-interface text + */ + LANGUAGE("language", "The language used for all signs and all messages to players", "en"), + /** + * The folder for portal files + */ + PORTAL_FOLDER("folders.portalFolder", "The folder containing the portal databases", "plugins/Stargate/portals/"), + /** + * The folder for gate files + */ + GATE_FOLDER("folders.gateFolder", "The folder containing all gate files", "plugins/Stargate/gates/"), + /** + * The max number of portals on a single network + */ + MAX_GATES_EACH_NETWORK("gates.maxGatesEachNetwork", "The max number of stargates in a single network", "0"), + /** + * The network used if not specified + */ + DEFAULT_GATE_NETWORK("gates.defaultGateNetwork", "The network used when no network is specified", "central"), + /** + * Whether to remember the lastly used destination + */ + REMEMBER_DESTINATION("gates.cosmetic.rememberDestination", "Whether to remember the last destination used", "false"), + /** + * Whether to sort the network destinations + */ + SORT_NETWORK_DESTINATIONS("gates.cosmetic.sortNetworkDestinations", "Whether to sort destinations by name", "false"), + /** + * The main color to use for all signs + */ + MAIN_SIGN_COLOR("gates.cosmetic.mainSignColor", "The main text color of all stargate signs", "BLACK"), + /** + * The color to use for highlighting sign text + */ + HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"), + /** + * Whether to destroy portals when any blocks are broken by explosions + */ + DESTROYED_BY_EXPLOSION("gates.integrity.destroyedByExplosion", "Whether stargates should be destroyed by explosions", "false"), + /** + * Whether to verify each portal's gate layout after each load + */ + VERIFY_PORTALS("gates.integrity.verifyPortals", "Whether to verify that portals match their gate layout on load", "false"), + /** + * Whether to protect the entrance of portals + */ + PROTECT_ENTRANCE("gates.integrity.protectEntrance", "Whether to protect stargates' entrances", "false"), + /** + * Whether to enable BungeeCord support + */ + ENABLE_BUNGEE("gates.functionality.enableBungee", "Whether to enable BungeeCord support", "false"), + /** + * Whether to enable vehicle teleportation + */ + HANDLE_VEHICLES("gates.functionality.handleVehicles", "Whether to enable vehicle teleportation", "true"), + /** + * Whether to enable teleportation of empty vehicles + */ + HANDLE_EMPTY_VEHICLES("gates.functionality.handleEmptyVehicles", "Whether to enable teleportation of empty vehicles", "true"), + /** + * Whether to enable teleportation of creatures using vehicles + */ + HANDLE_CREATURE_TELEPORTATION("gates.functionality.handleCreatureTransportation", + "Whether to enable teleportation of vehicles containing non-player creatures", "true"), + /** + * Whether to allow creatures to teleport alone, bypassing any access restrictions + */ + HANDLE_NON_PLAYER_VEHICLES("gates.functionality.handleNonPlayerVehicles", + "Whether to enable teleportation of non-empty vehicles without a player", "true"), + /** + * Whether to enable teleportations of creatures on a leash + */ + HANDLE_LEASHED_CREATURES("gates.functionality.handleLeashedCreatures", + "Whether to enable players to teleport a creature on a leash", "true"), + USE_ECONOMY("economy.useEconomy", "Whether to use economy to incur fees when stargates are used, created or destroyed", "false"), + CREATE_COST("economy.createCost", "The cost of creating a new stargate", "0"), + DESTROY_COST("economy.destroyCost", "The cost of destroying a stargate. Negative to refund", "0"), + USE_COST("economy.useCost", "The cost of using (teleporting through) a stargate", "0"), + TO_OWNER("economy.toOwner", "Whether any teleportation fees should go to the owner of the used stargate", "false"), + CHARGE_FREE_DESTINATION("economy.chargeFreeDestination", + "Whether to require payment if the destination is free, but the entrance stargate is not", "true"), + FREE_GATES_GREEN("economy.freeGatesGreen", "Whether to use green coloring to mark all free stargates", "false"), + DEBUG("debugging.debug", "Whether to enable debugging output", "false"), + PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", "false"); + + + private final String configNode; + private final String description; + private final String defaultValue; + + /** + * Instantiates a new config option + * + * @param configNode

The full path of this config option's config node

+ * @param description

The description of what this config option does

+ * @param defaultValue

The default value of this config option

+ */ + ConfigOption(String configNode, String description, String defaultValue) { + this.configNode = configNode; + this.description = description; + this.defaultValue = defaultValue; + } + + /** + * Gets the name of this config option + * + * @return

The name of this config option

+ */ + public String getName() { + if (!this.configNode.contains(".")) { + return this.configNode; + } + String[] pathParts = this.configNode.split("\\."); + return pathParts[pathParts.length - 1]; + } + + /** + * Gets the description of what this config option does + * + * @return

The description of this config option

+ */ + public String getDescription() { + return this.description; + } + + /** + * Gets this config option's default value + * + * @return

This config option's default value

+ */ + public String getDefaultValue() { + return this.defaultValue; + } + +} From 1ca2d36f5fa725bcba82e731469bba7e26ca7f86 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 02:01:11 +0100 Subject: [PATCH 256/378] Adds an unfinished implementation of the config command, which is only able to display config options for now --- .../stargate/command/CommandConfig.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/command/CommandConfig.java diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java new file mode 100644 index 0000000..cf4f1d8 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -0,0 +1,50 @@ +package net.knarcraft.stargate.command; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.ConfigOption; +import org.bukkit.ChatColor; +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 config command for changing config values + */ +public class CommandConfig implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + if (commandSender instanceof Player player) { + if (!player.hasPermission("stargate.admin")) { + Stargate.getMessageSender().sendErrorMessage(commandSender, "Permission Denied"); + return true; + } + } + + if (args.length > 1) { + //TODO: Do stuff + } else { + //TODO: Display list of config values + displayConfigValues(commandSender); + } + return true; + } + + /** + * Displays the name and a small description of every config value + * + * @param sender

The command sender to display the config list to

+ */ + private void displayConfigValues(CommandSender sender) { + sender.sendMessage(ChatColor.GREEN + Stargate.getBackupString("prefix") + ChatColor.GOLD + + "Config values:"); + for (ConfigOption option : ConfigOption.values()) { + sender.sendMessage(ChatColor.GOLD + option.getName() + ChatColor.WHITE + " - " + ChatColor.GREEN + + option.getDescription() + " (" + option.getDefaultValue() + ")"); + } + } + +} From 37cf75ada1314b65777f87a127dfe067659a68a6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 02:01:58 +0100 Subject: [PATCH 257/378] Adds the config command as a child to the Stargate command --- .../java/net/knarcraft/stargate/command/CommandStarGate.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index 98cf8f5..f1e6c9d 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -23,6 +23,8 @@ public class CommandStarGate implements CommandExecutor { return new CommandAbout().onCommand(commandSender, command, s, args); } else if (args[0].equalsIgnoreCase("reload")) { return new CommandReload().onCommand(commandSender, command, s, args); + } else if (args[0].equalsIgnoreCase("config")) { + return new CommandConfig().onCommand(commandSender, command, s, args); } return false; } else { From 6466c7b0ff52860aa94cbd5ba5a035d6f693fc30 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 02:04:59 +0100 Subject: [PATCH 258/378] Adds the config command to the stargate auto completer Additionally makes the reload command only auto-complete if the command sender can use it --- .../knarcraft/stargate/command/StarGateTabCompleter.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index 0242b4a..fd6be10 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.command; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,7 +20,13 @@ public class StarGateTabCompleter implements TabCompleter { @NotNull String s, @NotNull String[] args) { List commands = new ArrayList<>(); commands.add("about"); - commands.add("reload"); + if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.reload")) { + commands.add("reload"); + } + if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin")) { + commands.add("config"); + } + if (args.length == 1) { return commands; From 7c501cefe829ddc6eb2d4434ed03cea36cd3a2da Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 15:38:10 +0100 Subject: [PATCH 259/378] Gives all config options data types to make loading config values work properly --- .../stargate/config/ConfigOption.java | 94 ++++++++++++++----- 1 file changed, 69 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index f497f98..da046b1 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -20,7 +20,7 @@ public enum ConfigOption { /** * The max number of portals on a single network */ - MAX_GATES_EACH_NETWORK("gates.maxGatesEachNetwork", "The max number of stargates in a single network", "0"), + MAX_GATES_EACH_NETWORK("gates.maxGatesEachNetwork", "The max number of stargates in a single network", 0), /** * The network used if not specified */ @@ -28,11 +28,11 @@ public enum ConfigOption { /** * Whether to remember the lastly used destination */ - REMEMBER_DESTINATION("gates.cosmetic.rememberDestination", "Whether to remember the last destination used", "false"), + REMEMBER_DESTINATION("gates.cosmetic.rememberDestination", "Whether to remember the last destination used", false), /** * Whether to sort the network destinations */ - SORT_NETWORK_DESTINATIONS("gates.cosmetic.sortNetworkDestinations", "Whether to sort destinations by name", "false"), + SORT_NETWORK_DESTINATIONS("gates.cosmetic.sortNetworkDestinations", "Whether to sort destinations by name", false), /** * The main color to use for all signs */ @@ -44,57 +44,58 @@ public enum ConfigOption { /** * Whether to destroy portals when any blocks are broken by explosions */ - DESTROYED_BY_EXPLOSION("gates.integrity.destroyedByExplosion", "Whether stargates should be destroyed by explosions", "false"), + DESTROYED_BY_EXPLOSION("gates.integrity.destroyedByExplosion", "Whether stargates should be destroyed by explosions", false), /** * Whether to verify each portal's gate layout after each load */ - VERIFY_PORTALS("gates.integrity.verifyPortals", "Whether to verify that portals match their gate layout on load", "false"), + VERIFY_PORTALS("gates.integrity.verifyPortals", "Whether to verify that portals match their gate layout on load", false), /** * Whether to protect the entrance of portals */ - PROTECT_ENTRANCE("gates.integrity.protectEntrance", "Whether to protect stargates' entrances", "false"), + PROTECT_ENTRANCE("gates.integrity.protectEntrance", "Whether to protect stargates' entrances", false), /** * Whether to enable BungeeCord support */ - ENABLE_BUNGEE("gates.functionality.enableBungee", "Whether to enable BungeeCord support", "false"), + ENABLE_BUNGEE("gates.functionality.enableBungee", "Whether to enable BungeeCord support", false), /** * Whether to enable vehicle teleportation */ - HANDLE_VEHICLES("gates.functionality.handleVehicles", "Whether to enable vehicle teleportation", "true"), + HANDLE_VEHICLES("gates.functionality.handleVehicles", "Whether to enable vehicle teleportation", true), /** * Whether to enable teleportation of empty vehicles */ - HANDLE_EMPTY_VEHICLES("gates.functionality.handleEmptyVehicles", "Whether to enable teleportation of empty vehicles", "true"), + HANDLE_EMPTY_VEHICLES("gates.functionality.handleEmptyVehicles", "Whether to enable teleportation of empty vehicles", true), /** * Whether to enable teleportation of creatures using vehicles */ - HANDLE_CREATURE_TELEPORTATION("gates.functionality.handleCreatureTransportation", - "Whether to enable teleportation of vehicles containing non-player creatures", "true"), + HANDLE_CREATURE_TRANSPORTATION("gates.functionality.handleCreatureTransportation", + "Whether to enable teleportation of vehicles containing non-player creatures", true), /** * Whether to allow creatures to teleport alone, bypassing any access restrictions */ HANDLE_NON_PLAYER_VEHICLES("gates.functionality.handleNonPlayerVehicles", - "Whether to enable teleportation of non-empty vehicles without a player", "true"), + "Whether to enable teleportation of non-empty vehicles without a player", true), /** * Whether to enable teleportations of creatures on a leash */ HANDLE_LEASHED_CREATURES("gates.functionality.handleLeashedCreatures", - "Whether to enable players to teleport a creature on a leash", "true"), - USE_ECONOMY("economy.useEconomy", "Whether to use economy to incur fees when stargates are used, created or destroyed", "false"), - CREATE_COST("economy.createCost", "The cost of creating a new stargate", "0"), - DESTROY_COST("economy.destroyCost", "The cost of destroying a stargate. Negative to refund", "0"), - USE_COST("economy.useCost", "The cost of using (teleporting through) a stargate", "0"), - TO_OWNER("economy.toOwner", "Whether any teleportation fees should go to the owner of the used stargate", "false"), + "Whether to enable players to teleport a creature on a leash", true), + USE_ECONOMY("economy.useEconomy", "Whether to use economy to incur fees when stargates are used, created or destroyed", false), + CREATE_COST("economy.createCost", "The cost of creating a new stargate", 0), + DESTROY_COST("economy.destroyCost", "The cost of destroying a stargate. Negative to refund", 0), + USE_COST("economy.useCost", "The cost of using (teleporting through) a stargate", 0), + TO_OWNER("economy.toOwner", "Whether any teleportation fees should go to the owner of the used stargate", false), CHARGE_FREE_DESTINATION("economy.chargeFreeDestination", - "Whether to require payment if the destination is free, but the entrance stargate is not", "true"), - FREE_GATES_GREEN("economy.freeGatesGreen", "Whether to use green coloring to mark all free stargates", "false"), - DEBUG("debugging.debug", "Whether to enable debugging output", "false"), - PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", "false"); + "Whether to require payment if the destination is free, but the entrance stargate is not", true), + FREE_GATES_GREEN("economy.freeGatesGreen", "Whether to use green coloring to mark all free stargates", false), + DEBUG("debugging.debug", "Whether to enable debugging output", false), + PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", false); private final String configNode; private final String description; - private final String defaultValue; + private final Object defaultValue; + private final OptionDataType dataType; /** * Instantiates a new config option @@ -103,10 +104,35 @@ public enum ConfigOption { * @param description

The description of what this config option does

* @param defaultValue

The default value of this config option

*/ - ConfigOption(String configNode, String description, String defaultValue) { + ConfigOption(String configNode, String description, Object defaultValue) { this.configNode = configNode; this.description = description; this.defaultValue = defaultValue; + + if (defaultValue instanceof String) { + this.dataType = OptionDataType.STRING; + } else if (defaultValue instanceof Boolean) { + this.dataType = OptionDataType.BOOLEAN; + } else if (defaultValue instanceof Integer) { + this.dataType = OptionDataType.INTEGER; + } else { + throw new IllegalArgumentException("Unknown config data type encountered."); + } + } + + /** + * Gets a config option given its name + * + * @param name

The name of the config option to get

+ * @return

The corresponding config option, or null if the name is invalid

+ */ + public static ConfigOption getByName(String name) { + for (ConfigOption option : ConfigOption.values()) { + if (option.getName().equalsIgnoreCase(name)) { + return option; + } + } + return null; } /** @@ -122,6 +148,24 @@ public enum ConfigOption { return pathParts[pathParts.length - 1]; } + /** + * Gets the data type used for storing this config option + * + * @return

The data type used

+ */ + public OptionDataType getDataType() { + return this.dataType; + } + + /** + * Gets the config node of this config option + * + * @return

This config option's config node

+ */ + public String getConfigNode() { + return this.configNode; + } + /** * Gets the description of what this config option does * @@ -136,7 +180,7 @@ public enum ConfigOption { * * @return

This config option's default value

*/ - public String getDefaultValue() { + public Object getDefaultValue() { return this.defaultValue; } From 85edaa465792cb18bea0f135b91c6dd245b64593 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 15:38:42 +0100 Subject: [PATCH 260/378] Adds a new class to represent a data type usable by configs --- .../stargate/config/OptionDataType.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/config/OptionDataType.java diff --git a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java new file mode 100644 index 0000000..e657a69 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java @@ -0,0 +1,21 @@ +package net.knarcraft.stargate.config; + +/** + * An enum defining the different data types an option can have + */ +public enum OptionDataType { + + /** + * The data type for the option is a String + */ + STRING, + /** + * The data type for the option is a Boolean + */ + BOOLEAN, + /** + * The data type for the option is an Integer + */ + INTEGER + +} From d5f4b87e9bb27a1695c327b627d40f6a9583524d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 15:40:10 +0100 Subject: [PATCH 261/378] Changes how config values are loaded by using the ConfigOption class --- .../stargate/config/EconomyConfig.java | 26 +++--- .../stargate/config/StargateConfig.java | 35 ++++++-- .../stargate/config/StargateGateConfig.java | 80 ++++++------------- 3 files changed, 65 insertions(+), 76 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 10cf01b..22ae241 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -6,13 +6,13 @@ import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.utility.PermissionHelper; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicesManager; +import java.util.Map; import java.util.UUID; /** @@ -33,10 +33,10 @@ public final class EconomyConfig { /** * Instantiates a new economy config * - * @param newConfig

The file configuration to read values from

+ * @param configOptions

The loaded config options to read

*/ - public EconomyConfig(FileConfiguration newConfig) { - loadEconomyConfig(newConfig); + public EconomyConfig(Map configOptions) { + loadEconomyConfig(configOptions); } /** @@ -332,16 +332,16 @@ public final class EconomyConfig { /** * Loads all config values related to economy * - * @param newConfig

The configuration containing the values to read

+ * @param configOptions

The loaded config options to get values from

*/ - private void loadEconomyConfig(FileConfiguration newConfig) { - economyEnabled = newConfig.getBoolean("economy.useEconomy"); - setDefaultCreateCost(newConfig.getInt("economy.createCost")); - setDefaultDestroyCost(newConfig.getInt("economy.destroyCost")); - setDefaultUseCost(newConfig.getInt("economy.useCost")); - toOwner = newConfig.getBoolean("economy.toOwner"); - chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination"); - freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen"); + private void loadEconomyConfig(Map configOptions) { + economyEnabled = (boolean) configOptions.get(ConfigOption.USE_ECONOMY); + setDefaultCreateCost((Integer) configOptions.get(ConfigOption.CREATE_COST)); + setDefaultDestroyCost((Integer) configOptions.get(ConfigOption.DESTROY_COST)); + setDefaultUseCost((Integer) configOptions.get(ConfigOption.USE_COST)); + toOwner = (boolean) configOptions.get(ConfigOption.TO_OWNER); + chargeFreeDestination = (boolean) configOptions.get(ConfigOption.CHARGE_FREE_DESTINATION); + freeGatesGreen = (boolean) configOptions.get(ConfigOption.FREE_GATES_GREEN); } /** diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 5b13fe3..656ca23 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -18,6 +18,7 @@ import org.bukkit.plugin.messaging.Messenger; import java.io.File; import java.io.IOException; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Queue; @@ -47,6 +48,7 @@ public final class StargateConfig { private boolean debuggingEnabled = false; private boolean permissionDebuggingEnabled = false; + private final Map configOptions; /** * Instantiates a new stargate config @@ -55,6 +57,7 @@ public final class StargateConfig { */ public StargateConfig(Logger logger) { this.logger = logger; + configOptions = new HashMap<>(); dataFolderPath = Stargate.getInstance().getDataFolder().getPath().replaceAll("\\\\", "/"); portalFolder = dataFolderPath + "/portals/"; @@ -307,16 +310,34 @@ public final class StargateConfig { //Copy missing default values if any values are missing newConfig.options().copyDefaults(true); + //Load all options + for (ConfigOption option : ConfigOption.values()) { + Object optionValue; + String configNode = option.getConfigNode(); + + //Load the option using its correct data type + switch (option.getDataType()) { + case STRING -> { + String value = newConfig.getString(configNode); + optionValue = value != null ? value.trim() : ""; + } + case BOOLEAN -> optionValue = newConfig.getBoolean(configNode); + case INTEGER -> optionValue = newConfig.getInt(configNode); + default -> throw new IllegalArgumentException("Invalid config data type encountered"); + } + configOptions.put(option, optionValue); + } + //Get the language name from the config - languageName = newConfig.getString("language"); + languageName = (String) configOptions.get(ConfigOption.LANGUAGE); //Get important folders from the config - portalFolder = newConfig.getString("folders.portalFolder"); - gateFolder = newConfig.getString("folders.gateFolder"); + portalFolder = (String) configOptions.get(ConfigOption.PORTAL_FOLDER); + gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER); //Get enabled debug settings from the config - debuggingEnabled = newConfig.getBoolean("debugging.debug"); - permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug"); + debuggingEnabled = (boolean) configOptions.get(ConfigOption.DEBUG); + permissionDebuggingEnabled = (boolean) configOptions.get(ConfigOption.PERMISSION_DEBUG); //If users have an outdated config, assume they also need to update their default gates if (isMigrating) { @@ -324,10 +345,10 @@ public final class StargateConfig { } //Load all gate config values - stargateGateConfig = new StargateGateConfig(newConfig); + stargateGateConfig = new StargateGateConfig(configOptions); //Load all economy config values - economyConfig = new EconomyConfig(newConfig); + economyConfig = new EconomyConfig(configOptions); Stargate.getInstance().saveConfig(); } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index be13cdc..f14dd6b 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -3,36 +3,25 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.PortalSignDrawer; import org.bukkit.ChatColor; -import org.bukkit.configuration.file.FileConfiguration; + +import java.util.Map; /** * The Stargate gate config keeps track of all global config values related to gates */ public final class StargateGateConfig { - - private int maxGatesEachNetwork = 0; - private boolean rememberDestination = false; - private boolean handleVehicles = true; - private boolean handleEmptyVehicles = true; - private boolean handleCreatureTransportation = true; - private boolean handleNonPlayerVehicles = true; - private boolean handleLeashedCreatures = true; - private boolean sortNetworkDestinations = false; - private boolean protectEntrance = false; - private boolean enableBungee = true; - private boolean verifyPortals = true; - private boolean destroyExplosion = false; - private String defaultGateNetwork = "central"; private static final int activeTime = 10; private static final int openTime = 10; + private final Map configOptions; /** * Instantiates a new stargate config * - * @param newConfig

The file configuration to read values from

+ * @param configOptions

The loaded config options to use

*/ - public StargateGateConfig(FileConfiguration newConfig) { - loadGateConfig(newConfig); + public StargateGateConfig(Map configOptions) { + this.configOptions = configOptions; + loadGateConfig(); } /** @@ -59,7 +48,7 @@ public final class StargateGateConfig { * @return

Maximum number of gates for each network

*/ public int maxGatesEachNetwork() { - return maxGatesEachNetwork; + return (int) configOptions.get(ConfigOption.MAX_GATES_EACH_NETWORK); } /** @@ -68,7 +57,7 @@ public final class StargateGateConfig { * @return

Whether a portal's lastly used destination should be remembered

*/ public boolean rememberDestination() { - return rememberDestination; + return (boolean) configOptions.get(ConfigOption.REMEMBER_DESTINATION); } /** @@ -77,7 +66,7 @@ public final class StargateGateConfig { * @return

Whether vehicle teleportation should be handled

*/ public boolean handleVehicles() { - return handleVehicles; + return (boolean) configOptions.get(ConfigOption.HANDLE_VEHICLES); } /** @@ -89,7 +78,7 @@ public final class StargateGateConfig { * @return

Whether vehicles without passengers should be handled

*/ public boolean handleEmptyVehicles() { - return handleEmptyVehicles; + return (boolean) configOptions.get(ConfigOption.HANDLE_EMPTY_VEHICLES); } /** @@ -101,7 +90,7 @@ public final class StargateGateConfig { * @return

Whether vehicles with creatures should be handled

*/ public boolean handleCreatureTransportation() { - return handleCreatureTransportation; + return (boolean) configOptions.get(ConfigOption.HANDLE_CREATURE_TRANSPORTATION); } /** @@ -118,7 +107,7 @@ public final class StargateGateConfig { * @return

Whether non-empty vehicles without a player should be handled

*/ public boolean handleNonPlayerVehicles() { - return handleNonPlayerVehicles; + return (boolean) configOptions.get(ConfigOption.HANDLE_NON_PLAYER_VEHICLES); } /** @@ -127,7 +116,7 @@ public final class StargateGateConfig { * @return

Whether leashed creatures should be handled

*/ public boolean handleLeashedCreatures() { - return handleLeashedCreatures; + return (boolean) configOptions.get(ConfigOption.HANDLE_LEASHED_CREATURES); } /** @@ -136,7 +125,7 @@ public final class StargateGateConfig { * @return

Whether network destinations should be sorted

*/ public boolean sortNetworkDestinations() { - return sortNetworkDestinations; + return (boolean) configOptions.get(ConfigOption.SORT_NETWORK_DESTINATIONS); } /** @@ -145,7 +134,7 @@ public final class StargateGateConfig { * @return

Whether portal entrances should be protected

*/ public boolean protectEntrance() { - return protectEntrance; + return (boolean) configOptions.get(ConfigOption.PROTECT_ENTRANCE); } /** @@ -154,7 +143,7 @@ public final class StargateGateConfig { * @return

Whether bungee support is enabled

*/ public boolean enableBungee() { - return enableBungee; + return (boolean) configOptions.get(ConfigOption.ENABLE_BUNGEE); } /** @@ -163,7 +152,7 @@ public final class StargateGateConfig { * @return

Whether portals need to be verified

*/ public boolean verifyPortals() { - return verifyPortals; + return (boolean) configOptions.get(ConfigOption.VERIFY_PORTALS); } /** @@ -172,7 +161,7 @@ public final class StargateGateConfig { * @return

Whether portals should be destroyed by explosions

*/ public boolean destroyedByExplosion() { - return destroyExplosion; + return (boolean) configOptions.get(ConfigOption.DESTROYED_BY_EXPLOSION); } /** @@ -181,37 +170,16 @@ public final class StargateGateConfig { * @return

The default portal network

*/ public String getDefaultPortalNetwork() { - return defaultGateNetwork; + return (String) configOptions.get(ConfigOption.DEFAULT_GATE_NETWORK); } /** * Loads all config values related to gates - * - * @param newConfig

The configuration containing the values to read

*/ - private void loadGateConfig(FileConfiguration newConfig) { - String defaultNetwork = newConfig.getString("gates.defaultGateNetwork"); - defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null; - maxGatesEachNetwork = newConfig.getInt("gates.maxGatesEachNetwork"); - - //Functionality - handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles"); - handleEmptyVehicles = newConfig.getBoolean("gates.functionality.handleEmptyVehicles"); - handleCreatureTransportation = newConfig.getBoolean("gates.functionality.handleCreatureTransportation"); - handleNonPlayerVehicles = newConfig.getBoolean("gates.functionality.handleNonPlayerVehicles"); - handleLeashedCreatures = newConfig.getBoolean("gates.functionality.handleLeashedCreatures"); - enableBungee = newConfig.getBoolean("gates.functionality.enableBungee"); - - //Integrity - protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance"); - verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals"); - destroyExplosion = newConfig.getBoolean("gates.integrity.destroyedByExplosion"); - - //Cosmetic - sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations"); - rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination"); - loadSignColor(newConfig.getString("gates.cosmetic.mainSignColor"), - newConfig.getString("gates.cosmetic.highlightSignColor")); + private void loadGateConfig() { + //Load the sign colors + loadSignColor((String) configOptions.get(ConfigOption.MAIN_SIGN_COLOR), + (String) configOptions.get(ConfigOption.HIGHLIGHT_SIGN_COLOR)); } /** From aba70b669ee735d140d9517344d2289b8cac4af0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 18:21:25 +0100 Subject: [PATCH 262/378] Adds a method to be able to read config options --- .../net/knarcraft/stargate/config/StargateConfig.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 656ca23..f9e7144 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -93,6 +93,15 @@ public final class StargateConfig { setupVaultEconomy(); } + /** + * Gets a copy of all loaded config options with its values + * + * @return

The loaded config options

+ */ + public Map getConfigOptions() { + return new HashMap<>(configOptions); + } + /** * Gets the queue of open portals * From 05328fc456a3f4b5672f3f8d97d66dec4d412d78 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 20:56:43 +0100 Subject: [PATCH 263/378] Adds a tab completer for the config sub-command --- .../stargate/command/ConfigTabCompleter.java | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java new file mode 100644 index 0000000..046f4f2 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -0,0 +1,182 @@ +package net.knarcraft.stargate.command; + +import net.knarcraft.stargate.config.ConfigOption; +import net.knarcraft.stargate.config.OptionDataType; +import org.bukkit.ChatColor; +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; + +/** + * This is the completer for stargates config sub-command (/sg config) + */ +public class ConfigTabCompleter implements TabCompleter { + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + + if (args.length > 1) { + ConfigOption selectedOption = ConfigOption.getByName(args[0]); + if (selectedOption == null) { + return new ArrayList<>(); + } else { + return getPossibleOptionValues(selectedOption, args[1]); + } + } else { + List configOptionNames = new ArrayList<>(); + for (ConfigOption option : ConfigOption.values()) { + configOptionNames.add(option.getName()); + } + return filterMatching(configOptionNames, args[0]); + } + } + + /** + * Find completable strings which match the text typed by the command's sender + * + * @param values

The values to filter

+ * @param typedText

The text the player has started typing

+ * @return

The given string values which start with the player's typed text

+ */ + private List filterMatching(List values, String typedText) { + List configValues = new ArrayList<>(); + for (String value : values) { + if (value.toLowerCase().startsWith(typedText.toLowerCase())) { + configValues.add(value); + } + } + return configValues; + } + + /** + * Get possible values for the selected option + * + * @param selectedOption

The selected option

+ * @param typedText

The beginning of the typed text, for filtering matching results

+ * @return

Some or all of the valid values for the option

+ */ + private List getPossibleOptionValues(ConfigOption selectedOption, String typedText) { + List booleans = new ArrayList<>(); + booleans.add("true"); + booleans.add("false"); + + List numbers = new ArrayList<>(); + numbers.add("0"); + numbers.add("5"); + + switch (selectedOption) { + case LANGUAGE: + //Return available languages + return filterMatching(getLanguages(), typedText); + case GATE_FOLDER: + case PORTAL_FOLDER: + case DEFAULT_GATE_NETWORK: + //Just return the default value as most values should be possible + if (typedText.trim().isEmpty()) { + return putStringInList((String) selectedOption.getDefaultValue()); + } else { + return new ArrayList<>(); + } + case MAIN_SIGN_COLOR: + case HIGHLIGHT_SIGN_COLOR: + //Return all colors + return filterMatching(getColors(), typedText); + } + + //If the config value is a boolean, show the two boolean values + if (selectedOption.getDataType() == OptionDataType.BOOLEAN) { + return filterMatching(booleans, typedText); + } + + //If the config value is an integer, display some valid numbers + if (selectedOption.getDataType() == OptionDataType.INTEGER) { + if (typedText.trim().isEmpty()) { + return numbers; + } else { + return new ArrayList<>(); + } + } + + return null; + } + + /** + * Gets all available languages + * + * @return

The available languages

+ */ + private List getLanguages() { + List languages = new ArrayList<>(); + languages.add("de"); + languages.add("en"); + languages.add("es"); + languages.add("fr"); + languages.add("hu"); + languages.add("it"); + languages.add("nb-no"); + languages.add("nl"); + languages.add("nn-no"); + languages.add("pt-br"); + languages.add("ru"); + return languages; + } + + /** + * Gets all available colors + * + * @return

All available colors

+ */ + private List getColors() { + List colors = new ArrayList<>(); + for (ChatColor color : getChatColors()) { + colors.add(color.name()); + } + return colors; + } + + /** + * Gets a list of all available chat colors + * + * @return

A list of chat colors

+ */ + private List getChatColors() { + List chatColors = new ArrayList<>(); + chatColors.add(ChatColor.WHITE); + chatColors.add(ChatColor.BLUE); + chatColors.add(ChatColor.DARK_BLUE); + chatColors.add(ChatColor.DARK_PURPLE); + chatColors.add(ChatColor.LIGHT_PURPLE); + chatColors.add(ChatColor.GOLD); + chatColors.add(ChatColor.GREEN); + chatColors.add(ChatColor.BLACK); + chatColors.add(ChatColor.DARK_GREEN); + chatColors.add(ChatColor.DARK_RED); + chatColors.add(ChatColor.RED); + chatColors.add(ChatColor.AQUA); + chatColors.add(ChatColor.DARK_AQUA); + chatColors.add(ChatColor.DARK_GRAY); + chatColors.add(ChatColor.GRAY); + chatColors.add(ChatColor.YELLOW); + return chatColors; + } + + /** + * Puts a single string value into a string list + * + * @param value

The string to make into a list

+ * @return

A list containing the string value

+ */ + private List putStringInList(String value) { + List list = new ArrayList<>(); + list.add(value); + return list; + } + +} From 8546fd4f78ac73892a10371d711a694c50053ff9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 20:57:06 +0100 Subject: [PATCH 264/378] Fully implements the config command --- .../stargate/command/CommandConfig.java | 104 +++++++++++++++++- 1 file changed, 99 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index cf4f1d8..57ba4f2 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -6,6 +6,7 @@ import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -24,15 +25,98 @@ public class CommandConfig implements CommandExecutor { } } - if (args.length > 1) { - //TODO: Do stuff + if (args.length > 0) { + ConfigOption selectedOption = ConfigOption.getByName(args[0]); + if (selectedOption == null) { + return false; + } + if (args.length > 1) { + updateConfigValue(selectedOption, commandSender, args[1]); + } else { + //Display info and the current value of the given config value + printConfigOptionValue(commandSender, selectedOption); + } + return true; } else { - //TODO: Display list of config values + //Display all config options displayConfigValues(commandSender); } return true; } + /** + * Updates a config value + * + * @param selectedOption

The option which should be updated

+ * @param commandSender

The command sender that changed the value

+ * @param value

The new value of the config option

+ */ + private void updateConfigValue(ConfigOption selectedOption, CommandSender commandSender, String value) { + FileConfiguration configuration = Stargate.getInstance().getConfig(); + + //Validate any sign colors + if (selectedOption == ConfigOption.MAIN_SIGN_COLOR || selectedOption == ConfigOption.HIGHLIGHT_SIGN_COLOR) { + try { + ChatColor.valueOf(value.toUpperCase()); + } catch (IllegalArgumentException | NullPointerException ignored) { + commandSender.sendMessage(ChatColor.RED + "Invalid color given"); + return; + } + } + + //Store the config values, accounting for the data type + switch (selectedOption.getDataType()) { + case BOOLEAN -> configuration.set(selectedOption.getConfigNode(), Boolean.parseBoolean(value)); + case INTEGER -> { + try { + configuration.set(selectedOption.getConfigNode(), Integer.parseInt(value)); + } catch (NumberFormatException exception) { + commandSender.sendMessage(ChatColor.RED + "Invalid number given"); + return; + } + } + case STRING -> { + if (selectedOption == ConfigOption.GATE_FOLDER || selectedOption == ConfigOption.PORTAL_FOLDER || + selectedOption == ConfigOption.DEFAULT_GATE_NETWORK) { + if (value.contains("../") || value.contains("..\\")) { + commandSender.sendMessage(ChatColor.RED + "Path traversal characters cannot be used"); + return; + } + } + configuration.set(selectedOption.getConfigNode(), value); + } + default -> configuration.set(selectedOption.getConfigNode(), value); + } + + //Save the config file and reload if necessary + Stargate.getInstance().saveConfig(); + reloadIfNecessary(commandSender); + } + + /** + * Reloads the config if necessary + * + * @param commandSender

The command sender initiating the reload

+ */ + private void reloadIfNecessary(CommandSender commandSender) { + //TODO: Only update the config values which have changed and do the least amount of work necessary to load the + // changes. Only do a full reload if absolutely necessary, or when the partial reloading would be as + // inefficient as a full reload. + Stargate.getStargateConfig().reload(commandSender); + } + + /** + * Prints information about a config option and its current value + * + * @param sender

The command sender that sent the command

+ * @param option

The config option to print information about

+ */ + private void printConfigOptionValue(CommandSender sender, ConfigOption option) { + Object value = Stargate.getStargateConfig().getConfigOptions().get(option); + sender.sendMessage(getOptionDescription(option)); + sender.sendMessage(ChatColor.GREEN + "Current value: " + ChatColor.GOLD + value); + } + /** * Displays the name and a small description of every config value * @@ -42,9 +126,19 @@ public class CommandConfig implements CommandExecutor { sender.sendMessage(ChatColor.GREEN + Stargate.getBackupString("prefix") + ChatColor.GOLD + "Config values:"); for (ConfigOption option : ConfigOption.values()) { - sender.sendMessage(ChatColor.GOLD + option.getName() + ChatColor.WHITE + " - " + ChatColor.GREEN + - option.getDescription() + " (" + option.getDefaultValue() + ")"); + sender.sendMessage(getOptionDescription(option)); } } + /** + * Gets the description of a single config option + * + * @param option

The option to describe

+ * @return

A string describing the config option

+ */ + private String getOptionDescription(ConfigOption option) { + return ChatColor.GOLD + option.getName() + ChatColor.WHITE + " - " + ChatColor.GREEN + option.getDescription() + + ChatColor.DARK_GRAY + " (Default: " + ChatColor.GRAY + option.getDefaultValue() + ChatColor.DARK_GRAY + ")"; + } + } From b4d908eaa0f7aefce1959147a9f996db8eafcb00 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 20:58:55 +0100 Subject: [PATCH 265/378] Improves tab completion for Stargate commands by taking into account typed text Sends tab completion for the config command to the config tab completer --- .../stargate/command/CommandStarGate.java | 4 ++- .../command/StarGateTabCompleter.java | 33 +++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index f1e6c9d..796b0c2 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; +import org.apache.commons.lang.ArrayUtils; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -24,7 +25,8 @@ public class CommandStarGate implements CommandExecutor { } else if (args[0].equalsIgnoreCase("reload")) { return new CommandReload().onCommand(commandSender, command, s, args); } else if (args[0].equalsIgnoreCase("config")) { - return new CommandConfig().onCommand(commandSender, command, s, args); + String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + return new CommandConfig().onCommand(commandSender, command, s, subArgs); } return false; } else { diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index fd6be10..e9728c5 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate.command; +import org.apache.commons.lang.ArrayUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; @@ -18,6 +19,30 @@ public class StarGateTabCompleter implements TabCompleter { @Override public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { + if (args.length == 1) { + List commands = getAvailableCommands(commandSender); + List matchingCommands = new ArrayList<>(); + for (String availableCommand : commands) { + if (availableCommand.startsWith(args[0])) { + matchingCommands.add(availableCommand); + } + } + return matchingCommands; + } else if (args.length > 1 && args[0].equalsIgnoreCase("config")) { + String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + return new ConfigTabCompleter().onTabComplete(commandSender, command, s, subArgs); + } else { + return new ArrayList<>(); + } + } + + /** + * Gets the available commands + * + * @param commandSender

The command sender to get available commands for

+ * @return

The commands available to the command sender

+ */ + private List getAvailableCommands(CommandSender commandSender) { List commands = new ArrayList<>(); commands.add("about"); if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.reload")) { @@ -26,13 +51,7 @@ public class StarGateTabCompleter implements TabCompleter { if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin")) { commands.add("config"); } - - - if (args.length == 1) { - return commands; - } else { - return new ArrayList<>(); - } + return commands; } } From 1c2cad2ec1a3768d600a23856db07859b36d1ded Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 21:16:53 +0100 Subject: [PATCH 266/378] Updates version to 0.9.1.0, updates README and adds a permission for changing config values Adds the stargate.admin.config permission, which is required to use /sg config --- README.md | 10 +++++++++- pom.xml | 2 +- .../net/knarcraft/stargate/command/CommandConfig.java | 2 +- .../stargate/command/StarGateTabCompleter.java | 2 +- src/main/resources/plugin.yml | 10 +++++++--- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d027333..3557b6c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ can share a network or be split into clusters; they can be hidden on a network o - Underwater portals -- portals can be placed underwater as long as a waterproof button is used - API available -- using the API, a lot of behavior can be changed - Button customization -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) +- Config commands -- All main config values can be changed from the commandline ## Background @@ -80,11 +81,12 @@ stargate.free -- Allow free use/creation/destruction of Stargates stargate.free.create -- Allow free creation of Stargates stargate.free.destroy -- Allow free destruction of Stargates -stargate.admin -- Allow all admin features (Hidden/Private only so far) +stargate.admin -- Allow all admin features (Hidden/Private bypass, BungeeCord, Reload, Config) stargate.admin.private -- Allow use of Private gates not owned by user stargate.admin.hidden -- Allow access to Hidden gates not ownerd by user stargate.admin.bungee -- Allow the creation of BungeeCord stargates (U option) stargate.admin.reload -- Allow use of the reload command + stargate.admin.config -- Allows the player to change config values from the chat ``` ## Default Permissions @@ -386,6 +388,12 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.1.0] EpicKnarvik97 fork + +- Rewrites config loading as a part of the changes required to implement config commands +- This update adds commands to change all config values from the chat or the console, complete with tab completion +- Adds a new permission "stargate.admin.config" which is required to edit config values from the chat + #### \[Version 0.9.0.7] EpicKnarvik97 fork - Stops registering the sign as a lookup block for stargates without a sign diff --git a/pom.xml b/pom.xml index e20b239..4d91c35 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.0.7 + 0.9.1.0 diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 57ba4f2..e494e20 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -19,7 +19,7 @@ public class CommandConfig implements CommandExecutor { public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { if (commandSender instanceof Player player) { - if (!player.hasPermission("stargate.admin")) { + if (!player.hasPermission("stargate.admin.config")) { Stargate.getMessageSender().sendErrorMessage(commandSender, "Permission Denied"); return true; } diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index e9728c5..d67b4db 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -48,7 +48,7 @@ public class StarGateTabCompleter implements TabCompleter { if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.reload")) { commands.add("reload"); } - if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin")) { + if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.config")) { commands.add("config"); } return commands; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 02d8e18..7aeeb04 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.0.7 +version: 0.9.1.0 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] @@ -138,14 +138,18 @@ permissions: stargate.admin.bungee: description: Allows the creation and destruction of a stargate between BungeeCord servers default: false + stargate.admin.config: + description: Allows the player to change config values from the chat + default: false stargate.server: description: Allows the creation of a BungeeCord stargate going to any server default: false stargate.admin: - description: Allow all admin features and commands (Hidden/Private bypass, BungeeCord, Reload) + description: Allow all admin features and commands (Hidden/Private bypass, BungeeCord, Reload, Config) default: op children: stargate.admin.reload: true stargate.admin.hidden: true stargate.admin.private: true - stargate.admin.bungee: true \ No newline at end of file + stargate.admin.bungee: true + stargate.admin.config: true \ No newline at end of file From 7a03f49fb1522d53acd28e213ca18d4db910bbfd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 22:47:38 +0100 Subject: [PATCH 267/378] Translates the & character to make sure portal signs are colored on all servers --- .../stargate/portal/PortalSignDrawer.java | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index c84a1d1..2c4128b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -81,8 +81,7 @@ public class PortalSignDrawer { private void drawSign(Sign sign) { //Clear sign clearSign(sign); - setLine(sign, 0, highlightColor + "-" + mainColor + - portal.getName() + highlightColor + "-"); + setLine(sign, 0, highlightColor + "-" + mainColor + fixColor(portal.getName()) + highlightColor + "-"); if (!portal.getPortalActivator().isActive()) { //Default sign text @@ -123,7 +122,7 @@ public class PortalSignDrawer { return; } clearSign(sign); - sign.setLine(0, portal.getName()); + sign.setLine(0, fixColor(portal.getName())); sign.update(); } @@ -173,10 +172,10 @@ public class PortalSignDrawer { boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); ChatColor nameColor = (green ? freeColor : highlightColor); setLine(sign, signLineIndex, nameColor + ">" + (green ? freeColor : mainColor) + - portal.getDestinationName() + nameColor + "<"); + fixColor(portal.getDestinationName()) + nameColor + "<"); } else { - setLine(sign, signLineIndex, highlightColor + ">" + mainColor + portal.getDestinationName() + - highlightColor + "<"); + setLine(sign, signLineIndex, highlightColor + ">" + mainColor + + fixColor(portal.getDestinationName()) + highlightColor + "<"); } } @@ -205,9 +204,9 @@ public class PortalSignDrawer { if (freeGatesGreen) { Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork()); boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (green ? freeColor : mainColor) + destinationName); + setLine(sign, signLineIndex, (green ? freeColor : mainColor) + fixColor(destinationName)); } else { - setLine(sign, signLineIndex, mainColor + destinationName); + setLine(sign, signLineIndex, mainColor + fixColor(destinationName)); } } @@ -218,8 +217,10 @@ public class PortalSignDrawer { */ private void drawBungeeSign(Sign sign) { setLine(sign, 1, Stargate.getString("bungeeSign")); - setLine(sign, 2, highlightColor + ">" + mainColor + portal.getDestinationName() + highlightColor + "<"); - setLine(sign, 3, highlightColor + "[" + mainColor + portal.getNetwork() + highlightColor + "]"); + setLine(sign, 2, highlightColor + ">" + mainColor + fixColor(portal.getDestinationName()) + + highlightColor + "<"); + setLine(sign, 3, highlightColor + "[" + mainColor + fixColor(portal.getNetwork()) + + highlightColor + "]"); } /** @@ -233,7 +234,8 @@ public class PortalSignDrawer { setLine(sign, 1, Stargate.getString("signRightClick")); setLine(sign, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { - setLine(sign, 3, highlightColor + "(" + mainColor + portal.getNetwork() + highlightColor + ")"); + setLine(sign, 3, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + + highlightColor + ")"); } else { setLine(sign, 3, ""); } @@ -247,12 +249,13 @@ public class PortalSignDrawer { private void drawFixedSign(Sign sign) { String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : portal.getDestinationName(); - setLine(sign, 1, highlightColor + ">" + mainColor + destinationName + highlightColor + "<"); + setLine(sign, 1, highlightColor + ">" + mainColor + fixColor(destinationName) + highlightColor + "<"); if (portal.getOptions().isNoNetwork()) { setLine(sign, 2, ""); } else { - setLine(sign, 2, highlightColor + "(" + mainColor + portal.getNetwork() + highlightColor + ")"); + setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + + highlightColor + ")"); } Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { @@ -277,4 +280,14 @@ public class PortalSignDrawer { Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName)); } + /** + * Fixes coloring of signs as the & character isn't translated on all servers + * + * @param text

The text to fix the coloring of

+ * @return

The text with the coloring fixed

+ */ + private String fixColor(String text) { + return ChatColor.translateAlternateColorCodes('&', text); + } + } From 3db630f60ea80ea649b80b11e4e258051c3dff45 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 Nov 2021 22:51:11 +0100 Subject: [PATCH 268/378] Updates version and changelog --- README.md | 4 ++++ pom.xml | 2 +- .../knarcraft/stargate/portal/PortalSignDrawer.java | 12 ++++++------ src/main/resources/plugin.yml | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3557b6c..d9b1d74 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.1.1] EpicKnarvik97 fork + +- Makes sure to translate the `&` character to fix a bug causing portal signs to not be colored on some servers + #### \[Version 0.9.1.0] EpicKnarvik97 fork - Rewrites config loading as a part of the changes required to implement config commands diff --git a/pom.xml b/pom.xml index 4d91c35..c96dd5d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.1.0 + 0.9.1.1 diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 2c4128b..6133a89 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -174,7 +174,7 @@ public class PortalSignDrawer { setLine(sign, signLineIndex, nameColor + ">" + (green ? freeColor : mainColor) + fixColor(portal.getDestinationName()) + nameColor + "<"); } else { - setLine(sign, signLineIndex, highlightColor + ">" + mainColor + + setLine(sign, signLineIndex, highlightColor + ">" + mainColor + fixColor(portal.getDestinationName()) + highlightColor + "<"); } } @@ -217,9 +217,9 @@ public class PortalSignDrawer { */ private void drawBungeeSign(Sign sign) { setLine(sign, 1, Stargate.getString("bungeeSign")); - setLine(sign, 2, highlightColor + ">" + mainColor + fixColor(portal.getDestinationName()) + + setLine(sign, 2, highlightColor + ">" + mainColor + fixColor(portal.getDestinationName()) + highlightColor + "<"); - setLine(sign, 3, highlightColor + "[" + mainColor + fixColor(portal.getNetwork()) + + setLine(sign, 3, highlightColor + "[" + mainColor + fixColor(portal.getNetwork()) + highlightColor + "]"); } @@ -234,7 +234,7 @@ public class PortalSignDrawer { setLine(sign, 1, Stargate.getString("signRightClick")); setLine(sign, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { - setLine(sign, 3, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + + setLine(sign, 3, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + highlightColor + ")"); } else { setLine(sign, 3, ""); @@ -254,7 +254,7 @@ public class PortalSignDrawer { if (portal.getOptions().isNoNetwork()) { setLine(sign, 2, ""); } else { - setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + + setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + highlightColor + ")"); } Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); @@ -282,7 +282,7 @@ public class PortalSignDrawer { /** * Fixes coloring of signs as the & character isn't translated on all servers - * + * * @param text

The text to fix the coloring of

* @return

The text with the coloring fixed

*/ diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7aeeb04..fbc5416 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.1.0 +version: 0.9.1.1 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From ad310ddb9c95cb7f06a5f6c6b1b8808d03318b28 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 Nov 2021 22:54:20 +0100 Subject: [PATCH 269/378] Allows a sneaking player to see information about a silent stargate (0.9.1.2) --- README.md | 4 ++++ pom.xml | 2 +- .../net/knarcraft/stargate/listener/PlayerEventListener.java | 2 +- src/main/resources/plugin.yml | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d9b1d74..581c454 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.1.2] EpicKnarvik97 fork + +- Allows a sneaking player to see information about a silent stargate with no sign + #### \[Version 0.9.1.1] EpicKnarvik97 fork - Makes sure to translate the `&` character to fix a bug causing portal signs to not be colored on some servers diff --git a/pom.xml b/pom.xml index c96dd5d..72b0f05 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.1.1 + 0.9.1.2 diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index d38b117..94f5101 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -317,7 +317,7 @@ public class PlayerEventListener implements Listener { } //Display portal information as a portal without a sign does not display any - if (portal.getOptions().hasNoSign() && !portal.getOptions().isSilent()) { + if (portal.getOptions().hasNoSign() && (!portal.getOptions().isSilent() || player.isSneaking())) { MessageSender sender = Stargate.getMessageSender(); sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString("portalInfoTitle")); sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoName"), diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fbc5416..652ca2d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.1.1 +version: 0.9.1.2 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 42e02eb14191c82a800842716b601e6c1a2e849a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 Nov 2021 13:46:01 +0100 Subject: [PATCH 270/378] Makes the UUIDMigrationHelper final --- .../net/knarcraft/stargate/utility/UUIDMigrationHelper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java index 4e33457..6fc30a0 100644 --- a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -19,7 +19,11 @@ import java.util.UUID; /** * Helps migrate player names to UUID where necessary */ -public class UUIDMigrationHelper { +public final class UUIDMigrationHelper { + + private UUIDMigrationHelper() { + + } private static Map> playerNamesToMigrate; From 2c53b7d2a6a9b091635ac9f656e4d17a1c4c66db Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 Nov 2021 15:33:15 +0100 Subject: [PATCH 271/378] Makes portal names and networks case and color-insensitive and increases length limit to 13. #17 Ignores &[0-9a-f] color codes when counting towards the name and network string limits Makes portal lists store cleaned portal and network names to ignore case and color Names and networks will now match regardless of case and color Increases portal name/network limit to 13 characters --- .../listener/PlayerEventListener.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 51 ++++++++++++++++--- .../stargate/portal/PortalActivator.java | 12 ++--- .../stargate/portal/PortalCreator.java | 10 ++-- .../stargate/portal/PortalHandler.java | 13 ++--- .../stargate/portal/PortalOpener.java | 2 +- .../stargate/portal/PortalRegistry.java | 12 ++--- .../stargate/utility/BungeeHelper.java | 15 +++++- .../stargate/utility/PermissionHelper.java | 6 +-- .../stargate/utility/UUIDMigrationHelper.java | 4 +- 10 files changed, 87 insertions(+), 40 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 94f5101..70dc495 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -244,7 +244,7 @@ public class PlayerEventListener implements Listener { * @return

True if the player should be denied

*/ private boolean cannotAccessPortal(Player player, Portal portal) { - boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork()); + boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getCleanNetwork()); if (PermissionHelper.portalAccessDenied(player, portal, deny)) { if (!portal.getOptions().isSilent()) { diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 9b5449b..72463cf 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -8,6 +8,7 @@ import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.portal.property.gate.Gate; +import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; @@ -19,7 +20,10 @@ import java.util.Map; public class Portal { private final String name; + private final String cleanName; private final String network; + private final String cleanNetwork; + private final PortalOwner portalOwner; private boolean isRegistered; @@ -53,6 +57,8 @@ public class Portal { this.portalOpener = new PortalOpener(this, destination); this.structure = new PortalStructure(this, gate, button); this.portalActivator = portalOpener.getPortalActivator(); + this.cleanName = cleanString(name); + this.cleanNetwork = cleanString(network); } /** @@ -149,6 +155,15 @@ public class Portal { return network; } + /** + * Gets the clean name of the network this portal belongs to + * + * @return

The clean network name

+ */ + public String getCleanNetwork() { + return cleanNetwork; + } + /** * Gets the time this portal was triggered (activated/opened) * @@ -170,6 +185,15 @@ public class Portal { return name; } + /** + * Gets the clean name of this portal + * + * @return

The clean name of this portal

+ */ + public String getCleanName() { + return cleanName; + } + /** * Gets the portal opener used by this portal * @@ -273,6 +297,17 @@ public class Portal { return getTopLeft().getRelativeLocation(vector, getYaw()); } + /** + * Cleans a string by removing color codes, lower-casing and replacing spaces with underscores + * + * @param string

The string to clean

+ * @return

The clean string

+ */ + public static String cleanString(String string) { + string = ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string)); + return string.toLowerCase().replace(' ', '_'); + } + @Override public String toString() { return String.format("Portal [id=%s, network=%s name=%s, type=%s]", getSignLocation(), network, name, @@ -283,8 +318,8 @@ public class Portal { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((network == null) ? 0 : network.hashCode()); + result = prime * result + ((cleanName == null) ? 0 : cleanName.hashCode()); + result = prime * result + ((cleanNetwork == null) ? 0 : cleanNetwork.hashCode()); return result; } @@ -297,18 +332,18 @@ public class Portal { return false; } Portal other = (Portal) object; - if (name == null) { - if (other.name != null) { + if (cleanName == null) { + if (other.cleanName != null) { return false; } - } else if (!name.equalsIgnoreCase(other.name)) { + } else if (!cleanName.equalsIgnoreCase(other.cleanName)) { return false; } //If none of the portals have a name, check if the network is the same - if (network == null) { - return other.network == null; + if (cleanNetwork == null) { + return other.cleanNetwork == null; } else { - return network.equalsIgnoreCase(other.network); + return cleanNetwork.equalsIgnoreCase(other.cleanNetwork); } } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 3f8f5be..0e52d66 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -64,7 +64,7 @@ public class PortalActivator { * @return

The destination portal the player should teleport to

*/ public Portal getDestination(Player player) { - String portalNetwork = portal.getNetwork(); + String portalNetwork = portal.getCleanNetwork(); if (portal.getOptions().isRandom()) { //Find possible destinations List destinations = PortalHandler.getDestinations(portal, player, portalNetwork); @@ -73,10 +73,10 @@ public class PortalActivator { } //Get one random destination String destination = destinations.get((new Random()).nextInt(destinations.size())); - return PortalHandler.getByName(destination, portalNetwork); + return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork); } else { //Just return the normal fixed destination - return PortalHandler.getByName(destination, portalNetwork); + return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork); } } @@ -98,7 +98,7 @@ public class PortalActivator { * @param destination

The new destination of this portal activator's portal

*/ public void setDestination(Portal destination) { - setDestination(destination.getName()); + setDestination(destination.getCleanName()); } /** @@ -136,7 +136,7 @@ public class PortalActivator { //Set the given player as the active player activePlayer = player; - String network = portal.getNetwork(); + String network = portal.getCleanNetwork(); destinations = PortalHandler.getDestinations(portal, player, network); //Sort destinations if enabled @@ -242,7 +242,7 @@ public class PortalActivator { activate = true; Stargate.debug("cycleDestination", "Network Size: " + - PortalHandler.getNetwork(portal.getNetwork()).size()); + PortalHandler.getNetwork(portal.getCleanNetwork()).size()); Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index bf41a76..1b4e9b6 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -228,7 +228,7 @@ public class PortalCreator { */ private boolean checkIfNewPortalIsValid(int cost, String portalName) { //Check if the portal name can fit on the sign with padding (>name<) - if (portal.getName().length() < 1 || portal.getName().length() > 11) { + if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > 13) { Stargate.debug("createPortal", "Name length error"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength")); return false; @@ -236,21 +236,21 @@ public class PortalCreator { if (portal.getOptions().isBungee()) { //Check if the bungee portal's name has been duplicated - if (PortalHandler.getBungeePortals().get(portal.getName().toLowerCase()) != null) { + if (PortalHandler.getBungeePortals().get(portal.getCleanName()) != null) { Stargate.debug("createPortal::Bungee", "Gate name duplicate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); return false; } } else { //Check if the portal name has been duplicated on the network - if (PortalHandler.getByName(portal.getName(), portal.getNetwork()) != null) { + if (PortalHandler.getByName(portal.getCleanName(), portal.getCleanNetwork()) != null) { Stargate.debug("createPortal", "Gate name duplicate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); return false; } //Check if the number of portals in the network has been surpassed - List networkList = PortalHandler.getAllPortalNetworks().get(portal.getNetwork().toLowerCase()); + List networkList = PortalHandler.getAllPortalNetworks().get(portal.getCleanNetwork()); int maxGates = Stargate.getGateConfig().maxGatesEachNetwork(); if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createFull")); @@ -283,7 +283,7 @@ public class PortalCreator { portal.getPortalOpener().openPortal(true); } else if (portal.getOptions().isAlwaysOn()) { //For a normal always-on portal, open both the portal and the destination - Portal destinationPortal = PortalHandler.getByName(destinationName, portal.getNetwork()); + Portal destinationPortal = PortalHandler.getByName(destinationName, portal.getCleanNetwork()); if (destinationPortal != null) { portal.getPortalOpener().openPortal(true); destinationPortal.drawSign(); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index c75b6da..cabff97 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -66,7 +66,7 @@ public class PortalHandler { */ public static List getDestinations(Portal entrancePortal, Player player, String network) { List destinations = new ArrayList<>(); - for (String destination : PortalRegistry.getAllPortalNetworks().get(network.toLowerCase())) { + for (String destination : PortalRegistry.getAllPortalNetworks().get(network)) { Portal portal = getByName(destination, network); if (portal == null) { continue; @@ -80,11 +80,12 @@ public class PortalHandler { continue; } //Check if destination is this portal - if (destination.equalsIgnoreCase(entrancePortal.getName())) { + if (destination.equals(entrancePortal.getCleanName())) { continue; } //Check if destination is a fixed portal not pointing to this portal - if (portal.getOptions().isFixed() && !portal.getDestinationName().equalsIgnoreCase(entrancePortal.getName())) { + if (portal.getOptions().isFixed() && + !Portal.cleanString(portal.getDestinationName()).equals(entrancePortal.getCleanName())) { continue; } //Allow random use by non-players (Minecarts) @@ -182,10 +183,10 @@ public class PortalHandler { * @param portal

The newly created portal

*/ static void updatePortalsPointingAtNewPortal(Portal portal) { - for (String originName : PortalRegistry.getAllPortalNetworks().get(portal.getNetwork().toLowerCase())) { - Portal origin = getByName(originName, portal.getNetwork()); + for (String originName : PortalRegistry.getAllPortalNetworks().get(portal.getCleanNetwork())) { + Portal origin = getByName(originName, portal.getCleanNetwork()); if (origin == null || - !origin.getDestinationName().equalsIgnoreCase(portal.getName()) || + !Portal.cleanString(origin.getDestinationName()).equals(portal.getCleanName()) || !origin.getStructure().isVerified()) { continue; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 448537e..8390c05 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -126,7 +126,7 @@ public class PortalOpener { return; } - boolean thisIsDestination = destination.getDestinationName().equalsIgnoreCase(portal.getName()); + boolean thisIsDestination = Portal.cleanString(destination.getDestinationName()).equals(portal.getCleanName()); //Only open destination if it's not-fixed or points at this portal, and is not already open if (!options.isRandom() && (!destination.getOptions().isFixed() || thisIsDestination) && !destination.isOpen()) { //Open the destination portal diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index d58ae20..74faa96 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -63,7 +63,7 @@ public class PortalRegistry { private static void clearPortals(List portalsToRemove) { //Store the names of the portals to remove as some maps require the name, not the object List portalNames = new ArrayList<>(); - portalsToRemove.forEach((portal) -> portalNames.add(portal.getName())); + portalsToRemove.forEach((portal) -> portalNames.add(portal.getCleanName())); //Clear all the lookup locations for the portals lookupBlocks.keySet().removeIf((key) -> portalsToRemove.contains(lookupBlocks.get(key))); @@ -165,8 +165,8 @@ public class PortalRegistry { portal.getPortalActivator().deactivate(); portal.getPortalOpener().closePortal(true); - String portalName = portal.getName().toLowerCase(); - String networkName = portal.getNetwork().toLowerCase(); + String portalName = portal.getCleanName(); + String networkName = portal.getCleanNetwork(); //Remove portal from lookup blocks for (BlockLocation block : portal.getStructure().getFrame()) { @@ -203,7 +203,7 @@ public class PortalRegistry { //Update all portals in the same network with this portal as its destination for (String originName : allPortalNetworks.get(networkName)) { - Portal origin = PortalHandler.getByName(originName, portal.getNetwork()); + Portal origin = PortalHandler.getByName(originName, portal.getCleanNetwork()); if (origin == null || !origin.getDestinationName().equalsIgnoreCase(portalName) || !origin.getStructure().isVerified()) { continue; @@ -235,8 +235,8 @@ public class PortalRegistry { portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || portal.getOptions().isBungee()); - String portalName = portal.getName().toLowerCase(); - String networkName = portal.getNetwork().toLowerCase(); + String portalName = portal.getCleanName(); + String networkName = portal.getCleanNetwork(); //Bungee portals are stored in their own list if (portal.getOptions().isBungee()) { diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 9a508b2..8c87002 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; @@ -71,7 +72,7 @@ public final class BungeeHelper { //Build the message data and send it over the SGBungee BungeeCord channel dataOutputStream.writeUTF("Forward"); //Send the message to the server defined in the entrance portal's network line - dataOutputStream.writeUTF(entrancePortal.getNetwork()); + dataOutputStream.writeUTF(stripColor(entrancePortal.getNetwork())); //Specify the sub-channel/tag to make it recognizable on arrival dataOutputStream.writeUTF(bungeeSubChannel); //Write the length of the message @@ -102,7 +103,7 @@ public final class BungeeHelper { //Send a connect-message to connect the player to the server defined in the entrance portal's network line dataOutputStream.writeUTF("Connect"); - dataOutputStream.writeUTF(entrancePortal.getNetwork()); + dataOutputStream.writeUTF(stripColor(entrancePortal.getNetwork())); //Send the plugin message player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); @@ -207,4 +208,14 @@ public final class BungeeHelper { return true; } + /** + * Strips all color tags from a string + * + * @param string

The string to strip color from

+ * @return

The string without color codes

+ */ + private static String stripColor(String string) { + return ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string)); + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index b8351fa..6c0c226 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -105,12 +105,12 @@ public final class PermissionHelper { boolean deny = false; if (entrancePortal.getOptions().isBungee()) { - if (!PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { + if (!PermissionHelper.canAccessServer(player, entrancePortal.getCleanNetwork())) { //If the portal is a bungee portal, and the player cannot access the server, deny Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; } - } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { + } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getCleanNetwork())) { //If the player does not have access to the network, deny Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; @@ -345,7 +345,7 @@ public final class PermissionHelper { * @return

True if the player is allowed to destroy the portal

*/ public static boolean canDestroyPortal(Player player, Portal portal) { - String network = portal.getNetwork(); + String network = portal.getCleanNetwork(); //Use a special check for bungee portals if (portal.getOptions().isBungee()) { diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java index 6fc30a0..d74d57b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -22,7 +22,7 @@ import java.util.UUID; public final class UUIDMigrationHelper { private UUIDMigrationHelper() { - + } private static Map> playerNamesToMigrate; @@ -68,7 +68,7 @@ public final class UUIDMigrationHelper { //Get the real portal from the copy and set UUID for (Portal portalCopy : portals) { - Portal portal = PortalHandler.getByName(portalCopy.getName(), portalCopy.getNetwork()); + Portal portal = PortalHandler.getByName(portalCopy.getCleanName(), portalCopy.getCleanNetwork()); if (portal != null) { portal.getOwner().setUUID(uniqueId); worldsToSave.add(portal.getWorld()); From 351d1762e747e1d2fe73ff987654c3784a24a002 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 Nov 2021 15:50:32 +0100 Subject: [PATCH 272/378] Updates changelog, and updates version to 0.9.2.0 --- README.md | 17 +++++++++++++---- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 581c454..9d12fcf 100644 --- a/README.md +++ b/README.md @@ -119,9 +119,9 @@ section). See the Custom Gate Layout section to learn how to add custom gates. ### Sign Layout: -- Line 1: Gate Name (Max 11 characters) -- Line 2: Destination Name \[Optional] (Max 11 characters, used for fixed-gates only) -- Line 3: Network name \[Optional] (Max 11 characters) +- Line 1: Gate Name (Max 13 characters) +- Line 2: Destination Name \[Optional] (Max 13 characters, used for fixed-gates only) +- Line 3: Network name \[Optional] (Max 13 characters) - Line 4: Options \[Optional] : - 'A' for always-on fixed gate - 'H' for hidden networked gate @@ -136,7 +136,9 @@ section). See the Custom Gate Layout section to learn how to add custom gates. - 'I' is for a silent gate, which does not output anything to the chat while teleporting. Increases immersion - 'E' is for gate without a sign. Only for fixed stargates -The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. +The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. The +&\[0-9a-f] color codes are not counted in the character limit, thus allowing a 13-character name with an additional 2 +characters used for the color code. #### Gate networks: @@ -388,6 +390,13 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.2.0] EpicKnarvik97 fork + +- Increases max length of names and networks to 13 characters +- Excludes color codes from the counted character length to allow a colored, 13-character name +- Makes portal names and networks case- and color-agnostic to prevent some confusion caused by typos or sloppy + configuration + #### \[Version 0.9.1.2] EpicKnarvik97 fork - Allows a sneaking player to see information about a silent stargate with no sign diff --git a/pom.xml b/pom.xml index 72b0f05..6a501c0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.1.2 + 0.9.2.0 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 652ca2d..1448071 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.1.2 +version: 0.9.2.0 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From a84210d5506079cbb96931b5c9de483c03d4d053 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 13 Nov 2021 03:44:27 +0100 Subject: [PATCH 273/378] Fixes a couple of bugs which prevented portals using spaces in the name from being properly connected --- .../java/net/knarcraft/stargate/portal/PortalActivator.java | 2 +- .../java/net/knarcraft/stargate/portal/PortalSignDrawer.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 0e52d66..3397e81 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -98,7 +98,7 @@ public class PortalActivator { * @param destination

The new destination of this portal activator's portal

*/ public void setDestination(Portal destination) { - setDestination(destination.getCleanName()); + setDestination(destination.getName()); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 6133a89..cb59c04 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -257,7 +257,8 @@ public class PortalSignDrawer { setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + highlightColor + ")"); } - Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); + Portal destination = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), + portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { setLine(sign, 3, errorColor + Stargate.getString("signDisconnected")); } else { From e1a3d2d560bdbd404a8b53eda06852a6606bcb2a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 13 Nov 2021 17:02:13 +0100 Subject: [PATCH 274/378] Makes a fixed sign always use the destination portal's actual name if possible --- .../java/net/knarcraft/stargate/portal/PortalSignDrawer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index cb59c04..31b72f2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -247,8 +247,10 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawFixedSign(Sign sign) { + Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), + portal.getCleanNetwork()); String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : - portal.getDestinationName(); + (destinationPortal != null ? destinationPortal.getName() : portal.getDestinationName()); setLine(sign, 1, highlightColor + ">" + mainColor + fixColor(destinationName) + highlightColor + "<"); if (portal.getOptions().isNoNetwork()) { From 51f5420f9ea0062665b10a6567552d177b93f541 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 13 Nov 2021 17:04:13 +0100 Subject: [PATCH 275/378] Removes the replacement of spaces to underscores for the cleanString method --- src/main/java/net/knarcraft/stargate/portal/Portal.java | 3 +-- .../java/net/knarcraft/stargate/portal/PortalSignDrawer.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 72463cf..6a66e80 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -304,8 +304,7 @@ public class Portal { * @return

The clean string

*/ public static String cleanString(String string) { - string = ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string)); - return string.toLowerCase().replace(' ', '_'); + return ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string)).toLowerCase(); } @Override diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 31b72f2..a09b732 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -247,7 +247,7 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawFixedSign(Sign sign) { - Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), + Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getCleanNetwork()); String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : (destinationPortal != null ? destinationPortal.getName() : portal.getDestinationName()); @@ -259,7 +259,7 @@ public class PortalSignDrawer { setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + highlightColor + ")"); } - Portal destination = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), + Portal destination = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { setLine(sign, 3, errorColor + Stargate.getString("signDisconnected")); From 29c1a00fcdaa9d3ae7878fa13c6bfab642c76c37 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 13 Nov 2021 19:28:17 +0100 Subject: [PATCH 276/378] Makes the max portal name and network character limit more easily changeable --- src/main/java/net/knarcraft/stargate/Stargate.java | 9 +++++++++ .../knarcraft/stargate/portal/PortalCreator.java | 14 +++++++++----- .../stargate/utility/PermissionHelper.java | 6 ++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 1b4039a..1e0f3da 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -139,6 +139,15 @@ public class Stargate extends JavaPlugin { return logger; } + /** + * Gets the max length of portal names and networks + * + * @return

The max portal name/network length

+ */ + public static int getMaxNameNetworkLength() { + return 13; + } + /** * Sends a debug message * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 1b4e9b6..dac659f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -22,6 +22,8 @@ import org.bukkit.event.block.SignChangeEvent; import java.util.List; import java.util.Map; +import static net.knarcraft.stargate.Stargate.getMaxNameNetworkLength; + /** * The portal creator can create and validate a new portal */ @@ -105,7 +107,8 @@ public class PortalCreator { Stargate.debug("createPortal", builder.toString()); //Use default network if a proper alternative is not set - if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > 11)) { + if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > + getMaxNameNetworkLength())) { network = Stargate.getDefaultNetwork(); } @@ -117,8 +120,8 @@ public class PortalCreator { Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); if (PermissionHelper.canCreatePersonalPortal(player)) { network = player.getName(); - if (network.length() > 11) { - network = network.substring(0, 11); + if (network.length() > getMaxNameNetworkLength()) { + network = network.substring(0, getMaxNameNetworkLength()); } Stargate.debug("createPortal", "Creating personal portal"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createPersonal")); @@ -228,8 +231,9 @@ public class PortalCreator { */ private boolean checkIfNewPortalIsValid(int cost, String portalName) { //Check if the portal name can fit on the sign with padding (>name<) - if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > 13) { - Stargate.debug("createPortal", "Name length error"); + if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > getMaxNameNetworkLength()) { + Stargate.debug("createPortal", String.format("Name length error. %s is too long.", + portal.getCleanName())); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength")); return false; } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 6c0c226..9454c43 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -8,6 +8,8 @@ import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; +import static net.knarcraft.stargate.Stargate.getMaxNameNetworkLength; + /** * Helper class for deciding which actions a player is allowed to perform */ @@ -200,8 +202,8 @@ public final class PermissionHelper { } //Is able to create personal gates (Assumption is made they can also access them) String playerName = player.getName(); - if (playerName.length() > 11) { - playerName = playerName.substring(0, 11); + if (playerName.length() > getMaxNameNetworkLength()) { + playerName = playerName.substring(0, getMaxNameNetworkLength()); } return !network.equals(playerName) || !hasPermission(player, "stargate.create.personal"); } From 4699f717eccade820ca305fa90058d0792ee94f6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 14 Nov 2021 14:35:45 +0100 Subject: [PATCH 277/378] Ignores color codes and case when sorting destination names --- .../java/net/knarcraft/stargate/portal/PortalActivator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 3397e81..c0fd01e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -6,7 +6,7 @@ import net.knarcraft.stargate.event.StargateDeactivateEvent; import org.bukkit.entity.Player; import java.util.ArrayList; -import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Random; @@ -141,7 +141,7 @@ public class PortalActivator { //Sort destinations if enabled if (Stargate.getGateConfig().sortNetworkDestinations()) { - Collections.sort(destinations); + destinations.sort(Comparator.comparing(Portal::cleanString)); } //Select last used destination if remember destination is enabled From 10c3914a6072387e1514c6789da848491e785f24 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 15 Nov 2021 00:35:28 +0100 Subject: [PATCH 278/378] Makes the free gate color configurable --- README.md | 4 +- .../stargate/command/ConfigTabCompleter.java | 1 + .../stargate/config/ConfigOption.java | 60 ++++++++++++++++++- .../stargate/config/EconomyConfig.java | 21 +++++-- .../stargate/config/StargateConfig.java | 4 +- .../stargate/config/StargateGateConfig.java | 2 +- .../stargate/portal/PortalSignDrawer.java | 53 +++++++++------- src/main/resources/config-migrations.txt | 3 +- src/main/resources/config.yml | 6 +- 9 files changed, 117 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 9d12fcf..0e8956c 100644 --- a/README.md +++ b/README.md @@ -325,7 +325,8 @@ economy: useCost - The cost to use a stargate toOwner - Whether the money from gate-use goes to the owner or nobody chargeFreeDestination - Enable to make players pay for teleportation even if the destination is free - freeGatesGreen - Enable to make gates that won't cost the player money show up as green + freeGatesColored - Enable to make gates that won't cost the player money show up as green + freeGatesColor - This allows you to specify the color of the markings and name of free stargates debugging: debug - Whether to show massive debug output permissionDebug - Whether to show massive permission debug output @@ -396,6 +397,7 @@ portalInfoServer=Server: %server% - Excludes color codes from the counted character length to allow a colored, 13-character name - Makes portal names and networks case- and color-agnostic to prevent some confusion caused by typos or sloppy configuration +- Makes the free gate color configurable, and renames freeGatesGreen to freeGatesColored #### \[Version 0.9.1.2] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index 046f4f2..8484322 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -86,6 +86,7 @@ public class ConfigTabCompleter implements TabCompleter { } case MAIN_SIGN_COLOR: case HIGHLIGHT_SIGN_COLOR: + case FREE_GATES_COLOR: //Return all colors return filterMatching(getColors(), typedText); } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index da046b1..9bd6bf9 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -9,86 +9,144 @@ public enum ConfigOption { * The language used for player-interface text */ LANGUAGE("language", "The language used for all signs and all messages to players", "en"), + /** * The folder for portal files */ PORTAL_FOLDER("folders.portalFolder", "The folder containing the portal databases", "plugins/Stargate/portals/"), + /** * The folder for gate files */ GATE_FOLDER("folders.gateFolder", "The folder containing all gate files", "plugins/Stargate/gates/"), + /** * The max number of portals on a single network */ MAX_GATES_EACH_NETWORK("gates.maxGatesEachNetwork", "The max number of stargates in a single network", 0), + /** * The network used if not specified */ DEFAULT_GATE_NETWORK("gates.defaultGateNetwork", "The network used when no network is specified", "central"), + /** * Whether to remember the lastly used destination */ REMEMBER_DESTINATION("gates.cosmetic.rememberDestination", "Whether to remember the last destination used", false), + /** * Whether to sort the network destinations */ SORT_NETWORK_DESTINATIONS("gates.cosmetic.sortNetworkDestinations", "Whether to sort destinations by name", false), + /** * The main color to use for all signs */ MAIN_SIGN_COLOR("gates.cosmetic.mainSignColor", "The main text color of all stargate signs", "BLACK"), + /** * The color to use for highlighting sign text */ HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"), + /** * Whether to destroy portals when any blocks are broken by explosions */ DESTROYED_BY_EXPLOSION("gates.integrity.destroyedByExplosion", "Whether stargates should be destroyed by explosions", false), + /** * Whether to verify each portal's gate layout after each load */ VERIFY_PORTALS("gates.integrity.verifyPortals", "Whether to verify that portals match their gate layout on load", false), + /** * Whether to protect the entrance of portals */ PROTECT_ENTRANCE("gates.integrity.protectEntrance", "Whether to protect stargates' entrances", false), + /** * Whether to enable BungeeCord support */ ENABLE_BUNGEE("gates.functionality.enableBungee", "Whether to enable BungeeCord support", false), + /** * Whether to enable vehicle teleportation */ HANDLE_VEHICLES("gates.functionality.handleVehicles", "Whether to enable vehicle teleportation", true), + /** * Whether to enable teleportation of empty vehicles */ HANDLE_EMPTY_VEHICLES("gates.functionality.handleEmptyVehicles", "Whether to enable teleportation of empty vehicles", true), + /** * Whether to enable teleportation of creatures using vehicles */ HANDLE_CREATURE_TRANSPORTATION("gates.functionality.handleCreatureTransportation", "Whether to enable teleportation of vehicles containing non-player creatures", true), + /** * Whether to allow creatures to teleport alone, bypassing any access restrictions */ HANDLE_NON_PLAYER_VEHICLES("gates.functionality.handleNonPlayerVehicles", "Whether to enable teleportation of non-empty vehicles without a player", true), + /** * Whether to enable teleportations of creatures on a leash */ HANDLE_LEASHED_CREATURES("gates.functionality.handleLeashedCreatures", "Whether to enable players to teleport a creature on a leash", true), + + /** + * Whether to enable economy support for taking payment from players creating/destroying/using stargates + */ USE_ECONOMY("economy.useEconomy", "Whether to use economy to incur fees when stargates are used, created or destroyed", false), + + /** + * The cost of creating a new stargate + */ CREATE_COST("economy.createCost", "The cost of creating a new stargate", 0), + + /** + * The cost of destroying a stargate + */ DESTROY_COST("economy.destroyCost", "The cost of destroying a stargate. Negative to refund", 0), + + /** + * The cost of using (teleporting through) a stargate + */ USE_COST("economy.useCost", "The cost of using (teleporting through) a stargate", 0), + + /** + * Whether any payments should go to the stargate's owner + */ TO_OWNER("economy.toOwner", "Whether any teleportation fees should go to the owner of the used stargate", false), + + /** + * Whether to charge for using a stargate, even if its destination is free + */ CHARGE_FREE_DESTINATION("economy.chargeFreeDestination", "Whether to require payment if the destination is free, but the entrance stargate is not", true), - FREE_GATES_GREEN("economy.freeGatesGreen", "Whether to use green coloring to mark all free stargates", false), + + /** + * Whether to mark free gates with a different color + */ + FREE_GATES_COLORED("economy.freeGatesColored", "Whether to use coloring to mark all free stargates", false), + + /** + * The color to use for marking free stargates + */ + FREE_GATES_COLOR("economy.freeGatesColor", "The color to use for marking free stargates", "DARK_GREEN"), + + /** + * Whether to enable debug output + */ DEBUG("debugging.debug", "Whether to enable debugging output", false), + + /** + * Whether to enable debug output for debugging permissions + */ PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", false); diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 22ae241..6c645d8 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -2,10 +2,12 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalSignDrawer; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.utility.PermissionHelper; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -28,7 +30,7 @@ public final class EconomyConfig { private int destroyCost = 0; private boolean toOwner = false; private boolean chargeFreeDestination = true; - private boolean freeGatesGreen = false; + private boolean freeGatesColored = false; /** * Instantiates a new economy config @@ -84,12 +86,12 @@ public final class EconomyConfig { } /** - * Gets whether free portals should be marked with green coloring + * Gets whether free portals should be marked with a different coloring * - * @return

Whether free portals should be green

+ * @return

Whether free portals should be colored

*/ - public boolean drawFreePortalsGreen() { - return freeGatesGreen; + public boolean drawFreePortalsColored() { + return freeGatesColored; } /** @@ -341,7 +343,14 @@ public final class EconomyConfig { setDefaultUseCost((Integer) configOptions.get(ConfigOption.USE_COST)); toOwner = (boolean) configOptions.get(ConfigOption.TO_OWNER); chargeFreeDestination = (boolean) configOptions.get(ConfigOption.CHARGE_FREE_DESTINATION); - freeGatesGreen = (boolean) configOptions.get(ConfigOption.FREE_GATES_GREEN); + freeGatesColored = (boolean) configOptions.get(ConfigOption.FREE_GATES_COLORED); + + try { + String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR); + PortalSignDrawer.setFreeColor(ChatColor.valueOf(freeColor.toUpperCase())); + } catch (IllegalArgumentException | NullPointerException ignored) { + PortalSignDrawer.setFreeColor(ChatColor.DARK_GREEN); + } } /** diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index f9e7144..88caa6a 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -309,9 +309,7 @@ public final class StargateConfig { FileConfiguration newConfig = Stargate.getInstance().getConfig(); boolean isMigrating = false; - if (newConfig.getString("lang") != null || - newConfig.getString("gates.integrity.ignoreEntrance") != null || - newConfig.getString("ignoreEntrance") != null) { + if (newConfig.getString("lang") != null || newConfig.getString("economy.freeGatesGreen") != null) { migrateConfig(newConfig); isMigrating = true; } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index f14dd6b..f1640e0 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -188,7 +188,7 @@ public final class StargateGateConfig { * @param mainSignColor

A string representing the main sign color

*/ private void loadSignColor(String mainSignColor, String highlightSignColor) { - if (mainSignColor != null) { + if (mainSignColor != null && highlightSignColor != null) { try { PortalSignDrawer.setColors(ChatColor.valueOf(mainSignColor.toUpperCase()), ChatColor.valueOf(highlightSignColor.toUpperCase())); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index a09b732..2921bf8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -15,7 +15,7 @@ public class PortalSignDrawer { private final Portal portal; private final static ChatColor errorColor = ChatColor.DARK_RED; - private final static ChatColor freeColor = ChatColor.DARK_GREEN; + private static ChatColor freeColor; private static ChatColor mainColor; private static ChatColor highlightColor; @@ -29,7 +29,7 @@ public class PortalSignDrawer { } /** - * Sets the main sign color + * Sets the main and highlighting sign colors * *

The main sign color is used for most text on the sign, while the highlighting color is used for the markings * around portal names and network names ('>','<','-',')','(')

@@ -42,6 +42,15 @@ public class PortalSignDrawer { highlightColor = newHighlightColor; } + /** + * Sets the color to use for marking free stargates + * + * @param freeColor

The new color to use for marking free stargates

+ */ + public static void setFreeColor(ChatColor freeColor) { + PortalSignDrawer.freeColor = freeColor; + } + /** * Draws the sign of the portal this sign drawer is responsible for */ @@ -136,42 +145,42 @@ public class PortalSignDrawer { int maxIndex = destinations.getDestinations().size() - 1; int signLineIndex = 0; int destinationIndex = destinations.getDestinations().indexOf(portal.getDestinationName()); - boolean freeGatesGreen = Stargate.getEconomyConfig().useEconomy() && - Stargate.getEconomyConfig().drawFreePortalsGreen(); + boolean freeGatesColored = Stargate.getEconomyConfig().useEconomy() && + Stargate.getEconomyConfig().drawFreePortalsColored(); //Last, and not only entry. Draw the entry two back if ((destinationIndex == maxIndex) && (maxIndex > 1)) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 2); + drawNetworkSignLine(freeGatesColored, sign, ++signLineIndex, destinationIndex - 2); } //Not first entry. Draw the previous entry if (destinationIndex > 0) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex - 1); + drawNetworkSignLine(freeGatesColored, sign, ++signLineIndex, destinationIndex - 1); } //Draw the chosen entry (line 2 or 3) - drawNetworkSignChosenLine(freeGatesGreen, sign, ++signLineIndex); + drawNetworkSignChosenLine(freeGatesColored, sign, ++signLineIndex); //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 1)) { - drawNetworkSignLine(freeGatesGreen, sign, ++signLineIndex, destinationIndex + 1); + drawNetworkSignLine(freeGatesColored, sign, ++signLineIndex, destinationIndex + 1); } //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { - drawNetworkSignLine(freeGatesGreen, sign, signLineIndex, destinationIndex + 2); + drawNetworkSignLine(freeGatesColored, sign, signLineIndex, destinationIndex + 2); } } /** * Draws the chosen destination on one sign line * - * @param freeGatesGreen

Whether to display free gates in a green color

- * @param sign

The sign to draw on

- * @param signLineIndex

The line to draw on

+ * @param freeGatesColored

Whether to display free gates in a different color

+ * @param sign

The sign to draw on

+ * @param signLineIndex

The line to draw on

*/ - private void drawNetworkSignChosenLine(boolean freeGatesGreen, Sign sign, int signLineIndex) { - if (freeGatesGreen) { + private void drawNetworkSignChosenLine(boolean freeGatesColored, Sign sign, int signLineIndex) { + if (freeGatesColored) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); - boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - ChatColor nameColor = (green ? freeColor : highlightColor); - setLine(sign, signLineIndex, nameColor + ">" + (green ? freeColor : mainColor) + + boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); + ChatColor nameColor = (free ? freeColor : highlightColor); + setLine(sign, signLineIndex, nameColor + ">" + (free ? freeColor : mainColor) + fixColor(portal.getDestinationName()) + nameColor + "<"); } else { setLine(sign, signLineIndex, highlightColor + ">" + mainColor + @@ -193,18 +202,18 @@ public class PortalSignDrawer { /** * Draws one network destination on one sign line * - * @param freeGatesGreen

Whether to display free gates in a green color

+ * @param freeGatesColored

Whether to display free gates in a different color

* @param sign

The sign to draw on

* @param signLineIndex

The line to draw on

* @param destinationIndex

The index of the destination to draw

*/ - private void drawNetworkSignLine(boolean freeGatesGreen, Sign sign, int signLineIndex, int destinationIndex) { + private void drawNetworkSignLine(boolean freeGatesColored, Sign sign, int signLineIndex, int destinationIndex) { PortalActivator destinations = portal.getPortalActivator(); String destinationName = destinations.getDestinations().get(destinationIndex); - if (freeGatesGreen) { + if (freeGatesColored) { Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork()); - boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (green ? freeColor : mainColor) + fixColor(destinationName)); + boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); + setLine(sign, signLineIndex, (free ? freeColor : mainColor) + fixColor(destinationName)); } else { setLine(sign, signLineIndex, mainColor + fixColor(destinationName)); } diff --git a/src/main/resources/config-migrations.txt b/src/main/resources/config-migrations.txt index 2de4df7..b38533f 100644 --- a/src/main/resources/config-migrations.txt +++ b/src/main/resources/config-migrations.txt @@ -24,4 +24,5 @@ usecost=economy.useCost toowner=economy.toOwner chargefreedestination=economy.chargeFreeDestination freegatesgreen=economy.freeGatesGreen -CheckUpdates= \ No newline at end of file +CheckUpdates= +economy.freeGatesGreen=economy.freeGatesColored \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index aa6aec7..4852940 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -27,7 +27,8 @@ # useCost - The cost to use a gate # toOwner - Whether the charge for using a gate goes to the gate's owner # chargeFreeDestination - Whether a gate whose destination is a free gate is still charged -# freeGatesGreen - Whether a free gate in the destination list is drawn green +# freeGatesColored - Whether a free gate in the destination list is marked with a color +# freeGatesColor - The color to use for marking free gates # I-------I-------I # # Debug options # # I-------I-------I # @@ -64,7 +65,8 @@ economy: useCost: 0 toOwner: false chargeFreeDestination: true - freeGatesGreen: false + freeGatesColored: false + freeGatesColor: DARK_GREEN debugging: debug: false permissionDebug: false \ No newline at end of file From 70495220eb0437f3389c0f0a13e6540b7ae0beca Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 15 Nov 2021 17:18:00 +0100 Subject: [PATCH 279/378] Simplifies some function calls --- .../knarcraft/stargate/portal/teleporter/Teleporter.java | 6 +++--- .../net/knarcraft/stargate/utility/PortalFileHelper.java | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 8cc3e6f..06befad 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -191,9 +191,9 @@ public abstract class Teleporter { */ private Location adjustExitLocation(Location traveller, Location exitLocation) { if (exitLocation != null) { - BlockData blockData = portal.getWorld().getBlockAt(exitLocation).getBlockData(); - if ((blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) || - (blockData instanceof Slab) && ((Slab) blockData).getType() == Slab.Type.BOTTOM) { + BlockData blockData = exitLocation.getBlock().getBlockData(); + if ((blockData instanceof Bisected bisected && bisected.getHalf() == Bisected.Half.BOTTOM) || + (blockData instanceof Slab slab && slab.getType() == Slab.Type.BOTTOM)) { //Prevent traveller from spawning inside a slab Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); exitLocation.add(0, 1, 0); diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index b2678a7..74741fc 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -292,16 +292,15 @@ public final class PortalFileHelper { */ private static void updatePortalButton(Portal portal) { BlockLocation buttonLocation = getButtonLocation(portal); - BlockData buttonData = buttonLocation.getBlock().getBlockData(); if (portal.getOptions().isAlwaysOn()) { //Clear button if not already air or water - if (MaterialHelper.isButtonCompatible(buttonData.getMaterial())) { + if (MaterialHelper.isButtonCompatible(buttonLocation.getType())) { Material newMaterial = decideRemovalMaterial(buttonLocation, portal); Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, newMaterial, null)); } } else { //Replace button if the material does not match - if (buttonData.getMaterial() != portal.getGate().getPortalButton()) { + if (buttonLocation.getType() != portal.getGate().getPortalButton()) { generatePortalButton(portal, DirectionHelper.getBlockFaceFromYaw(portal.getYaw())); } } From 37ac3d4877ca7832986ad60937491b8e295611d6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 15 Nov 2021 17:25:03 +0100 Subject: [PATCH 280/378] Fixes a debug route --- .../net/knarcraft/stargate/utility/UUIDMigrationHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java index d74d57b..4cb4472 100644 --- a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -44,7 +44,7 @@ public final class UUIDMigrationHelper { return; } - Stargate.debug("PlayerEventListener::migrateUUID", String.format("Migrating name to UUID for player %s", + Stargate.debug("UUIDMigrationHelper::migrateUUID", String.format("Migrating name to UUID for player %s", playerName)); List portalsOwned = playersToMigrate.get(playerName); if (portalsOwned == null) { From 1247c548990b357275e493101f633a8a95e6add3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 21 Nov 2021 13:10:13 +0100 Subject: [PATCH 281/378] Fixes some wrong migration information --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0e8956c..7eed297 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,8 @@ Permissions have had a few changes, so you should check the permissions section permissions. Payment to owner using Economy, through Vault, is only possible if the portal owner in the portal database is defined by -a UUID, and not a username. Right now, there is no automatic upgrade from usernames to UUID. You must either make the -stargate owner re-create the stargate or edit the file in the portals folder in a text editor. There are various ways to -find the UUID of players. You may look in the usercache.json file in the server directory or search for the username on -various websites. +a UUID, and not a username. A player name will be upgraded to a UUID when the player with the given name joins the +server. # Permissions From 48bb68d665a2ee1e5229f77d99a375b6313ebd7e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 21 Nov 2021 13:34:52 +0100 Subject: [PATCH 282/378] Adds a missing 'a' in a sentence --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7eed297..cf7d8f8 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ section). See the Custom Gate Layout section to learn how to add custom gates. player enters. (Implicitly always on) - 'U' is for a gate connecting to another through bungee (Implicitly always on) - 'I' is for a silent gate, which does not output anything to the chat while teleporting. Increases immersion - - 'E' is for gate without a sign. Only for fixed stargates + - 'E' is for a gate without a sign. Only for fixed stargates The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. The &\[0-9a-f] color codes are not counted in the character limit, thus allowing a 13-character name with an additional 2 From a80a8520ceebd24a20d0eaa8e5e8c734a2bc6a8b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Nov 2021 17:58:56 +0100 Subject: [PATCH 283/378] Improves the description of the /sg command --- src/main/resources/plugin.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1448071..0500053 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -11,8 +11,8 @@ commands: stargate: aliases: - sg - description: Used to see stargate info - usage: / - Used to see stargate info or reload the plugin + description: Used to see stargate info, reloading and editing config values + usage: / - Used to see stargate info, reload the plugin or change config values permissions: stargate.*: description: Wildcard permission which gives all Stargate permissions From ab9a118d4974f1a1aa515a52fdf993880b670290 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 22 Nov 2021 22:01:43 +0100 Subject: [PATCH 284/378] Prevents an empty deny reason from being displayed --- .../net/knarcraft/stargate/listener/BlockEventListener.java | 4 +++- .../java/net/knarcraft/stargate/portal/PortalCreator.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 1fa29a8..b0c0576 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -140,7 +140,9 @@ public class BlockEventListener implements Listener { //Destroy denied if (destroyEvent.getDeny()) { - Stargate.getMessageSender().sendErrorMessage(player, destroyEvent.getDenyReason()); + if (!destroyEvent.getDenyReason().trim().isEmpty()) { + Stargate.getMessageSender().sendErrorMessage(player, destroyEvent.getDenyReason()); + } event.setCancelled(true); return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index dac659f..306503f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -192,7 +192,9 @@ public class PortalCreator { //Tell the user why it was denied from creating the portal if (stargateCreateEvent.getDeny()) { - Stargate.getMessageSender().sendErrorMessage(player, stargateCreateEvent.getDenyReason()); + if (!stargateCreateEvent.getDenyReason().trim().isEmpty()) { + Stargate.getMessageSender().sendErrorMessage(player, stargateCreateEvent.getDenyReason()); + } return null; } From 22bb75d4dfc4b8cf0ad38f7a6b3fc151f41957c7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 23 Nov 2021 07:20:48 +0100 Subject: [PATCH 285/378] Moves some methods from EconomyConfig to EconomyHelper and tries to simplify EconomyConfig --- .../java/net/knarcraft/stargate/Stargate.java | 1 + .../stargate/command/CommandConfig.java | 32 ++- .../stargate/config/EconomyConfig.java | 185 ++---------------- .../stargate/listener/BlockEventListener.java | 2 +- .../listener/VehicleEventListener.java | 4 +- .../stargate/portal/PortalCreator.java | 2 +- .../stargate/utility/EconomyHelper.java | 117 ++++++++++- .../stargate/utility/PermissionHelper.java | 4 +- 8 files changed, 165 insertions(+), 182 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 1e0f3da..e3055d6 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -144,6 +144,7 @@ public class Stargate extends JavaPlugin { * * @return

The max portal name/network length

*/ + @SuppressWarnings("SameReturnValue") public static int getMaxNameNetworkLength() { return 13; } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index e494e20..54aa1a5 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -68,11 +68,11 @@ public class CommandConfig implements CommandExecutor { switch (selectedOption.getDataType()) { case BOOLEAN -> configuration.set(selectedOption.getConfigNode(), Boolean.parseBoolean(value)); case INTEGER -> { - try { - configuration.set(selectedOption.getConfigNode(), Integer.parseInt(value)); - } catch (NumberFormatException exception) { - commandSender.sendMessage(ChatColor.RED + "Invalid number given"); + Integer intValue = getInteger(commandSender, selectedOption, value); + if (intValue == null) { return; + } else { + configuration.set(selectedOption.getConfigNode(), intValue); } } case STRING -> { @@ -93,6 +93,30 @@ public class CommandConfig implements CommandExecutor { reloadIfNecessary(commandSender); } + /** + * Gets an integer from a string + * + * @param commandSender

The command sender that sent the config command

+ * @param selectedOption

The option the command sender is trying to change

+ * @param value

The value given

+ * @return

An integer, or null if it was invalid

+ */ + private Integer getInteger(CommandSender commandSender, ConfigOption selectedOption, String value) { + try { + int intValue = Integer.parseInt(value); + + if ((selectedOption == ConfigOption.USE_COST || selectedOption == ConfigOption.CREATE_COST) && intValue < 0) { + commandSender.sendMessage(ChatColor.RED + "This config option cannot be negative."); + return null; + } + + return intValue; + } catch (NumberFormatException exception) { + commandSender.sendMessage(ChatColor.RED + "Invalid number given"); + return null; + } + } + /** * Reloads the config if necessary * diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 6c645d8..ba842d3 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -1,12 +1,10 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalSignDrawer; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.utility.PermissionHelper; import net.milkbowl.vault.economy.Economy; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -15,22 +13,16 @@ import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicesManager; import java.util.Map; -import java.util.UUID; /** * The economy config keeps track of economy config values and performs economy actions such as payment for using a gate */ public final class EconomyConfig { - private boolean economyEnabled = false; private Economy economy = null; private Plugin vault = null; - private int useCost = 0; - private int createCost = 0; - private int destroyCost = 0; - private boolean toOwner = false; - private boolean chargeFreeDestination = true; - private boolean freeGatesColored = false; + + private final Map configOptions; /** * Instantiates a new economy config @@ -38,6 +30,7 @@ public final class EconomyConfig { * @param configOptions

The loaded config options to read

*/ public EconomyConfig(Map configOptions) { + this.configOptions = configOptions; loadEconomyConfig(configOptions); } @@ -47,7 +40,7 @@ public final class EconomyConfig { * @return

The gate use cost

*/ public int getDefaultUseCost() { - return useCost; + return (Integer) configOptions.get(ConfigOption.USE_COST); } /** @@ -56,7 +49,7 @@ public final class EconomyConfig { * @return

Whether economy is enabled

*/ public boolean isEconomyEnabled() { - return economyEnabled; + return (boolean) configOptions.get(ConfigOption.USE_ECONOMY); } /** @@ -91,7 +84,7 @@ public final class EconomyConfig { * @return

Whether free portals should be colored

*/ public boolean drawFreePortalsColored() { - return freeGatesColored; + return (boolean) configOptions.get(ConfigOption.FREE_GATES_COLORED); } /** @@ -103,8 +96,8 @@ public final class EconomyConfig { * * @return

Whether to charge for free destinations

*/ - public boolean chargeFreeDestination() { - return chargeFreeDestination; + public boolean freeIfFreeDestination() { + return !((boolean) configOptions.get(ConfigOption.CHARGE_FREE_DESTINATION)); } /** @@ -113,21 +106,7 @@ public final class EconomyConfig { * @return

Whether to send payments to the portal owner

*/ public boolean sendPaymentToOwner() { - return toOwner; - } - - /** - * Sets the cost of using a gate without a specified cost - * - *

The use cost cannot be negative.

- * - * @param useCost

The gate use cost

- */ - public void setDefaultUseCost(int useCost) { - if (useCost < 0) { - throw new IllegalArgumentException("Using a gate cannot cost a negative amount"); - } - this.useCost = useCost; + return (boolean) configOptions.get(ConfigOption.TO_OWNER); } /** @@ -136,18 +115,7 @@ public final class EconomyConfig { * @return

The gate creation cost

*/ public int getDefaultCreateCost() { - return createCost; - } - - /** - * Sets the cost of creating a gate without a specified cost - * - *

The gate create cost cannot be negative

- * - * @param createCost

The gate creation cost

- */ - public void setDefaultCreateCost(int createCost) { - this.createCost = createCost; + return (Integer) configOptions.get(ConfigOption.CREATE_COST); } /** @@ -156,31 +124,7 @@ public final class EconomyConfig { * @return

The gate destruction cost

*/ public int getDefaultDestroyCost() { - return destroyCost; - } - - /** - * Sets the cost of destroying a gate without a specified cost - * - * @param destroyCost

The gate destruction cost

- */ - public void setDefaultDestroyCost(int destroyCost) { - this.destroyCost = destroyCost; - } - - /** - * Charges the player for an action, if required - * - * @param player

The player to take money from

- * @param cost

The cost of the transaction

- * @return

True if the player was charged successfully

- */ - public boolean chargePlayerIfNecessary(Player player, int cost) { - if (skipPayment(cost)) { - return true; - } - //Charge player - return chargePlayer(player, cost); + return (Integer) configOptions.get(ConfigOption.DESTROY_COST); } /** @@ -194,22 +138,6 @@ public final class EconomyConfig { return economy.getBalance(player) > cost; } - /** - * Charges the player for an action, if required - * - * @param player

The player to take money from

- * @param target

The target to pay

- * @param cost

The cost of the transaction

- * @return

True if the player was charged successfully

- */ - public boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { - if (skipPayment(cost)) { - return true; - } - //Charge player - return chargePlayer(player, target, cost); - } - /** * Gets a formatted string for an amount, adding the name of the currency * @@ -217,7 +145,7 @@ public final class EconomyConfig { * @return

A formatted text string describing the amount

*/ public String format(int amount) { - if (economyEnabled) { + if (isEconomyEnabled()) { return economy.format(amount); } else { return ""; @@ -231,7 +159,7 @@ public final class EconomyConfig { * @return

True if economy was enabled

*/ public boolean setupEconomy(PluginManager pluginManager) { - if (!economyEnabled) { + if (!isEconomyEnabled()) { return false; } //Check if vault is loaded @@ -249,7 +177,7 @@ public final class EconomyConfig { } else { Stargate.logInfo(Stargate.getString("vaultLoadError")); } - economyEnabled = false; + configOptions.put(ConfigOption.USE_ECONOMY, false); return false; } @@ -259,46 +187,7 @@ public final class EconomyConfig { * @return

True if the user has turned on economy and economy is available

*/ public boolean useEconomy() { - return economyEnabled && economy != null; - } - - /** - * Checks whether a payment transaction should be skipped - * - * @param cost

The cost of the transaction

- * @return

True if the transaction should be skipped

- */ - private boolean skipPayment(int cost) { - return cost == 0 || !useEconomy(); - } - - /** - * Determines the cost of using a gate - * - * @param player

The player trying to use the gate

- * @param source

The source/entry portal

- * @param destination

The destination portal

- * @return

The cost of using the portal

- */ - public int getUseCost(Player player, Portal source, Portal destination) { - //No payment required - if (!useEconomy() || source.getOptions().isFree()) { - return 0; - } - //Not charging for free destinations - if (destination != null && !chargeFreeDestination && destination.getOptions().isFree()) { - return 0; - } - //Cost is 0 if the player owns this gate and funds go to the owner - if (source.getGate().getToOwner() && source.isOwner(player)) { - return 0; - } - //Player gets free gate use - if (PermissionHelper.hasPermission(player, "stargate.free.use")) { - return 0; - } - - return source.getGate().getUseCost(); + return isEconomyEnabled() && economy != null; } /** @@ -337,13 +226,6 @@ public final class EconomyConfig { * @param configOptions

The loaded config options to get values from

*/ private void loadEconomyConfig(Map configOptions) { - economyEnabled = (boolean) configOptions.get(ConfigOption.USE_ECONOMY); - setDefaultCreateCost((Integer) configOptions.get(ConfigOption.CREATE_COST)); - setDefaultDestroyCost((Integer) configOptions.get(ConfigOption.DESTROY_COST)); - setDefaultUseCost((Integer) configOptions.get(ConfigOption.USE_COST)); - toOwner = (boolean) configOptions.get(ConfigOption.TO_OWNER); - chargeFreeDestination = (boolean) configOptions.get(ConfigOption.CHARGE_FREE_DESTINATION); - freeGatesColored = (boolean) configOptions.get(ConfigOption.FREE_GATES_COLORED); try { String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR); @@ -364,41 +246,4 @@ public final class EconomyConfig { return !useEconomy() || PermissionHelper.hasPermission(player, "stargate.free." + permissionNode); } - /** - * Charges a player - * - * @param player

The player to charge

- * @param amount

The amount to charge

- * @return

True if the payment succeeded, or if no payment was necessary

- */ - private boolean chargePlayer(Player player, double amount) { - if (economyEnabled && economy != null) { - if (!economy.has(player, amount)) { - return false; - } - economy.withdrawPlayer(player, amount); - } - return true; - } - - /** - * Charges a player, giving the charge to a target - * - * @param player

The player to charge

- * @param target

The UUID of the player to pay

- * @param amount

The amount to charge

- * @return

True if the payment succeeded, or if no payment was necessary

- */ - private boolean chargePlayer(Player player, UUID target, double amount) { - if (economyEnabled && player.getUniqueId().compareTo(target) != 0 && economy != null) { - if (!economy.has(player, amount)) { - return false; - } - //Take money from the user and give to the owner - economy.withdrawPlayer(player, amount); - economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); - } - return true; - } - } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index b0c0576..b15d70d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -171,7 +171,7 @@ public class BlockEventListener implements Listener { if (cost != 0) { String portalName = portal.getName(); //Cannot pay - if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) { + if (!EconomyHelper.chargePlayerIfNecessary(player, cost)) { Stargate.debug("onBlockBreak", "Insufficient Funds"); EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); event.setCancelled(true); diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 79947b0..1cbd0b3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -110,7 +110,7 @@ public class VehicleEventListener implements Listener { //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be // run after it has been confirmed that all passengers are able to pay - int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal); + int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { if (!takePlayerPayment(passengers, entrancePortal, cost)) { return; @@ -164,7 +164,7 @@ public class VehicleEventListener implements Listener { } //Check if the player is able to afford the teleport fee - int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal); + int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); if (!canAffordFee && !entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 306503f..4ec865c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -266,7 +266,7 @@ public class PortalCreator { if (cost > 0) { //Deduct the required fee from the player - if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) { + if (!EconomyHelper.chargePlayerIfNecessary(player, cost)) { EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); Stargate.debug("createPortal", "Insufficient Funds"); return false; diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index d1dc0e4..e3ab32c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -1,8 +1,11 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.EconomyConfig; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.property.PortalOwner; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.UUID; @@ -34,9 +37,9 @@ public final class EconomyHelper { "was therefore not possible. Make the owner re-create the portal to fix this.", entrancePortal)); } if (entrancePortal.getGate().getToOwner() && ownerUUID != null) { - success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, ownerUUID, cost); + success = chargePlayerIfNecessary(player, ownerUUID, cost); } else { - success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost); + success = chargePlayerIfNecessary(player, cost); } //Send the insufficient funds message @@ -118,6 +121,116 @@ public final class EconomyHelper { Stargate.getMessageSender().sendSuccessMessage(player, refundMsg); } + /** + * Determines the cost of using a gate + * + * @param player

The player trying to use the gate

+ * @param source

The source/entry portal

+ * @param destination

The destination portal

+ * @return

The cost of using the portal

+ */ + public static int getUseCost(Player player, Portal source, Portal destination) { + EconomyConfig config = Stargate.getEconomyConfig(); + //No payment required + if (!config.useEconomy() || source.getOptions().isFree()) { + return 0; + } + //Not charging for free destinations + if (destination != null && config.freeIfFreeDestination() && destination.getOptions().isFree()) { + return 0; + } + //Cost is 0 if the player owns this gate and funds go to the owner + if (source.getGate().getToOwner() && source.isOwner(player)) { + return 0; + } + //Player gets free gate use + if (PermissionHelper.hasPermission(player, "stargate.free.use")) { + return 0; + } + + return source.getGate().getUseCost(); + } + + /** + * Charges the player for an action, if required + * + * @param player

The player to take money from

+ * @param target

The target to pay

+ * @param cost

The cost of the transaction

+ * @return

True if the player was charged successfully

+ */ + public static boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { + if (skipPayment(cost)) { + return true; + } + //Charge player + return chargePlayer(player, target, cost); + } + + /** + * Charges a player + * + * @param player

The player to charge

+ * @param amount

The amount to charge

+ * @return

True if the payment succeeded, or if no payment was necessary

+ */ + private static boolean chargePlayer(Player player, double amount) { + Economy economy = Stargate.getEconomyConfig().getEconomy(); + if (Stargate.getEconomyConfig().isEconomyEnabled() && economy != null) { + if (!economy.has(player, amount)) { + return false; + } + economy.withdrawPlayer(player, amount); + } + return true; + } + + /** + * Charges the player for an action, if required + * + * @param player

The player to take money from

+ * @param cost

The cost of the transaction

+ * @return

True if the player was charged successfully

+ */ + public static boolean chargePlayerIfNecessary(Player player, int cost) { + if (skipPayment(cost)) { + return true; + } + //Charge player + return chargePlayer(player, cost); + } + + /** + * Checks whether a payment transaction should be skipped + * + * @param cost

The cost of the transaction

+ * @return

True if the transaction should be skipped

+ */ + private static boolean skipPayment(int cost) { + return cost == 0 || !Stargate.getEconomyConfig().useEconomy(); + } + + /** + * Charges a player, giving the charge to a target + * + * @param player

The player to charge

+ * @param target

The UUID of the player to pay

+ * @param amount

The amount to charge

+ * @return

True if the payment succeeded, or if no payment was necessary

+ */ + private static boolean chargePlayer(Player player, UUID target, double amount) { + Economy economy = Stargate.getEconomyConfig().getEconomy(); + if (Stargate.getEconomyConfig().isEconomyEnabled() && player.getUniqueId().compareTo(target) != 0 && economy != null) { + if (!economy.has(player, amount)) { + return false; + } + //Take money from the user and give to the owner + economy.withdrawPlayer(player, amount); + economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount); + } + return true; + } + /** * Replaces the cost and portal variables in a string * diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 9454c43..2a8c1ce 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -243,7 +243,7 @@ public final class PermissionHelper { return true; } //Don't charge for free destinations unless specified in the config - return dest != null && !Stargate.getEconomyConfig().chargeFreeDestination() && dest.getOptions().isFree(); + return dest != null && Stargate.getEconomyConfig().freeIfFreeDestination() && dest.getOptions().isFree(); } /** @@ -407,7 +407,7 @@ public final class PermissionHelper { } //Player cannot pay for teleportation - int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destination); + int cost = EconomyHelper.getUseCost(player, entrancePortal, destination); if (cost > 0) { return EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost); } From 2b4d15dab44a91e68c30cf1ab48fc3e9a16f655b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Nov 2021 03:06:35 +0100 Subject: [PATCH 286/378] Adds some boldness to the description and fixes an inaccuracy --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cf7d8f8..50149e0 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,18 @@ Create gates that allow for instant-teleportation between large distances. Gates can be always-open or triggered; they can share a network or be split into clusters; they can be hidden on a network or accessible to everybody. -- Player permissions -- let players build their own networks. -- Vault economy support -- can add costs for create, destroy and use. -- Ability to create custom gate configurations. Three different default gate configurations are available. -- Message customization -- Multiple built-in languages (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) -- Teleport across worlds or servers (BungeeCord supported) -- Vehicle teleportation -- teleport minecarts, boats, horses, pigs and striders -- Leashed teleportation -- teleport any creature in a leash with the player -- Underwater portals -- portals can be placed underwater as long as a waterproof button is used -- API available -- using the API, a lot of behavior can be changed -- Button customization -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) -- Config commands -- All main config values can be changed from the commandline +- **Player permissions** -- let players build their own networks. +- **Vault economy support** -- can add costs for create, destroy and use. +- **Ability to create custom gate configurations**. Four different default gate configurations are available. +- **Message customization** +- **Multiple built-in languages** (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) +- **Teleport across worlds or servers** (BungeeCord supported) +- **Vehicle teleportation** -- teleport minecarts, boats, horses, pigs and striders +- **Leashed teleportation** -- teleport any creature in a leash with the player +- **Underwater portals** -- portals can be placed underwater as long as a waterproof button is used +- **API available** -- using the API, a lot of behavior can be changed +- **Button customization** -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) +- **Config commands** -- All main config values can be changed from the commandline ## Background From 6e7ac5dbb942e1928f03633609f79a54694107d2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Nov 2021 22:20:47 +0100 Subject: [PATCH 287/378] Makes the protectEntrance option protect the entrance from all block placement --- .../stargate/listener/BlockEventListener.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index b15d70d..f443569 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -25,6 +25,7 @@ import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPistonEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.EntityBlockFormEvent; import org.bukkit.event.block.SignChangeEvent; @@ -96,6 +97,22 @@ public class BlockEventListener implements Listener { portal::drawSign, 1); } + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlockPlace(BlockPlaceEvent event) { + if (event.isCancelled() || !Stargate.getGateConfig().protectEntrance()) { + return; + } + Block block = event.getBlock(); + Player player = event.getPlayer(); + + Portal portal = PortalHandler.getByEntrance(block); + if (portal != null) { + //Prevent blocks from being placed in the entrance, if protectEntrance is enabled, as breaking the block + // would destroy the portal + event.setCancelled(true); + } + } + /** * Detects block breaking to detect if the user is destroying a gate * From 32975ca35dfeaee279ecf13b0e54de9e0941cc27 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Nov 2021 22:33:45 +0100 Subject: [PATCH 288/378] Rewrites a lot of the config command to only do the minimum necessary steps to load the changes Adds a ConfigTag class for helping to decide the action necessary for updating a given config option Splits the color setting in PortalSignDrawer as only one color is set at a time when the /config command is used Updates the configOptions map when a config option is changed --- .../stargate/command/CommandConfig.java | 99 +++++++++++++++++-- .../knarcraft/stargate/config/ConfigTag.java | 74 ++++++++++++++ .../stargate/config/EconomyConfig.java | 22 ++--- .../stargate/config/StargateConfig.java | 44 ++++++--- .../stargate/config/StargateGateConfig.java | 10 +- .../stargate/portal/PortalSignDrawer.java | 20 ++-- 6 files changed, 218 insertions(+), 51 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/config/ConfigTag.java diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 54aa1a5..8328352 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -2,6 +2,10 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.ConfigOption; +import net.knarcraft.stargate.config.ConfigTag; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalRegistry; +import net.knarcraft.stargate.portal.PortalSignDrawer; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -55,7 +59,7 @@ public class CommandConfig implements CommandExecutor { FileConfiguration configuration = Stargate.getInstance().getConfig(); //Validate any sign colors - if (selectedOption == ConfigOption.MAIN_SIGN_COLOR || selectedOption == ConfigOption.HIGHLIGHT_SIGN_COLOR) { + if (ConfigTag.COLOR.isTagged(selectedOption)) { try { ChatColor.valueOf(value.toUpperCase()); } catch (IllegalArgumentException | NullPointerException ignored) { @@ -66,12 +70,20 @@ public class CommandConfig implements CommandExecutor { //Store the config values, accounting for the data type switch (selectedOption.getDataType()) { - case BOOLEAN -> configuration.set(selectedOption.getConfigNode(), Boolean.parseBoolean(value)); + case BOOLEAN -> { + boolean newValue = Boolean.parseBoolean(value); + if (selectedOption == ConfigOption.ENABLE_BUNGEE && newValue != Stargate.getGateConfig().enableBungee()) { + Stargate.getStargateConfig().startStopBungeeListener(newValue); + } + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, newValue); + configuration.set(selectedOption.getConfigNode(), newValue); + } case INTEGER -> { Integer intValue = getInteger(commandSender, selectedOption, value); if (intValue == null) { return; } else { + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, intValue); configuration.set(selectedOption.getConfigNode(), intValue); } } @@ -83,14 +95,68 @@ public class CommandConfig implements CommandExecutor { return; } } + if (ConfigTag.COLOR.isTagged(selectedOption)) { + if (!registerColor(selectedOption, value, commandSender)) { + return; + } + } + if (selectedOption == ConfigOption.LANGUAGE) { + Stargate.getStargateConfig().getLanguageLoader().setChosenLanguage(value); + } + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); + configuration.set(selectedOption.getConfigNode(), value); + } + default -> { + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); configuration.set(selectedOption.getConfigNode(), value); } - default -> configuration.set(selectedOption.getConfigNode(), value); } //Save the config file and reload if necessary Stargate.getInstance().saveConfig(); - reloadIfNecessary(commandSender); + + Stargate.getMessageSender().sendSuccessMessage(commandSender, "Config updated"); + + //Reload whatever is necessary + reloadIfNecessary(commandSender, selectedOption); + } + + /** + * Registers the chat color if + * + * @param selectedOption

The option to change

+ * @param commandSender

The command sender to alert if the color is invalid

+ * @param value

The new option value

+ */ + private boolean registerColor(ConfigOption selectedOption, String value, CommandSender commandSender) { + ChatColor parsedColor = parseColor(value); + if (parsedColor == null) { + commandSender.sendMessage(ChatColor.RED + "Invalid color given"); + return false; + } + + if (selectedOption == ConfigOption.FREE_GATES_COLOR) { + PortalSignDrawer.setFreeColor(parsedColor); + } else if (selectedOption == ConfigOption.MAIN_SIGN_COLOR) { + PortalSignDrawer.setMainColor(parsedColor); + } else if (selectedOption == ConfigOption.HIGHLIGHT_SIGN_COLOR) { + PortalSignDrawer.setHighlightColor(parsedColor); + } + return true; + } + + /** + * Parses a chat color + * + * @param value

The value to parse

+ * @return

The parsed color or null

+ */ + private ChatColor parseColor(String value) { + try { + return ChatColor.valueOf(value.toUpperCase()); + } catch (IllegalArgumentException | NullPointerException ignored) { + return null; + } } /** @@ -121,12 +187,27 @@ public class CommandConfig implements CommandExecutor { * Reloads the config if necessary * * @param commandSender

The command sender initiating the reload

+ * @param configOption

The changed config option

*/ - private void reloadIfNecessary(CommandSender commandSender) { - //TODO: Only update the config values which have changed and do the least amount of work necessary to load the - // changes. Only do a full reload if absolutely necessary, or when the partial reloading would be as - // inefficient as a full reload. - Stargate.getStargateConfig().reload(commandSender); + private void reloadIfNecessary(CommandSender commandSender, ConfigOption configOption) { + if (ConfigTag.requiresFullReload(configOption)) { + //Reload everything + Stargate.getStargateConfig().reload(commandSender); + } else if (ConfigTag.requiresPortalReload(configOption)) { + //Just unload and reload the portals + Stargate.getStargateConfig().unloadAllPortals(); + Stargate.getStargateConfig().loadAllPortals(); + } else if (ConfigTag.requiresLanguageReload(configOption)) { + //Reload the language loader + Stargate.getStargateConfig().getLanguageLoader().reload(); + //Re-draw all portal signs + for (Portal portal : PortalRegistry.getAllPortals()) { + portal.drawSign(); + } + } else if (ConfigTag.requiresEconomyReload(configOption)) { + //Load or unload Vault and Economy as necessary + Stargate.getStargateConfig().reloadEconomy(); + } } /** diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java new file mode 100644 index 0000000..4896e20 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java @@ -0,0 +1,74 @@ +package net.knarcraft.stargate.config; + +import java.util.Arrays; + +/** + * A config tag groups config values by a property + */ +public enum ConfigTag { + + COLOR(new ConfigOption[]{ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, ConfigOption.HIGHLIGHT_SIGN_COLOR}), + FOLDER(new ConfigOption[]{ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER}); + + private final ConfigOption[] taggedOptions; + + /** + * Instantiates a new config tag + * + * @param taggedOptions

The config options included in this tag

+ */ + ConfigTag(ConfigOption[] taggedOptions) { + this.taggedOptions = taggedOptions; + } + + /** + * Checks whether a config tag includes the given config option + * + * @param option

The config option to check

+ * @return

True of the config option is tagged

+ */ + public boolean isTagged(ConfigOption option) { + return Arrays.stream(taggedOptions).anyMatch((item) -> item == option); + } + + /** + * Checks whether a given config option requires a full reload to take effect + * + * @param option

The config option to check

+ * @return

True if changing the config option requires a full reload to take effect

+ */ + public static boolean requiresFullReload(ConfigOption option) { + return FOLDER.isTagged(option); + } + + /** + * Checks whether a given config option requires a portal reload to take effect + * + * @param option

The config option to check

+ * @return

True if changing the config option requires a portal reload to take effect

+ */ + public static boolean requiresPortalReload(ConfigOption option) { + return COLOR.isTagged(option) || FOLDER.isTagged(option) || option == ConfigOption.VERIFY_PORTALS; + } + + /** + * Checks whether a given config option requires the language loader to be reloaded + * + * @param option

The config option to check

+ * @return

True if the language loader requires a reload

+ */ + public static boolean requiresLanguageReload(ConfigOption option) { + return option == ConfigOption.LANGUAGE; + } + + /** + * Checks whether a given config option requires economy to be reloaded + * + * @param option

The config option to check

+ * @return

True if economy requires a reload

+ */ + public static boolean requiresEconomyReload(ConfigOption option) { + return option == ConfigOption.USE_ECONOMY; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index ba842d3..d19c379 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -31,7 +31,12 @@ public final class EconomyConfig { */ public EconomyConfig(Map configOptions) { this.configOptions = configOptions; - loadEconomyConfig(configOptions); + try { + String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR); + PortalSignDrawer.setFreeColor(ChatColor.valueOf(freeColor.toUpperCase())); + } catch (IllegalArgumentException | NullPointerException ignored) { + PortalSignDrawer.setFreeColor(ChatColor.DARK_GREEN); + } } /** @@ -220,21 +225,6 @@ public final class EconomyConfig { } } - /** - * Loads all config values related to economy - * - * @param configOptions

The loaded config options to get values from

- */ - private void loadEconomyConfig(Map configOptions) { - - try { - String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR); - PortalSignDrawer.setFreeColor(ChatColor.valueOf(freeColor.toUpperCase())); - } catch (IllegalArgumentException | NullPointerException ignored) { - PortalSignDrawer.setFreeColor(ChatColor.DARK_GREEN); - } - } - /** * Determines if a player can do a gate action for free * diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 88caa6a..19ba95d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -46,8 +46,6 @@ public final class StargateConfig { private String portalFolder; private String languageName = "en"; - private boolean debuggingEnabled = false; - private boolean permissionDebuggingEnabled = false; private final Map configOptions; /** @@ -65,6 +63,18 @@ public final class StargateConfig { languageLoader = new LanguageLoader(dataFolderPath + "/lang/"); } + /** + * Gets a direct reference to the config option map + * + *

This reference can be used to alter the value of config options. Values should only be altered after it's + * been verified that the value is valid.

+ * + * @return

A reference to the config options map

+ */ + public Map getConfigOptionsReference() { + return configOptions; + } + /** * Finish the config setup by loading languages, gates and portals, and loading economy if vault is loaded */ @@ -81,7 +91,7 @@ public final class StargateConfig { languageLoader.reload(); messageSender = new MessageSender(languageLoader); - if (debuggingEnabled) { + if (isDebuggingEnabled()) { languageLoader.debug(); } @@ -130,7 +140,7 @@ public final class StargateConfig { * @return

Whether debugging is enabled

*/ public boolean isDebuggingEnabled() { - return debuggingEnabled; + return (boolean) configOptions.get(ConfigOption.DEBUG); } /** @@ -139,7 +149,7 @@ public final class StargateConfig { * @return

Whether permission debugging is enabled

*/ public boolean isPermissionDebuggingEnabled() { - return permissionDebuggingEnabled; + return (boolean) configOptions.get(ConfigOption.PERMISSION_DEBUG); } /** @@ -186,6 +196,17 @@ public final class StargateConfig { * Un-loads all loaded data */ private void unload() { + //De-activate, close and unload all loaded portals + unloadAllPortals(); + + //Clear all loaded gates + GateHandler.clearGates(); + } + + /** + * Un-loads all loaded portals + */ + public void unloadAllPortals() { //De-activate all currently active portals for (Portal activePortal : activePortalsQueue) { activePortal.getPortalActivator().deactivate(); @@ -201,9 +222,6 @@ public final class StargateConfig { //Clear all loaded portals PortalRegistry.clearPortals(); - - //Clear all loaded gates - GateHandler.clearGates(); } /** @@ -256,7 +274,7 @@ public final class StargateConfig { //Update the language loader in case the loaded language changed languageLoader.setChosenLanguage(languageName); languageLoader.reload(); - if (debuggingEnabled) { + if (isDebuggingEnabled()) { languageLoader.debug(); } @@ -267,7 +285,7 @@ public final class StargateConfig { /** * Starts the listener for listening to BungeeCord messages */ - private void startStopBungeeListener(boolean start) { + public void startStopBungeeListener(boolean start) { Messenger messenger = Bukkit.getMessenger(); String bungeeChannel = "BungeeCord"; @@ -283,7 +301,7 @@ public final class StargateConfig { /** * Reloads economy by enabling or disabling it as necessary */ - private void reloadEconomy() { + public void reloadEconomy() { EconomyConfig economyConfig = getEconomyConfig(); if (economyConfig.isEconomyEnabled() && economyConfig.getEconomy() == null) { setupVaultEconomy(); @@ -342,10 +360,6 @@ public final class StargateConfig { portalFolder = (String) configOptions.get(ConfigOption.PORTAL_FOLDER); gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER); - //Get enabled debug settings from the config - debuggingEnabled = (boolean) configOptions.get(ConfigOption.DEBUG); - permissionDebuggingEnabled = (boolean) configOptions.get(ConfigOption.PERMISSION_DEBUG); - //If users have an outdated config, assume they also need to update their default gates if (isMigrating) { GateHandler.writeDefaultGatesToFolder(gateFolder); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index f1640e0..035ee98 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -190,13 +190,13 @@ public final class StargateGateConfig { private void loadSignColor(String mainSignColor, String highlightSignColor) { if (mainSignColor != null && highlightSignColor != null) { try { - PortalSignDrawer.setColors(ChatColor.valueOf(mainSignColor.toUpperCase()), - ChatColor.valueOf(highlightSignColor.toUpperCase())); - return; + PortalSignDrawer.setMainColor(ChatColor.valueOf(highlightSignColor.toUpperCase())); + PortalSignDrawer.setHighlightColor(ChatColor.valueOf(highlightSignColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException ignored) { + Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); + PortalSignDrawer.setMainColor(ChatColor.BLACK); + PortalSignDrawer.setHighlightColor(ChatColor.WHITE); } } - Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); - PortalSignDrawer.setColors(ChatColor.BLACK, ChatColor.WHITE); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 2921bf8..7b9cb2d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -29,19 +29,27 @@ public class PortalSignDrawer { } /** - * Sets the main and highlighting sign colors + * Sets the highlighting sign color * - *

The main sign color is used for most text on the sign, while the highlighting color is used for the markings - * around portal names and network names ('>','<','-',')','(')

+ *

The highlighting color is used for the markings around portal names and network names ('>','<','-',')','(').

* - * @param newMainColor

The new main sign color

* @param newHighlightColor

The new highlight color

*/ - public static void setColors(ChatColor newMainColor, ChatColor newHighlightColor) { - mainColor = newMainColor; + public static void setHighlightColor(ChatColor newHighlightColor) { highlightColor = newHighlightColor; } + /** + * Sets the main sign color + * + *

The main sign color is used for most text on the sign.

+ * + * @param newMainColor

The new main sign color

+ */ + public static void setMainColor(ChatColor newMainColor) { + mainColor = newMainColor; + } + /** * Sets the color to use for marking free stargates * From 14511f558d81cfef07973f66bb87778e5d06fad5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 24 Nov 2021 22:38:44 +0100 Subject: [PATCH 289/378] Updates readme and version to 0.9.2.1 --- README.md | 6 ++++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cf7d8f8..1b38786 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,12 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.2.1] EpicKnarvik97 fork + +- Makes sure to only reload whatever is necessary when config values are changed using commands, instead of reloading + the entire config file every time +- Protects portals from block placement when protectEntrance is enabled + #### \[Version 0.9.2.0] EpicKnarvik97 fork - Increases max length of names and networks to 13 characters diff --git a/pom.xml b/pom.xml index 6a501c0..8427145 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.2.0 + 0.9.2.1 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0500053..46c5ef7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.2.0 +version: 0.9.2.1 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From bab51d76fd8dc254857eb74d33911afb7c80f460 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 01:53:47 +0100 Subject: [PATCH 290/378] Prevents teleportation of players holding one or more creatures on a leash if handleLeashedCreatures is disabled --- README.md | 5 ++++ .../listener/PlayerEventListener.java | 5 +++- .../listener/VehicleEventListener.java | 11 +++++-- .../portal/teleporter/Teleporter.java | 29 ++++++++++++++++++- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b83466c..316ca8e 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,11 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.2.2] EpicKnarvik97 fork + +- Prevents teleportation of a player holding creatures on a leash when handleLeashedCreatures is disabled to prevent + players accidentally losing the creatures during teleportation + #### \[Version 0.9.2.1] EpicKnarvik97 fork - Makes sure to only reload whatever is necessary when config values are changed using commands, instead of reloading diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 70dc495..3477847 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -7,6 +7,7 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalActivator; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; +import net.knarcraft.stargate.portal.teleporter.Teleporter; import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; @@ -170,7 +171,9 @@ public class PlayerEventListener implements Listener { } return false; } - return true; + + //Make sure to check if the player has any leashed creatures, even though leashed teleportation is disabled + return Teleporter.noLeashedCreaturesPreventTeleportation(player, entrancePortal.getOptions().isSilent()); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 1cbd0b3..1adc928 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.teleporter.Teleporter; import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; @@ -166,10 +167,14 @@ public class VehicleEventListener implements Listener { //Check if the player is able to afford the teleport fee int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); - if (!canAffordFee && !entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); + if (!canAffordFee) { + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); + } + return false; } - return canAffordFee; + + return Teleporter.noLeashedCreaturesPreventTeleportation(player, entrancePortal.getOptions().isSilent()); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 06befad..314a100 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -250,9 +250,35 @@ public abstract class Teleporter { return chunksToLoad; } + /** + * Checks whether a player has leashed creatures that block the teleportation + * + * @param player

The player trying to teleport

+ * @param silent

Whether the entrance portal is silent

+ * @return

False if the player has leashed any creatures that cannot go through the portal

+ */ + public static boolean noLeashedCreaturesPreventTeleportation(Player player, boolean silent) { + //Find any nearby leashed entities to teleport with the player + List nearbyEntities = getLeashedCreatures(player); + + //If this feature is disabled, just return + if (!Stargate.getGateConfig().handleLeashedCreatures()) { + boolean isAllowed = nearbyEntities.isEmpty(); + if (!isAllowed && !silent) { + Stargate.getMessageSender().sendErrorMessage(player, "Leashed teleportation is disabled"); + } + return isAllowed; + } else { + return true; + } + } + /** * Teleports any creatures leashed by the player * + *

Will return false if the teleportation should be aborted because the player has leashed creatures that + * aren't allowed to be teleported with the player.

+ * * @param player

The player which is teleported

* @param origin

The portal the player is teleporting from

*/ @@ -264,6 +290,7 @@ public abstract class Teleporter { //Find any nearby leashed entities to teleport with the player List nearbyEntities = getLeashedCreatures(player); + //Teleport all creatures leashed by the player to the portal the player is to exit from for (Creature creature : nearbyEntities) { creature.setLeashHolder(null); @@ -280,7 +307,7 @@ public abstract class Teleporter { * @param player

The player to check

* @return

A list of all creatures the player is holding in a leash (lead)

*/ - protected List getLeashedCreatures(Player player) { + protected static List getLeashedCreatures(Player player) { List leashedCreatures = new ArrayList<>(); //Find any nearby leashed entities to teleport with the player List nearbyEntities = player.getNearbyEntities(15, 15, 15); From 0740cd0a66cbe54160d8514deb7e6cf4945f06c3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 02:02:20 +0100 Subject: [PATCH 291/378] Removes the error message displayed when teleportation is cancelled because handleLeashedCreatures is disabled The message should be removed as it's inconsistent with how disabled vehicle teleportation is silent --- .../listener/PlayerEventListener.java | 2 +- .../listener/VehicleEventListener.java | 2 +- .../portal/teleporter/Teleporter.java | 19 +++++++------------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 3477847..8ee954e 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -173,7 +173,7 @@ public class PlayerEventListener implements Listener { } //Make sure to check if the player has any leashed creatures, even though leashed teleportation is disabled - return Teleporter.noLeashedCreaturesPreventTeleportation(player, entrancePortal.getOptions().isSilent()); + return Teleporter.noLeashedCreaturesPreventTeleportation(player); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 1adc928..0b263a2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -174,7 +174,7 @@ public class VehicleEventListener implements Listener { return false; } - return Teleporter.noLeashedCreaturesPreventTeleportation(player, entrancePortal.getOptions().isSilent()); + return Teleporter.noLeashedCreaturesPreventTeleportation(player); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 314a100..72e2c26 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -254,23 +254,18 @@ public abstract class Teleporter { * Checks whether a player has leashed creatures that block the teleportation * * @param player

The player trying to teleport

- * @param silent

Whether the entrance portal is silent

* @return

False if the player has leashed any creatures that cannot go through the portal

*/ - public static boolean noLeashedCreaturesPreventTeleportation(Player player, boolean silent) { + public static boolean noLeashedCreaturesPreventTeleportation(Player player) { + //If it's enabled, there is no problem + if (Stargate.getGateConfig().handleLeashedCreatures()) { + return true; + } + //Find any nearby leashed entities to teleport with the player List nearbyEntities = getLeashedCreatures(player); - //If this feature is disabled, just return - if (!Stargate.getGateConfig().handleLeashedCreatures()) { - boolean isAllowed = nearbyEntities.isEmpty(); - if (!isAllowed && !silent) { - Stargate.getMessageSender().sendErrorMessage(player, "Leashed teleportation is disabled"); - } - return isAllowed; - } else { - return true; - } + return nearbyEntities.isEmpty(); } /** From 4b34ea3cf52829c05aa44e42e317d90aa71b9ef0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 03:25:22 +0100 Subject: [PATCH 292/378] Fixes a potential exception when a gate's open-block or closed-block is not a block --- .../portal/property/gate/GateHandler.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index 4aec3b7..0596ed1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -188,14 +188,25 @@ public class GateHandler { * @return

True if the gate is valid. False otherwise

*/ private static boolean validateGate(Gate gate, String fileName) { + String failString = String.format("Could not load Gate %s", fileName) + " - %s"; + if (gate.getLayout().getControls().length != 2) { - Stargate.logSevere(String.format("Could not load Gate %s - Gates must have exactly 2 control points.", - fileName)); + Stargate.logSevere(String.format(failString, "Gates must have exactly 2 control points.")); return false; } if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { - Stargate.logSevere(String.format("Could not load Gate %s - Gate button must be a type of button.", fileName)); + Stargate.logSevere(String.format(failString, "Gate button must be a type of button.")); + return false; + } + + if (!gate.getPortalOpenBlock().isBlock()) { + Stargate.logSevere(String.format(failString, "Gate open block must be a type of block.")); + return false; + } + + if (!gate.getPortalClosedBlock().isBlock()) { + Stargate.logSevere(String.format(failString, "Gate closed block must be a type of block.")); return false; } return true; From 27b964837f57157d6490485df8cd41c96efca8d3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 03:25:58 +0100 Subject: [PATCH 293/378] Fixes a potential exception when a portal with an invalid gate type is missing a sign --- .../java/net/knarcraft/stargate/portal/PortalSignDrawer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 7b9cb2d..a09d94e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -293,7 +293,10 @@ public class PortalSignDrawer { * @param lineIndex

The index of the line the invalid portal was found at

*/ public static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) { - Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState(); + BlockState blockState = portalLocation.getSignLocation().getBlock().getState(); + if (!(blockState instanceof Sign sign)) { + return; + } sign.setLine(3, errorColor + Stargate.getString("signInvalidGate")); sign.update(); From 2ed0fe7817f3186557bf8f86c09f6b5ac67d9856 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 03:26:12 +0100 Subject: [PATCH 294/378] Updates README with recent changes --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 316ca8e..094abcb 100644 --- a/README.md +++ b/README.md @@ -393,6 +393,8 @@ portalInfoServer=Server: %server% - Prevents teleportation of a player holding creatures on a leash when handleLeashedCreatures is disabled to prevent players accidentally losing the creatures during teleportation +- Fixes a potential exception when a gate's open-block or closed-block is set to a material which isn't a block +- Fixes a potential exception when a portal without a sign has an invalid gate type #### \[Version 0.9.2.1] EpicKnarvik97 fork From f92fd2de5dfa9f7f840f050440a6db0572cbc4f6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 03:39:15 +0100 Subject: [PATCH 295/378] Prevents loading of gate files using non-blocks as part of the border --- README.md | 1 + .../stargate/portal/property/gate/Gate.java | 9 +++++++++ .../stargate/portal/property/gate/GateHandler.java | 14 +++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 094abcb..fe1feda 100644 --- a/README.md +++ b/README.md @@ -395,6 +395,7 @@ portalInfoServer=Server: %server% players accidentally losing the creatures during teleportation - Fixes a potential exception when a gate's open-block or closed-block is set to a material which isn't a block - Fixes a potential exception when a portal without a sign has an invalid gate type +- Prevents loading of gate files using non-blocks as part of the border #### \[Version 0.9.2.1] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index 18cbf12..684b6d2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -69,6 +69,15 @@ public class Gate { return layout; } + /** + * Gets a copy of the character to material mapping for this gate + * + * @return

The character to material map

+ */ + public Map getCharacterMaterialMap() { + return new HashMap<>(characterMaterialMap); + } + /** * Gets the material type used for this gate's control blocks * diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index 0596ed1..9558175 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -189,7 +189,7 @@ public class GateHandler { */ private static boolean validateGate(Gate gate, String fileName) { String failString = String.format("Could not load Gate %s", fileName) + " - %s"; - + if (gate.getLayout().getControls().length != 2) { Stargate.logSevere(String.format(failString, "Gates must have exactly 2 control points.")); return false; @@ -199,16 +199,24 @@ public class GateHandler { Stargate.logSevere(String.format(failString, "Gate button must be a type of button.")); return false; } - + if (!gate.getPortalOpenBlock().isBlock()) { Stargate.logSevere(String.format(failString, "Gate open block must be a type of block.")); return false; } - + if (!gate.getPortalClosedBlock().isBlock()) { Stargate.logSevere(String.format(failString, "Gate closed block must be a type of block.")); return false; } + + for (Material material : gate.getCharacterMaterialMap().values()) { + if (!material.isBlock()) { + Stargate.logSevere(String.format(failString, "Every gate border block must be a type of block.")); + return false; + } + } + return true; } From b2bb995d7e72de140e9588fc526dc0e00db5fdae Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 03:54:09 +0100 Subject: [PATCH 296/378] Prevents teleportation of a leashed creature with a passenger --- README.md | 4 +++- .../stargate/portal/teleporter/Teleporter.java | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fe1feda..53d7084 100644 --- a/README.md +++ b/README.md @@ -391,11 +391,13 @@ portalInfoServer=Server: %server% #### \[Version 0.9.2.2] EpicKnarvik97 fork -- Prevents teleportation of a player holding creatures on a leash when handleLeashedCreatures is disabled to prevent +- Prevents teleportation of a player holding creatures on a leash when handleLeashedCreatures is disabled, to prevent players accidentally losing the creatures during teleportation - Fixes a potential exception when a gate's open-block or closed-block is set to a material which isn't a block - Fixes a potential exception when a portal without a sign has an invalid gate type - Prevents loading of gate files using non-blocks as part of the border +- Prevents a player smuggling another player through a restricted stargate by sitting on a creature held in a lead by + the first player #### \[Version 0.9.2.1] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 72e2c26..5ffd9f4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -257,15 +257,22 @@ public abstract class Teleporter { * @return

False if the player has leashed any creatures that cannot go through the portal

*/ public static boolean noLeashedCreaturesPreventTeleportation(Player player) { + //Find any nearby leashed entities to teleport with the player + List nearbyCreatures = getLeashedCreatures(player); + + //Disallow creatures with passengers to prevent smuggling + for (Creature creature : nearbyCreatures) { + if (!creature.getPassengers().isEmpty()) { + return false; + } + } + //If it's enabled, there is no problem if (Stargate.getGateConfig().handleLeashedCreatures()) { return true; + } else { + return nearbyCreatures.isEmpty(); } - - //Find any nearby leashed entities to teleport with the player - List nearbyEntities = getLeashedCreatures(player); - - return nearbyEntities.isEmpty(); } /** From 7f9dc6756b0fad813ded4bc180fda2a418ffe4b6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 03:58:42 +0100 Subject: [PATCH 297/378] Updates version to 0.9.2.2 --- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8427145..3252b32 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.2.1 + 0.9.2.2 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 46c5ef7..63a2a2a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.2.1 +version: 0.9.2.2 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 445638a561e7b299d0e2177916109a2ce117e3a2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 04:27:36 +0100 Subject: [PATCH 298/378] Releases a small hotfix for sign color as version 0.9.2.3 --- README.md | 4 ++++ pom.xml | 2 +- .../stargate/config/StargateGateConfig.java | 16 +++++++--------- src/main/resources/plugin.yml | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 53d7084..13caca6 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.2.3] EpicKnarvik97 fork + +- Fixes a typo which caused both colors to change into the highlightSignColor + #### \[Version 0.9.2.2] EpicKnarvik97 fork - Prevents teleportation of a player holding creatures on a leash when handleLeashedCreatures is disabled, to prevent diff --git a/pom.xml b/pom.xml index 3252b32..ef1ea7f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.2.2 + 0.9.2.3 diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 035ee98..4e5b5a3 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -188,15 +188,13 @@ public final class StargateGateConfig { * @param mainSignColor

A string representing the main sign color

*/ private void loadSignColor(String mainSignColor, String highlightSignColor) { - if (mainSignColor != null && highlightSignColor != null) { - try { - PortalSignDrawer.setMainColor(ChatColor.valueOf(highlightSignColor.toUpperCase())); - PortalSignDrawer.setHighlightColor(ChatColor.valueOf(highlightSignColor.toUpperCase())); - } catch (IllegalArgumentException | NullPointerException ignored) { - Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); - PortalSignDrawer.setMainColor(ChatColor.BLACK); - PortalSignDrawer.setHighlightColor(ChatColor.WHITE); - } + try { + PortalSignDrawer.setMainColor(ChatColor.valueOf(mainSignColor.toUpperCase())); + PortalSignDrawer.setHighlightColor(ChatColor.valueOf(highlightSignColor.toUpperCase())); + } catch (IllegalArgumentException | NullPointerException exception) { + Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); + PortalSignDrawer.setMainColor(ChatColor.BLACK); + PortalSignDrawer.setHighlightColor(ChatColor.WHITE); } } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 63a2a2a..3f90395 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.2.2 +version: 0.9.2.3 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From a61a03be33a32b89811e9bb9f37581daac6639f1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 14:54:50 +0100 Subject: [PATCH 299/378] Adds an update checker for alerting about new updates --- .../java/net/knarcraft/stargate/Stargate.java | 26 ++++++ .../stargate/utility/UpdateChecker.java | 87 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index e3055d6..4da5074 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -21,6 +21,7 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; +import net.knarcraft.stargate.utility.UpdateChecker; import org.bukkit.Server; import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; @@ -55,6 +56,8 @@ public class Stargate extends JavaPlugin { private static PluginManager pluginManager; private static StargateConfig stargateConfig; + private static String updateAvailable = null; + /** * Empty constructor necessary for Spigot */ @@ -74,6 +77,26 @@ public class Stargate extends JavaPlugin { super(loader, descriptionFile, dataFolder, file); } + /** + * Stores information about an available update + * + *

If a non-null version is given, joining admins will be alerted about the new update.

+ * + * @param version

The version of the new update available

+ */ + public static void setUpdateAvailable(String version) { + updateAvailable = version; + } + + /** + * Gets information about an available update + * + * @return

The version number if an update is available. Null otherwise

+ */ + public static String getUpdateAvailable() { + return updateAvailable; + } + /** * Gets an instance of this plugin * @@ -334,6 +357,9 @@ public class Stargate extends JavaPlugin { runThreads(); this.registerCommands(); + + //Check for any available updates + UpdateChecker.checkForUpdate(); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java b/src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java new file mode 100644 index 0000000..2df40f4 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java @@ -0,0 +1,87 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import org.bukkit.scheduler.BukkitScheduler; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.logging.Level; + +/** + * The update checker is responsible for looking for new updates + */ +public final class UpdateChecker { + + private final static String APIResourceURL = "https://api.spigotmc.org/legacy/update.php?resource=97784"; + private final static String updateNotice = "A new update is available: %s (You are still on %s)"; + + private UpdateChecker() { + + } + + /** + * Checks if there's a new update available, and alerts the user if necessary + */ + public static void checkForUpdate() { + BukkitScheduler scheduler = Stargate.getInstance().getServer().getScheduler(); + scheduler.runTaskAsynchronously(Stargate.getInstance(), UpdateChecker::queryAPI); + } + + /** + * Queries the spigot API to check for a newer version, and informs the user + */ + private static void queryAPI() { + try { + InputStream inputStream = new URL(APIResourceURL).openStream(); + BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream); + //There should only be one line of output + String newVersion = reader.readLine(); + reader.close(); + + String oldVersion = Stargate.getPluginVersion(); + //If there is a newer version, notify the user + if (isVersionHigher(oldVersion, newVersion)) { + Stargate.getConsoleLogger().log(Level.INFO, Stargate.getBackupString("prefix") + + getUpdateAvailableString(newVersion, oldVersion)); + Stargate.setUpdateAvailable(newVersion); + } + } catch (IOException e) { + Stargate.debug("UpdateChecker", "Unable to get newest version."); + } + } + + /** + * Gets the string to display to a user to alert about a new update + * + * @param newVersion

The new available plugin version

+ * @param oldVersion

The old (current) plugin version

+ * @return

The string to display

+ */ + public static String getUpdateAvailableString(String newVersion, String oldVersion) { + return String.format(updateNotice, newVersion, oldVersion); + } + + /** + * Decides whether one version number is higher than another + * + * @param oldVersion

The old version to check

+ * @param newVersion

The new version to check

+ * @return

True if the new version is higher than the old one

+ */ + public static boolean isVersionHigher(String oldVersion, String newVersion) { + String[] oldVersionParts = oldVersion.split("\\."); + String[] newVersionParts = newVersion.split("\\."); + int versionLength = Math.max(oldVersionParts.length, newVersionParts.length); + for (int i = 0; i < versionLength; i++) { + int oldVersionNumber = oldVersionParts.length > i ? Integer.parseInt(oldVersionParts[i]) : 0; + int newVersionNumber = newVersionParts.length > i ? Integer.parseInt(newVersionParts[i]) : 0; + if (newVersionNumber != oldVersionNumber) { + return newVersionNumber > oldVersionNumber; + } + } + return false; + } + +} From cfb4910977ee6f091af03e8a1ee136d65dc3656c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 14:56:05 +0100 Subject: [PATCH 300/378] Adds a toggle-able admin alert when any admin joins the server --- .../net/knarcraft/stargate/config/ConfigOption.java | 7 ++++++- .../knarcraft/stargate/config/StargateConfig.java | 9 +++++++++ .../stargate/listener/PlayerEventListener.java | 13 +++++++++++-- src/main/resources/config.yml | 2 ++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 9bd6bf9..4709a05 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -147,7 +147,12 @@ public enum ConfigOption { /** * Whether to enable debug output for debugging permissions */ - PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", false); + PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", false), + + /** + * Whether to alert admins about new updates + */ + ADMIN_UPDATE_ALERT("adminUpdateAlert", "Whether to alert admins about new plugin updates", true); private final String configNode; diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 19ba95d..f5526d5 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -319,6 +319,15 @@ public final class StargateConfig { } } + /** + * Gets whether admins should be alerted about new plugin updates + * + * @return

Whether admins should be alerted about new updates

+ */ + public boolean alertAdminsAboutUpdates() { + return (boolean) configOptions.get(ConfigOption.ADMIN_UPDATE_ALERT); + } + /** * Loads all config values */ diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 8ee954e..fdcef17 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -13,6 +13,7 @@ import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.UUIDMigrationHelper; +import net.knarcraft.stargate.utility.UpdateChecker; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.block.Block; @@ -48,14 +49,22 @@ public class PlayerEventListener implements Listener { */ @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); //Migrate player name to UUID if necessary - UUIDMigrationHelper.migrateUUID(event.getPlayer()); + UUIDMigrationHelper.migrateUUID(player); + + //Notify joining admins about the available update + String availableUpdate = Stargate.getUpdateAvailable(); + if (availableUpdate != null && Stargate.getStargateConfig().alertAdminsAboutUpdates() && + player.hasPermission("stargate.admin")) { + String updateMessage = UpdateChecker.getUpdateAvailableString(availableUpdate, Stargate.getPluginVersion()); + Stargate.getMessageSender().sendErrorMessage(player, updateMessage); + } if (!Stargate.getGateConfig().enableBungee()) { return; } - Player player = event.getPlayer(); //Check if the player is waiting to be teleported to a stargate String destination = BungeeHelper.removeFromQueue(player.getUniqueId()); if (destination == null) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4852940..474be7f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -18,6 +18,7 @@ # mainSignColor - The color used for drawing signs (Default: BLACK). # highlightSignColor - The color used for sign markings (Default: WHITE) # verifyPortals - Whether all the non-sign blocks are checked to match the gate layout when a stargate is loaded. +# adminUpdateAlert - Whether to alert admins about new plugin updates # I------------I-------------I # # stargate economy options # # I------------I-------------I # @@ -36,6 +37,7 @@ # permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) language: en +adminUpdateAlert: true folders: portalFolder: plugins/Stargate/portals/ gateFolder: plugins/Stargate/gates/ From f8ae83bc082498a05f047891c42c2d9dec67b954 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 25 Nov 2021 14:56:44 +0100 Subject: [PATCH 301/378] Updates README and version to 0.9.2.4 --- README.md | 7 +++++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13caca6..8507b58 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,7 @@ while the per-gate costs re defined in the .gate files. To define a certain cost ``` language - The language to use (Included languages: en, de, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) +adminUpdateAlert - Whether to alert admins about an available update when joining the server folders: portalFolder - The folder your portal databases are saved in gateFolder - The folder containing your .gate files @@ -389,6 +390,12 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.2.4] EpicKnarvik97 fork + +- Adds update checking, which will display a notice in the console when updates are available +- Adds an alert about an available update when an admin joins the server +- Adds the adminUpdateAlert config option to allow the admin notices to be turned off + #### \[Version 0.9.2.3] EpicKnarvik97 fork - Fixes a typo which caused both colors to change into the highlightSignColor diff --git a/pom.xml b/pom.xml index ef1ea7f..3d0648c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.2.3 + 0.9.2.4 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3f90395..d249261 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.2.3 +version: 0.9.2.4 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From fc5bac937a2b380c7ad29ae1bc6762fc683b5b7d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 26 Nov 2021 16:55:22 +0100 Subject: [PATCH 302/378] Changes the max age of gateway blocks to prevent the occasional purple beam --- .../knarcraft/stargate/thread/BlockChangeThread.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index ebc2026..d177a0b 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -39,8 +39,7 @@ public class BlockChangeThread implements Runnable { Block block = blockChangeRequest.getBlockLocation().getBlock(); block.setType(blockChangeRequest.getMaterial(), false); - if (blockChangeRequest.getMaterial() == Material.END_GATEWAY && - block.getWorld().getEnvironment() == World.Environment.THE_END) { + if (blockChangeRequest.getMaterial() == Material.END_GATEWAY) { //Force a specific location to prevent exit gateway generation fixEndGatewayGate(block); } else if (blockChangeRequest.getAxis() != null) { @@ -56,8 +55,11 @@ public class BlockChangeThread implements Runnable { */ private static void fixEndGatewayGate(Block block) { EndGateway gateway = (EndGateway) block.getState(); - gateway.setExitLocation(block.getLocation()); - gateway.setExactTeleport(true); + gateway.setAge(Long.MIN_VALUE); + if (block.getWorld().getEnvironment() == World.Environment.THE_END) { + gateway.setExitLocation(block.getLocation()); + gateway.setExactTeleport(true); + } gateway.update(false, false); } From 9177773a0eed3e843b2cbf016eb1162425514914 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 2 Dec 2021 04:05:27 +0100 Subject: [PATCH 303/378] Updates Spigot and Java version --- pom.xml | 10 +++++----- src/main/resources/plugin.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 3d0648c..74b141d 100644 --- a/pom.xml +++ b/pom.xml @@ -15,8 +15,8 @@ UTF-8 - 16 - 16 + 17 + 17 @@ -34,7 +34,7 @@ org.spigotmc spigot-api - 1.17.1-R0.1-SNAPSHOT + 1.18-R0.1-SNAPSHOT net.milkbowl.vault @@ -75,8 +75,8 @@ maven-compiler-plugin 3.6.1 - 16 - 16 + 17 + 17 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d249261..c56f16c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,7 +5,7 @@ description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] website: https://git.knarcraft.net/EpicKnarvik97/Stargate -api-version: 1.17 +api-version: 1.18 softdepend: [ Vault ] commands: stargate: From a7dc02eef07c50eb92c381b04dd594dd489cdccd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 2 Dec 2021 04:19:44 +0100 Subject: [PATCH 304/378] Updates plugin version and README --- README.md | 5 +++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8507b58..82968f9 100644 --- a/README.md +++ b/README.md @@ -390,6 +390,11 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.2.5] EpicKnarvik97 fork + +- Updates Java version to JDK 17 +- Updates Spigot API version to 1.18 + #### \[Version 0.9.2.4] EpicKnarvik97 fork - Adds update checking, which will display a notice in the console when updates are available diff --git a/pom.xml b/pom.xml index 74b141d..3c1d735 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.2.4 + 0.9.2.5 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c56f16c..92399fb 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.2.4 +version: 0.9.2.5 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 5d1d6ffaf0df9a14045eea125be23d506c464347 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 3 Dec 2021 23:23:19 +0100 Subject: [PATCH 305/378] Removes some unnecessary calculation when converting relative vectors to real vectors --- .../stargate/utility/DirectionHelper.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 3229c6d..c42fe6d 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -113,16 +113,21 @@ public final class DirectionHelper { * @return

A normal vector

*/ public static Vector getCoordinateVectorFromRelativeVector(double right, double down, double out, double yaw) { - Vector distanceVector = DirectionHelper.getDirectionVectorFromYaw(yaw); - distanceVector.multiply(out); - - Vector rightVector = DirectionHelper.getDirectionVectorFromYaw(yaw - 90); - rightVector.multiply(right); - - Vector depthVector = new Vector(0, -1, 0); - depthVector.multiply(down); - - return distanceVector.add(rightVector).add(depthVector); + if (yaw == 0) { + //South + return new Vector(right, -down, out); + } else if (yaw == 90) { + //West + return new Vector(-out, -down, right); + } else if (yaw == 180) { + //North + return new Vector(-right, -down, -out); + } else if (yaw == 270) { + //East + return new Vector(out, -down, -right); + } else { + throw new IllegalArgumentException(String.format("Invalid yaw %f given", yaw)); + } } /** From 948f92f140c8198af776d33b9ea462d192b5f21e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 15 Jan 2022 21:59:46 +0100 Subject: [PATCH 306/378] Updates Spigot and MockBukkit versions --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3c1d735..7f2e650 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ org.spigotmc spigot-api - 1.18-R0.1-SNAPSHOT + 1.18.1-R0.1-SNAPSHOT net.milkbowl.vault @@ -49,8 +49,8 @@ com.github.seeseemelk - MockBukkit-v1.17 - 1.7.0 + MockBukkit-v1.18 + 1.14.0 test From acbdcd3ce36366729faf2b7863338ae7c53baa50 Mon Sep 17 00:00:00 2001 From: Kristian Knarvik Date: Tue, 25 Jan 2022 15:34:27 +0100 Subject: [PATCH 307/378] Fixes a hang caused by MockBukkit --- src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 5f85dbe..c8bf07c 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -32,6 +32,7 @@ public class GateLayoutTest { @AfterAll public static void tearDown() { + MockBukkit.getMock().getPluginManager().disablePlugins(); MockBukkit.unmock(); } From 2bb0e8670d607258673e4507eba07b17f0df79ba Mon Sep 17 00:00:00 2001 From: Kristian Knarvik Date: Tue, 25 Jan 2022 16:46:29 +0100 Subject: [PATCH 308/378] Makes a lot of changes necessary for RGB and per-sign color configuration support --- .../stargate/command/CommandAbout.java | 2 +- .../stargate/command/CommandConfig.java | 6 +- .../stargate/command/CommandStarGate.java | 2 +- .../stargate/command/ConfigTabCompleter.java | 4 +- .../stargate/config/ConfigOption.java | 8 +- .../stargate/config/EconomyConfig.java | 4 +- .../stargate/config/MessageSender.java | 2 +- .../stargate/config/OptionDataType.java | 1 + .../stargate/config/StargateGateConfig.java | 27 ++++- .../listener/PlayerEventListener.java | 2 +- .../net/knarcraft/stargate/portal/Portal.java | 2 +- .../stargate/portal/PortalSignDrawer.java | 110 +++++++++++++++--- .../stargate/utility/BungeeHelper.java | 2 +- .../stargate/utility/FileHelper.java | 2 +- src/main/resources/config.yml | 9 ++ 15 files changed, 147 insertions(+), 36 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 1a43ef5..3e5b441 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 8328352..2bac15c 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -6,7 +6,7 @@ import net.knarcraft.stargate.config.ConfigTag; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.PortalSignDrawer; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -61,7 +61,7 @@ public class CommandConfig implements CommandExecutor { //Validate any sign colors if (ConfigTag.COLOR.isTagged(selectedOption)) { try { - ChatColor.valueOf(value.toUpperCase()); + ChatColor.of(value.toUpperCase()); } catch (IllegalArgumentException | NullPointerException ignored) { commandSender.sendMessage(ChatColor.RED + "Invalid color given"); return; @@ -153,7 +153,7 @@ public class CommandConfig implements CommandExecutor { */ private ChatColor parseColor(String value) { try { - return ChatColor.valueOf(value.toUpperCase()); + return ChatColor.of(value.toUpperCase()); } catch (IllegalArgumentException | NullPointerException ignored) { return null; } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index 796b0c2..bd82080 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; +import net.md_5.bungee.api.ChatColor; import org.apache.commons.lang.ArrayUtils; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index 8484322..f0f01c6 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -2,7 +2,7 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.config.ConfigOption; import net.knarcraft.stargate.config.OptionDataType; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; @@ -137,7 +137,7 @@ public class ConfigTabCompleter implements TabCompleter { private List getColors() { List colors = new ArrayList<>(); for (ChatColor color : getChatColors()) { - colors.add(color.name()); + colors.add(color.getName()); } return colors; } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 4709a05..5944889 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -50,6 +50,10 @@ public enum ConfigOption { */ HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"), + PER_SIGN_COLORS("gates.cosmetic.perSignColors", "The per-sign color specification", new String[]{ + "ACACIA:default,default", "BIRCH:default,default", "CRIMSON:default,default", "DARK_OAK:default,default", + "JUNGLE:default,default", "OAK:default,default", "SPRUCE:default,default", "WARPED:default,default"}), + /** * Whether to destroy portals when any blocks are broken by explosions */ @@ -172,7 +176,9 @@ public enum ConfigOption { this.description = description; this.defaultValue = defaultValue; - if (defaultValue instanceof String) { + if (defaultValue instanceof String[]) { + this.dataType = OptionDataType.STRING_LIST; + } else if (defaultValue instanceof String) { this.dataType = OptionDataType.STRING; } else if (defaultValue instanceof Boolean) { this.dataType = OptionDataType.BOOLEAN; diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index d19c379..1b8400c 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -4,8 +4,8 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.PortalSignDrawer; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.utility.PermissionHelper; +import net.md_5.bungee.api.ChatColor; import net.milkbowl.vault.economy.Economy; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -33,7 +33,7 @@ public final class EconomyConfig { this.configOptions = configOptions; try { String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR); - PortalSignDrawer.setFreeColor(ChatColor.valueOf(freeColor.toUpperCase())); + PortalSignDrawer.setFreeColor(ChatColor.of(freeColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException ignored) { PortalSignDrawer.setFreeColor(ChatColor.DARK_GREEN); } diff --git a/src/main/java/net/knarcraft/stargate/config/MessageSender.java b/src/main/java/net/knarcraft/stargate/config/MessageSender.java index 1507dd7..bfc706a 100644 --- a/src/main/java/net/knarcraft/stargate/config/MessageSender.java +++ b/src/main/java/net/knarcraft/stargate/config/MessageSender.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.config; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.command.CommandSender; /** diff --git a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java index e657a69..5cb8bee 100644 --- a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java +++ b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java @@ -13,6 +13,7 @@ public enum OptionDataType { * The data type for the option is a Boolean */ BOOLEAN, + STRING_LIST, /** * The data type for the option is an Integer */ diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 4e5b5a3..e9cede7 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -2,8 +2,10 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.PortalSignDrawer; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Material; +import java.util.HashMap; import java.util.Map; /** @@ -180,6 +182,25 @@ public final class StargateGateConfig { //Load the sign colors loadSignColor((String) configOptions.get(ConfigOption.MAIN_SIGN_COLOR), (String) configOptions.get(ConfigOption.HIGHLIGHT_SIGN_COLOR)); + String[] perSignColors = (String[]) configOptions.get(ConfigOption.PER_SIGN_COLORS); + + Map signMainColors = new HashMap<>(); + Map signHighlightColors = new HashMap<>(); + for (String signColorSpecification : perSignColors) { + String[] specificationData = signColorSpecification.split(":"); + String[] colors = specificationData[1].split(","); + if (!colors[0].equalsIgnoreCase("default")) { + signMainColors.put(Material.matchMaterial(specificationData[0] + "_SIGN"), ChatColor.of(colors[0])); + signMainColors.put(Material.matchMaterial(specificationData[0] + "_WALL_SIGN"), ChatColor.of(colors[0])); + } + if (!colors[1].equalsIgnoreCase("default")) { + signHighlightColors.put(Material.matchMaterial(specificationData[0] + "_SIGN"), ChatColor.of(colors[1])); + signHighlightColors.put(Material.matchMaterial(specificationData[0] + "_WALL_SIGN"), ChatColor.of(colors[1])); + } + } + + PortalSignDrawer.setPerSignMainColors(signMainColors); + PortalSignDrawer.setPerSignHighlightColors(signHighlightColors); } /** @@ -189,8 +210,8 @@ public final class StargateGateConfig { */ private void loadSignColor(String mainSignColor, String highlightSignColor) { try { - PortalSignDrawer.setMainColor(ChatColor.valueOf(mainSignColor.toUpperCase())); - PortalSignDrawer.setHighlightColor(ChatColor.valueOf(highlightSignColor.toUpperCase())); + PortalSignDrawer.setMainColor(ChatColor.of(mainSignColor.toUpperCase())); + PortalSignDrawer.setHighlightColor(ChatColor.of(highlightSignColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException exception) { Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); PortalSignDrawer.setMainColor(ChatColor.BLACK); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index fdcef17..a73b314 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -14,7 +14,7 @@ import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.UUIDMigrationHelper; import net.knarcraft.stargate.utility.UpdateChecker; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 6a66e80..93e664f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -8,7 +8,7 @@ import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.portal.property.gate.Gate; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index a09d94e..563933c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -3,11 +3,16 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.utility.PermissionHelper; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * The portal sign drawer draws the sing of a given portal */ @@ -18,6 +23,8 @@ public class PortalSignDrawer { private static ChatColor freeColor; private static ChatColor mainColor; private static ChatColor highlightColor; + private static Map perSignMainColors; + private static Map perSignHighlightColors; /** * Instantiates a new portal sign drawer @@ -59,6 +66,24 @@ public class PortalSignDrawer { PortalSignDrawer.freeColor = freeColor; } + /** + * Sets the per-sign main colors + * + * @param signMainColors

The per-sign main colors

+ */ + public static void setPerSignMainColors(Map signMainColors) { + PortalSignDrawer.perSignMainColors = signMainColors; + } + + /** + * Sets the per-sign highlight colors + * + * @param signHighlightColors

The per-sign highlight colors

+ */ + public static void setPerSignHighlightColors(Map signHighlightColors) { + PortalSignDrawer.perSignHighlightColors = signHighlightColors; + } + /** * Draws the sign of the portal this sign drawer is responsible for */ @@ -96,9 +121,11 @@ public class PortalSignDrawer { * @param sign

The sign re-draw

*/ private void drawSign(Sign sign) { + ChatColor highlightColor = getHighlightColor(sign.getType()); + ChatColor mainColor = getMainColor(sign.getType()); //Clear sign clearSign(sign); - setLine(sign, 0, highlightColor + "-" + mainColor + fixColor(portal.getName()) + highlightColor + "-"); + setLine(sign, 0, highlightColor + "-" + mainColor + translateAllColorCodes(portal.getName()) + highlightColor + "-"); if (!portal.getPortalActivator().isActive()) { //Default sign text @@ -139,7 +166,7 @@ public class PortalSignDrawer { return; } clearSign(sign); - sign.setLine(0, fixColor(portal.getName())); + sign.setLine(0, translateAllColorCodes(portal.getName())); sign.update(); } @@ -184,15 +211,17 @@ public class PortalSignDrawer { * @param signLineIndex

The line to draw on

*/ private void drawNetworkSignChosenLine(boolean freeGatesColored, Sign sign, int signLineIndex) { + ChatColor highlightColor = getHighlightColor(sign.getType()); + ChatColor mainColor = getMainColor(sign.getType()); if (freeGatesColored) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); ChatColor nameColor = (free ? freeColor : highlightColor); setLine(sign, signLineIndex, nameColor + ">" + (free ? freeColor : mainColor) + - fixColor(portal.getDestinationName()) + nameColor + "<"); + translateAllColorCodes(portal.getDestinationName()) + nameColor + "<"); } else { setLine(sign, signLineIndex, highlightColor + ">" + mainColor + - fixColor(portal.getDestinationName()) + highlightColor + "<"); + translateAllColorCodes(portal.getDestinationName()) + highlightColor + "<"); } } @@ -204,6 +233,7 @@ public class PortalSignDrawer { * @param text

The new text on the sign

*/ public void setLine(Sign sign, int index, String text) { + ChatColor mainColor = getMainColor(sign.getType()); sign.setLine(index, mainColor + text); } @@ -216,14 +246,15 @@ public class PortalSignDrawer { * @param destinationIndex

The index of the destination to draw

*/ private void drawNetworkSignLine(boolean freeGatesColored, Sign sign, int signLineIndex, int destinationIndex) { + ChatColor mainColor = getMainColor(sign.getType()); PortalActivator destinations = portal.getPortalActivator(); String destinationName = destinations.getDestinations().get(destinationIndex); if (freeGatesColored) { Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork()); boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (free ? freeColor : mainColor) + fixColor(destinationName)); + setLine(sign, signLineIndex, (free ? freeColor : mainColor) + translateAllColorCodes(destinationName)); } else { - setLine(sign, signLineIndex, mainColor + fixColor(destinationName)); + setLine(sign, signLineIndex, mainColor + translateAllColorCodes(destinationName)); } } @@ -233,10 +264,12 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawBungeeSign(Sign sign) { + ChatColor highlightColor = getHighlightColor(sign.getType()); + ChatColor mainColor = getMainColor(sign.getType()); setLine(sign, 1, Stargate.getString("bungeeSign")); - setLine(sign, 2, highlightColor + ">" + mainColor + fixColor(portal.getDestinationName()) + + setLine(sign, 2, highlightColor + ">" + mainColor + translateAllColorCodes(portal.getDestinationName()) + highlightColor + "<"); - setLine(sign, 3, highlightColor + "[" + mainColor + fixColor(portal.getNetwork()) + + setLine(sign, 3, highlightColor + "[" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + "]"); } @@ -248,10 +281,12 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawInactiveSign(Sign sign) { + ChatColor highlightColor = getHighlightColor(sign.getType()); + ChatColor mainColor = getMainColor(sign.getType()); setLine(sign, 1, Stargate.getString("signRightClick")); setLine(sign, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { - setLine(sign, 3, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + + setLine(sign, 3, highlightColor + "(" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + ")"); } else { setLine(sign, 3, ""); @@ -264,17 +299,20 @@ public class PortalSignDrawer { * @param sign

The sign to re-draw

*/ private void drawFixedSign(Sign sign) { + ChatColor highlightColor = getHighlightColor(sign.getType()); + ChatColor mainColor = getMainColor(sign.getType()); Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getCleanNetwork()); String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : (destinationPortal != null ? destinationPortal.getName() : portal.getDestinationName()); - setLine(sign, 1, highlightColor + ">" + mainColor + fixColor(destinationName) + highlightColor + "<"); + setLine(sign, 1, highlightColor + ">" + mainColor + translateAllColorCodes(destinationName) + + highlightColor + "<"); if (portal.getOptions().isNoNetwork()) { setLine(sign, 2, ""); } else { - setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) + - highlightColor + ")"); + setLine(sign, 2, highlightColor + "(" + mainColor + + translateAllColorCodes(portal.getNetwork()) + highlightColor + ")"); } Portal destination = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getNetwork()); @@ -304,13 +342,49 @@ public class PortalSignDrawer { } /** - * Fixes coloring of signs as the & character isn't translated on all servers + * Translates all found color codes to formatting in a string * - * @param text

The text to fix the coloring of

- * @return

The text with the coloring fixed

+ * @param message

The string to search for color codes

+ * @return

The message with color codes translated

*/ - private String fixColor(String text) { - return ChatColor.translateAlternateColorCodes('&', text); + public static String translateAllColorCodes(String message) { + message = ChatColor.translateAlternateColorCodes('&', message); + Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})"); + Matcher matcher = pattern.matcher(message); + while (matcher.find()) { + message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group())); + } + return message; + } + + /** + * Gets the main color to use for the given sign type + * + * @param signType

The sign type to get the main color for

+ * @return

The main color for the given sign type

+ */ + private ChatColor getMainColor(Material signType) { + ChatColor signColor = perSignMainColors.get(signType); + if (signColor == null) { + return mainColor; + } else { + return signColor; + } + } + + /** + * Gets the highlight color to use for the given sign type + * + * @param signType

The sign type to get the highlight color for

+ * @return

The highlight color for the given sign type

+ */ + private ChatColor getHighlightColor(Material signType) { + ChatColor signColor = perSignHighlightColors.get(signType); + if (signColor == null) { + return highlightColor; + } else { + return signColor; + } } } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 8c87002..00ee6db 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -4,7 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; diff --git a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java index c0be420..b4cdac5 100644 --- a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.utility; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import java.io.BufferedReader; import java.io.BufferedWriter; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 474be7f..0cba56c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -49,6 +49,15 @@ gates: sortNetworkDestinations: false mainSignColor: BLACK highlightSignColor: WHITE + perSignColors: + - "ACACIA:default,default" + - "BIRCH:default,default" + - "CRIMSON:default,default" + - "DARK_OAK:default,default" + - "JUNGLE:default,default" + - "OAK:default,default" + - "SPRUCE:default,default" + - "WARPED:default,default" integrity: destroyedByExplosion: false verifyPortals: false From 842fd9c452f338fab6c0b9eaec88af79e963bef0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 02:06:42 +0100 Subject: [PATCH 309/378] Fixes a few bugs regarding the new sign color system Fixes missing STRING_LIST in loadConfig switch Fixes missing color valid check in loadGateConfig Fixes typing of PER_SIGN_COLORS --- .../net/knarcraft/stargate/config/ConfigOption.java | 6 +++--- .../net/knarcraft/stargate/config/StargateConfig.java | 1 + .../knarcraft/stargate/config/StargateGateConfig.java | 11 ++++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 5944889..622639c 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -51,8 +51,8 @@ public enum ConfigOption { HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"), PER_SIGN_COLORS("gates.cosmetic.perSignColors", "The per-sign color specification", new String[]{ - "ACACIA:default,default", "BIRCH:default,default", "CRIMSON:default,default", "DARK_OAK:default,default", - "JUNGLE:default,default", "OAK:default,default", "SPRUCE:default,default", "WARPED:default,default"}), + "'ACACIA:default,default'", "'BIRCH:default,default'", "'CRIMSON:WHITE,BLACK'", "'DARK_OAK:WHITE,BLACK'", + "'JUNGLE:default,default'", "'OAK:default,default'", "'SPRUCE:WHITE,BLACK'", "'WARPED:WHITE,BLACK'"}), /** * Whether to destroy portals when any blocks are broken by explosions @@ -185,7 +185,7 @@ public enum ConfigOption { } else if (defaultValue instanceof Integer) { this.dataType = OptionDataType.INTEGER; } else { - throw new IllegalArgumentException("Unknown config data type encountered."); + throw new IllegalArgumentException("Unknown config data type encountered: " + defaultValue); } } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index f5526d5..346bb4d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -351,6 +351,7 @@ public final class StargateConfig { //Load the option using its correct data type switch (option.getDataType()) { + case STRING_LIST -> optionValue = newConfig.getStringList(configNode); case STRING -> { String value = newConfig.getString(configNode); optionValue = value != null ? value.trim() : ""; diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index e9cede7..ca26f20 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -6,6 +6,7 @@ import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -182,18 +183,18 @@ public final class StargateGateConfig { //Load the sign colors loadSignColor((String) configOptions.get(ConfigOption.MAIN_SIGN_COLOR), (String) configOptions.get(ConfigOption.HIGHLIGHT_SIGN_COLOR)); - String[] perSignColors = (String[]) configOptions.get(ConfigOption.PER_SIGN_COLORS); + List perSignColors = (List) configOptions.get(ConfigOption.PER_SIGN_COLORS); Map signMainColors = new HashMap<>(); Map signHighlightColors = new HashMap<>(); - for (String signColorSpecification : perSignColors) { - String[] specificationData = signColorSpecification.split(":"); + for (Object signColorSpecification : perSignColors) { + String[] specificationData = String.valueOf(signColorSpecification).split(":"); String[] colors = specificationData[1].split(","); - if (!colors[0].equalsIgnoreCase("default")) { + if (!colors[0].equalsIgnoreCase("default") && ChatColor.of(colors[0]) != null) { signMainColors.put(Material.matchMaterial(specificationData[0] + "_SIGN"), ChatColor.of(colors[0])); signMainColors.put(Material.matchMaterial(specificationData[0] + "_WALL_SIGN"), ChatColor.of(colors[0])); } - if (!colors[1].equalsIgnoreCase("default")) { + if (!colors[1].equalsIgnoreCase("default") && ChatColor.of(colors[1]) != null) { signHighlightColors.put(Material.matchMaterial(specificationData[0] + "_SIGN"), ChatColor.of(colors[1])); signHighlightColors.put(Material.matchMaterial(specificationData[0] + "_WALL_SIGN"), ChatColor.of(colors[1])); } From 404b4d0543dd98336c70cd5c73b60bfe29b7de20 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 02:07:07 +0100 Subject: [PATCH 310/378] Changes the comment format for config files --- src/main/resources/config.yml | 87 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0cba56c..769c35a 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,83 +1,84 @@ # stargate Configuration File # Main stargate config -# I----------I----------I # -# portalFolder - The folder for storing portals -# gateFolder - The folder for storing gate layouts -# defaultGateNetwork - The default gate network -# destroyedByExplosion - Whether to destroy gates with explosions (Creeper, TNT, etc.) -# maxGatesEachNetwork - The maximum number of gates allowed on a network - 0 for unlimited -# language - The language file to load for messages -# rememberDestination - Whether to remember the cursor location between uses -# handleVehicles - Whether to allow vehicles through gates. This overrides other vehicle settings -# handleEmptyVehicles - Whether to allow empty vehicles through gates (chest/hopper/tnt/furnace minecarts included) -# handleCreatureTransportation - Whether to allow players to transport creatures by sending vehicles (minecarts, boats) through gates -# handleNonPlayerVehicles - Whether to allow vehicles with a passenger which is not a player through gates. handleCreatureTransportation must be enabled -# handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player -# sortNetworkDestinations - Whether to sort network lists alphabetically -# protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) -# mainSignColor - The color used for drawing signs (Default: BLACK). -# highlightSignColor - The color used for sign markings (Default: WHITE) -# verifyPortals - Whether all the non-sign blocks are checked to match the gate layout when a stargate is loaded. -# adminUpdateAlert - Whether to alert admins about new plugin updates -# I------------I-------------I # -# stargate economy options # -# I------------I-------------I # -# useEconomy - Whether to use an economy plugin -# createCost - The cost to create a gate -# destroyCost - The cost to destroy a gate -# useCost - The cost to use a gate -# toOwner - Whether the charge for using a gate goes to the gate's owner -# chargeFreeDestination - Whether a gate whose destination is a free gate is still charged -# freeGatesColored - Whether a free gate in the destination list is marked with a color -# freeGatesColor - The color to use for marking free gates -# I-------I-------I # -# Debug options # -# I-------I-------I # -# debug - Debug -- Only enable if you have issues, massive console output -# permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) +# language - The language file to load for messages language: en +# adminUpdateAlert - Whether to alert admins about new plugin updates adminUpdateAlert: true folders: + # portalFolder - The folder for storing portals portalFolder: plugins/Stargate/portals/ + # gateFolder - The folder for storing gate layouts gateFolder: plugins/Stargate/gates/ gates: + # maxGatesEachNetwork - The maximum number of gates allowed on a network - 0 for unlimited maxGatesEachNetwork: 0 + # defaultGateNetwork - The default gate network defaultGateNetwork: central cosmetic: + # rememberDestination - Whether to remember the cursor location between uses rememberDestination: false + # sortNetworkDestinations - Whether to sort network lists alphabetically sortNetworkDestinations: false + # mainSignColor - The color used for drawing signs (Default: BLACK). mainSignColor: BLACK + # highlightSignColor - The color used for sign markings (Default: WHITE) highlightSignColor: WHITE perSignColors: - - "ACACIA:default,default" - - "BIRCH:default,default" - - "CRIMSON:default,default" - - "DARK_OAK:default,default" - - "JUNGLE:default,default" - - "OAK:default,default" - - "SPRUCE:default,default" - - "WARPED:default,default" + - 'ACACIA:default,default' + - 'BIRCH:default,default' + - 'CRIMSON:WHITE,BLACK' + - 'DARK_OAK:WHITE,BLACK' + - 'JUNGLE:default,default' + - 'OAK:default,default' + - 'SPRUCE:WHITE,BLACK' + - 'WARPED:WHITE,BLACK' integrity: + # destroyedByExplosion - Whether to destroy gates with explosions (Creeper, TNT, etc.) destroyedByExplosion: false + # verifyPortals - Whether all the non-sign blocks are checked to match the gate layout when a stargate is loaded. verifyPortals: false + # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) protectEntrance: false functionality: enableBungee: false + # handleVehicles - Whether to allow vehicles through gates. This overrides other vehicle settings handleVehicles: true + # handleEmptyVehicles - Whether to allow empty vehicles through gates (chest/hopper/tnt/furnace minecarts included) handleEmptyVehicles: true + # handleCreatureTransportation - Whether to allow players to transport creatures by sending vehicles (minecarts, boats) through gates handleCreatureTransportation: true + # handleNonPlayerVehicles - Whether to allow vehicles with a passenger which is not a player through gates. handleCreatureTransportation must be enabled handleNonPlayerVehicles: true + # handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player handleLeashedCreatures: true + +# I------------I-------------I # +# stargate economy options # +# I------------I-------------I # economy: + # useEconomy - Whether to use an economy plugin useEconomy: false + # createCost - The cost to create a gate createCost: 0 + # destroyCost - The cost to destroy a gate destroyCost: 0 + # useCost - The cost to use a gate useCost: 0 + # toOwner - Whether the charge for using a gate goes to the gate's owner toOwner: false + # chargeFreeDestination - Whether a gate whose destination is a free gate is still charged chargeFreeDestination: true + # freeGatesColored - Whether a free gate in the destination list is marked with a color freeGatesColored: false + # freeGatesColor - The color to use for marking free gates freeGatesColor: DARK_GREEN + +# I-------I-------I # +# Debug options # +# I-------I-------I # debugging: + # debug - Debug -- Only enable if you have issues, massive console output debug: false + # permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) permissionDebug: false \ No newline at end of file From 7d41b75bac318273e6edba9cd01b518407bdcc11 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 05:09:34 +0100 Subject: [PATCH 311/378] Makes string list config values display their default value properly --- .../knarcraft/stargate/command/CommandConfig.java | 14 +++++++++++++- .../stargate/command/ConfigTabCompleter.java | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 2bac15c..7df2447 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -3,10 +3,12 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.ConfigOption; import net.knarcraft.stargate.config.ConfigTag; +import net.knarcraft.stargate.config.OptionDataType; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.PortalSignDrawer; import net.md_5.bungee.api.ChatColor; +import org.apache.commons.lang.StringUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -106,6 +108,11 @@ public class CommandConfig implements CommandExecutor { Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); configuration.set(selectedOption.getConfigNode(), value); } + case STRING_LIST -> { + if (selectedOption == ConfigOption.PER_SIGN_COLORS) { + commandSender.sendMessage(ChatColor.RED + value); + } + } default -> { Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); configuration.set(selectedOption.getConfigNode(), value); @@ -242,8 +249,13 @@ public class CommandConfig implements CommandExecutor { * @return

A string describing the config option

*/ private String getOptionDescription(ConfigOption option) { + Object defaultValue = option.getDefaultValue(); + String stringValue = String.valueOf(defaultValue); + if (option.getDataType() == OptionDataType.STRING_LIST) { + stringValue = "[" + StringUtils.join((String[]) defaultValue, ",") + "]"; + } return ChatColor.GOLD + option.getName() + ChatColor.WHITE + " - " + ChatColor.GREEN + option.getDescription() + - ChatColor.DARK_GRAY + " (Default: " + ChatColor.GRAY + option.getDefaultValue() + ChatColor.DARK_GRAY + ")"; + ChatColor.DARK_GRAY + " (Default: " + ChatColor.GRAY + stringValue + ChatColor.DARK_GRAY + ")"; } } diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index f0f01c6..a324d39 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -105,6 +105,8 @@ public class ConfigTabCompleter implements TabCompleter { } } + //TODO: What to do with per-sign colors? + return null; } From 4cae54e46f25fcc60c61a6b5b9a5a2d9dc85fb20 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 14:40:29 +0100 Subject: [PATCH 312/378] Adds support for dyed stargate signs A dyed sign's color will now take priority over its main sign color. Black is used as the "default" color, so use black dye to remove dye effects Adds a new class to keep track of a sign and its colors Updates a bunch of code to make everything account for the dye color --- .../stargate/container/SignData.java | 64 ++++++++++ .../listener/PlayerEventListener.java | 12 ++ .../stargate/portal/PortalSignDrawer.java | 120 +++++++++--------- 3 files changed, 138 insertions(+), 58 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/container/SignData.java diff --git a/src/main/java/net/knarcraft/stargate/container/SignData.java b/src/main/java/net/knarcraft/stargate/container/SignData.java new file mode 100644 index 0000000..9e64e96 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/container/SignData.java @@ -0,0 +1,64 @@ +package net.knarcraft.stargate.container; + +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Color; +import org.bukkit.DyeColor; +import org.bukkit.block.Sign; + +/** + * A class that keeps track of the sign colors for a given sign + */ +public class SignData { + + private final Sign sign; + private final ChatColor mainSignColor; + private final ChatColor highlightSignColor; + private final DyeColor dyedColor; + + /** + * Instantiates a new sign colors object + * + * @param sign

The sign the colors belong to

+ * @param mainSignColor

The main color to use for the sign

+ * @param highlightSignColor

The highlighting color to use for the sign

+ */ + public SignData(Sign sign, ChatColor mainSignColor, ChatColor highlightSignColor) { + this.sign = sign; + this.mainSignColor = mainSignColor; + this.highlightSignColor = highlightSignColor; + this.dyedColor = sign.getColor(); + } + + /** + * Gets the sign of this sign colors object + * + * @return

The sign of this sign colors object

+ */ + public Sign getSign() { + return sign; + } + + /** + * Gets the main color of the sign + * + * @return

The main color of the sign

+ */ + public ChatColor getMainSignColor() { + if (dyedColor != DyeColor.BLACK) { + Color color = dyedColor.getColor(); + return ChatColor.of(String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue())); + } else { + return mainSignColor; + } + } + + /** + * Gets the highlighting color of the sign + * + * @return

The highlighting color of the sign

+ */ + public ChatColor getHighlightSignColor() { + return highlightSignColor; + } + +} diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index a73b314..eb46e2c 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -15,6 +15,7 @@ import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.UUIDMigrationHelper; import net.knarcraft.stargate.utility.UpdateChecker; import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -221,6 +222,17 @@ public class PlayerEventListener implements Listener { return; } + //Allow players to apply dye to signs + EquipmentSlot hand = event.getHand(); + if (hand != null) { + String itemName = player.getInventory().getItem(hand).getType().toString(); + if (itemName.endsWith("DYE") || itemName.endsWith("INK_SAC")) { + event.setUseInteractedBlock(Event.Result.ALLOW); + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), portal::drawSign, 1); + return; + } + } + event.setUseInteractedBlock(Event.Result.DENY); if (leftClick) { //Cancel event in creative mode to prevent breaking the sign diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 563933c..b942d5d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.SignData; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.utility.PermissionHelper; import net.md_5.bungee.api.ChatColor; @@ -93,7 +94,8 @@ public class PortalSignDrawer { return; } - drawSign(sign); + SignData signData = new SignData(sign, getMainColor(sign.getType()), getHighlightColor(sign.getType())); + drawSign(signData); } /** @@ -118,28 +120,30 @@ public class PortalSignDrawer { /** * Draws the sign of the portal this sign drawer is responsible for * - * @param sign

The sign re-draw

+ * @param signData

All necessary sign information

*/ - private void drawSign(Sign sign) { - ChatColor highlightColor = getHighlightColor(sign.getType()); - ChatColor mainColor = getMainColor(sign.getType()); + private void drawSign(SignData signData) { + Sign sign = signData.getSign(); + ChatColor highlightColor = signData.getHighlightSignColor(); + ChatColor mainColor = signData.getMainSignColor(); //Clear sign clearSign(sign); - setLine(sign, 0, highlightColor + "-" + mainColor + translateAllColorCodes(portal.getName()) + highlightColor + "-"); + setLine(signData, 0, highlightColor + "-" + mainColor + translateAllColorCodes(portal.getName()) + + highlightColor + "-"); if (!portal.getPortalActivator().isActive()) { //Default sign text - drawInactiveSign(sign); + drawInactiveSign(signData); } else { if (portal.getOptions().isBungee()) { //Bungee sign - drawBungeeSign(sign); + drawBungeeSign(signData); } else if (portal.getOptions().isFixed()) { //Sign pointing at one other portal - drawFixedSign(sign); + drawFixedSign(signData); } else { //Networking stuff - drawNetworkSign(sign); + drawNetworkSign(signData); } } @@ -173,9 +177,9 @@ public class PortalSignDrawer { /** * Draws a sign with choose-able network locations * - * @param sign

The sign to re-draw

+ * @param signData

All necessary sign information

*/ - private void drawNetworkSign(Sign sign) { + private void drawNetworkSign(SignData signData) { PortalActivator destinations = portal.getPortalActivator(); int maxIndex = destinations.getDestinations().size() - 1; int signLineIndex = 0; @@ -185,42 +189,42 @@ public class PortalSignDrawer { //Last, and not only entry. Draw the entry two back if ((destinationIndex == maxIndex) && (maxIndex > 1)) { - drawNetworkSignLine(freeGatesColored, sign, ++signLineIndex, destinationIndex - 2); + drawNetworkSignLine(signData, freeGatesColored, ++signLineIndex, destinationIndex - 2); } //Not first entry. Draw the previous entry if (destinationIndex > 0) { - drawNetworkSignLine(freeGatesColored, sign, ++signLineIndex, destinationIndex - 1); + drawNetworkSignLine(signData, freeGatesColored, ++signLineIndex, destinationIndex - 1); } //Draw the chosen entry (line 2 or 3) - drawNetworkSignChosenLine(freeGatesColored, sign, ++signLineIndex); + drawNetworkSignChosenLine(signData, freeGatesColored, ++signLineIndex); //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 1)) { - drawNetworkSignLine(freeGatesColored, sign, ++signLineIndex, destinationIndex + 1); + drawNetworkSignLine(signData, freeGatesColored, ++signLineIndex, destinationIndex + 1); } //Has another entry and space on the sign if ((maxIndex >= destinationIndex + 2) && (++signLineIndex <= 3)) { - drawNetworkSignLine(freeGatesColored, sign, signLineIndex, destinationIndex + 2); + drawNetworkSignLine(signData, freeGatesColored, signLineIndex, destinationIndex + 2); } } /** * Draws the chosen destination on one sign line * + * @param signData

All necessary sign information

* @param freeGatesColored

Whether to display free gates in a different color

- * @param sign

The sign to draw on

* @param signLineIndex

The line to draw on

*/ - private void drawNetworkSignChosenLine(boolean freeGatesColored, Sign sign, int signLineIndex) { - ChatColor highlightColor = getHighlightColor(sign.getType()); - ChatColor mainColor = getMainColor(sign.getType()); + private void drawNetworkSignChosenLine(SignData signData, boolean freeGatesColored, int signLineIndex) { + ChatColor highlightColor = signData.getHighlightSignColor(); + ChatColor mainColor = signData.getMainSignColor(); if (freeGatesColored) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); ChatColor nameColor = (free ? freeColor : highlightColor); - setLine(sign, signLineIndex, nameColor + ">" + (free ? freeColor : mainColor) + + setLine(signData, signLineIndex, nameColor + ">" + (free ? freeColor : mainColor) + translateAllColorCodes(portal.getDestinationName()) + nameColor + "<"); } else { - setLine(sign, signLineIndex, highlightColor + ">" + mainColor + + setLine(signData, signLineIndex, highlightColor + ">" + mainColor + translateAllColorCodes(portal.getDestinationName()) + highlightColor + "<"); } } @@ -228,48 +232,48 @@ public class PortalSignDrawer { /** * Sets a line on a sign, adding the chosen sign color * - * @param sign

The sign to update

- * @param index

The index of the sign line to change

- * @param text

The new text on the sign

+ * @param signData

All necessary sign information

+ * @param index

The index of the sign line to change

+ * @param text

The new text on the sign

*/ - public void setLine(Sign sign, int index, String text) { - ChatColor mainColor = getMainColor(sign.getType()); - sign.setLine(index, mainColor + text); + public void setLine(SignData signData, int index, String text) { + ChatColor mainColor = signData.getMainSignColor(); + signData.getSign().setLine(index, mainColor + text); } /** * Draws one network destination on one sign line * + * @param signData

All necessary sign information

* @param freeGatesColored

Whether to display free gates in a different color

- * @param sign

The sign to draw on

* @param signLineIndex

The line to draw on

* @param destinationIndex

The index of the destination to draw

*/ - private void drawNetworkSignLine(boolean freeGatesColored, Sign sign, int signLineIndex, int destinationIndex) { - ChatColor mainColor = getMainColor(sign.getType()); + private void drawNetworkSignLine(SignData signData, boolean freeGatesColored, int signLineIndex, int destinationIndex) { + ChatColor mainColor = signData.getMainSignColor(); PortalActivator destinations = portal.getPortalActivator(); String destinationName = destinations.getDestinations().get(destinationIndex); if (freeGatesColored) { Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork()); boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); - setLine(sign, signLineIndex, (free ? freeColor : mainColor) + translateAllColorCodes(destinationName)); + setLine(signData, signLineIndex, (free ? freeColor : mainColor) + translateAllColorCodes(destinationName)); } else { - setLine(sign, signLineIndex, mainColor + translateAllColorCodes(destinationName)); + setLine(signData, signLineIndex, mainColor + translateAllColorCodes(destinationName)); } } /** * Draws the sign of a BungeeCord portal * - * @param sign

The sign to re-draw

+ * @param signData

All necessary sign information

*/ - private void drawBungeeSign(Sign sign) { - ChatColor highlightColor = getHighlightColor(sign.getType()); - ChatColor mainColor = getMainColor(sign.getType()); - setLine(sign, 1, Stargate.getString("bungeeSign")); - setLine(sign, 2, highlightColor + ">" + mainColor + translateAllColorCodes(portal.getDestinationName()) + + private void drawBungeeSign(SignData signData) { + ChatColor highlightColor = signData.getHighlightSignColor(); + ChatColor mainColor = signData.getMainSignColor(); + setLine(signData, 1, Stargate.getString("bungeeSign")); + setLine(signData, 2, highlightColor + ">" + mainColor + translateAllColorCodes(portal.getDestinationName()) + highlightColor + "<"); - setLine(sign, 3, highlightColor + "[" + mainColor + translateAllColorCodes(portal.getNetwork()) + + setLine(signData, 3, highlightColor + "[" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + "]"); } @@ -278,48 +282,48 @@ public class PortalSignDrawer { * *

The sign for an in-active portal should display the right-click prompt and the network.

* - * @param sign

The sign to re-draw

+ * @param signData

All necessary sign information

*/ - private void drawInactiveSign(Sign sign) { - ChatColor highlightColor = getHighlightColor(sign.getType()); - ChatColor mainColor = getMainColor(sign.getType()); - setLine(sign, 1, Stargate.getString("signRightClick")); - setLine(sign, 2, Stargate.getString("signToUse")); + private void drawInactiveSign(SignData signData) { + ChatColor highlightColor = signData.getHighlightSignColor(); + ChatColor mainColor = signData.getMainSignColor(); + setLine(signData, 1, Stargate.getString("signRightClick")); + setLine(signData, 2, Stargate.getString("signToUse")); if (!portal.getOptions().isNoNetwork()) { - setLine(sign, 3, highlightColor + "(" + mainColor + translateAllColorCodes(portal.getNetwork()) + + setLine(signData, 3, highlightColor + "(" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + ")"); } else { - setLine(sign, 3, ""); + setLine(signData, 3, ""); } } /** * Draws a sign pointing to a fixed location * - * @param sign

The sign to re-draw

+ * @param signData

All necessary sign information

*/ - private void drawFixedSign(Sign sign) { - ChatColor highlightColor = getHighlightColor(sign.getType()); - ChatColor mainColor = getMainColor(sign.getType()); + private void drawFixedSign(SignData signData) { + ChatColor highlightColor = signData.getHighlightSignColor(); + ChatColor mainColor = signData.getMainSignColor(); Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getCleanNetwork()); String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : (destinationPortal != null ? destinationPortal.getName() : portal.getDestinationName()); - setLine(sign, 1, highlightColor + ">" + mainColor + translateAllColorCodes(destinationName) + + setLine(signData, 1, highlightColor + ">" + mainColor + translateAllColorCodes(destinationName) + highlightColor + "<"); if (portal.getOptions().isNoNetwork()) { - setLine(sign, 2, ""); + setLine(signData, 2, ""); } else { - setLine(sign, 2, highlightColor + "(" + mainColor + + setLine(signData, 2, highlightColor + "(" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + ")"); } Portal destination = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { - setLine(sign, 3, errorColor + Stargate.getString("signDisconnected")); + setLine(signData, 3, errorColor + Stargate.getString("signDisconnected")); } else { - setLine(sign, 3, ""); + setLine(signData, 3, ""); } } From 071f1895de9aab20ebc0185d836ceedb93eb5bb9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 14:57:15 +0100 Subject: [PATCH 313/378] Makes sure only the owner and players with stargate.admin.dye can dye stargate signs --- .../knarcraft/stargate/listener/PlayerEventListener.java | 5 +++-- src/main/resources/plugin.yml | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index eb46e2c..b182690 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -222,9 +222,10 @@ public class PlayerEventListener implements Listener { return; } - //Allow players to apply dye to signs + //Allow players with permissions to apply dye to signs EquipmentSlot hand = event.getHand(); - if (hand != null) { + if (hand != null && (PermissionHelper.hasPermission(player, "stargate.admin.dye") || + portal.isOwner(player))) { String itemName = player.getInventory().getItem(hand).getType().toString(); if (itemName.endsWith("DYE") || itemName.endsWith("INK_SAC")) { event.setUseInteractedBlock(Event.Result.ALLOW); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 92399fb..ac9be07 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -141,6 +141,9 @@ permissions: stargate.admin.config: description: Allows the player to change config values from the chat default: false + stargate.admin.dye: + description: Allows this player to change the dye of any stargate's sign + default: false stargate.server: description: Allows the creation of a BungeeCord stargate going to any server default: false @@ -152,4 +155,5 @@ permissions: stargate.admin.hidden: true stargate.admin.private: true stargate.admin.bungee: true - stargate.admin.config: true \ No newline at end of file + stargate.admin.config: true + stargate.admin.dye: true \ No newline at end of file From 2773079a09816a343cac55c3b73542817b037c68 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 15:49:07 +0100 Subject: [PATCH 314/378] Uses the inverted color for a dyed sign's highlighting color --- .../stargate/container/SignData.java | 11 +++-- .../stargate/portal/PortalSignDrawer.java | 20 +------- .../stargate/utility/ColorHelper.java | 47 +++++++++++++++++++ 3 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/ColorHelper.java diff --git a/src/main/java/net/knarcraft/stargate/container/SignData.java b/src/main/java/net/knarcraft/stargate/container/SignData.java index 9e64e96..38b3076 100644 --- a/src/main/java/net/knarcraft/stargate/container/SignData.java +++ b/src/main/java/net/knarcraft/stargate/container/SignData.java @@ -1,7 +1,7 @@ package net.knarcraft.stargate.container; +import net.knarcraft.stargate.utility.ColorHelper; import net.md_5.bungee.api.ChatColor; -import org.bukkit.Color; import org.bukkit.DyeColor; import org.bukkit.block.Sign; @@ -45,8 +45,7 @@ public class SignData { */ public ChatColor getMainSignColor() { if (dyedColor != DyeColor.BLACK) { - Color color = dyedColor.getColor(); - return ChatColor.of(String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue())); + return ColorHelper.fromColor(dyedColor.getColor()); } else { return mainSignColor; } @@ -58,7 +57,11 @@ public class SignData { * @return

The highlighting color of the sign

*/ public ChatColor getHighlightSignColor() { - return highlightSignColor; + if (dyedColor != DyeColor.BLACK) { + return ColorHelper.fromColor(ColorHelper.invert(dyedColor.getColor())); + } else { + return highlightSignColor; + } } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index b942d5d..299aad7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -11,8 +11,8 @@ import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; + +import static net.knarcraft.stargate.utility.ColorHelper.translateAllColorCodes; /** * The portal sign drawer draws the sing of a given portal @@ -345,22 +345,6 @@ public class PortalSignDrawer { Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName)); } - /** - * Translates all found color codes to formatting in a string - * - * @param message

The string to search for color codes

- * @return

The message with color codes translated

- */ - public static String translateAllColorCodes(String message) { - message = ChatColor.translateAlternateColorCodes('&', message); - Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})"); - Matcher matcher = pattern.matcher(message); - while (matcher.find()) { - message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group())); - } - return message; - } - /** * Gets the main color to use for the given sign type * diff --git a/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java b/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java new file mode 100644 index 0000000..027bd66 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java @@ -0,0 +1,47 @@ +package net.knarcraft.stargate.utility; + +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Color; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ColorHelper { + + /** + * Inverts the given color + * + * @param color

The color to invert

+ * @return

The inverted color

+ */ + public static Color invert(Color color) { + return color.setRed(255 - color.getRed()).setGreen(255 - color.getGreen()).setBlue(255 - color.getBlue()); + } + + /** + * Gets the chat color corresponding to the given color + * + * @param color

The color to convert into a chat color

+ * @return

The resulting chat color

+ */ + public static ChatColor fromColor(Color color) { + return ChatColor.of(String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue())); + } + + /** + * Translates all found color codes to formatting in a string + * + * @param message

The string to search for color codes

+ * @return

The message with color codes translated

+ */ + public static String translateAllColorCodes(String message) { + message = ChatColor.translateAlternateColorCodes('&', message); + Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})"); + Matcher matcher = pattern.matcher(message); + while (matcher.find()) { + message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group())); + } + return message; + } + +} From 97670c9367a4b3544f4a0b7466e3e2840d8375f9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 18:02:53 +0100 Subject: [PATCH 315/378] Adds the possibility to use the inverted default colors for per-sign colors Adds code for getting inverted colors if "inverted" is given as the per-sign color Fixes exceptions thrown when the per-sign config value is malformed Changes the default to use inverted colors for crimson, dark_oak, spruce and warped signs Adds methods to get main and highlighting colors from the portal sign drawer in case the given default colors are invalid and fallback colors are necessary instead --- .../stargate/config/ConfigOption.java | 4 +- .../stargate/config/StargateGateConfig.java | 103 +++++++++++++++--- .../stargate/portal/PortalSignDrawer.java | 18 +++ src/main/resources/config.yml | 8 +- 4 files changed, 109 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 622639c..76d3870 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -51,8 +51,8 @@ public enum ConfigOption { HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"), PER_SIGN_COLORS("gates.cosmetic.perSignColors", "The per-sign color specification", new String[]{ - "'ACACIA:default,default'", "'BIRCH:default,default'", "'CRIMSON:WHITE,BLACK'", "'DARK_OAK:WHITE,BLACK'", - "'JUNGLE:default,default'", "'OAK:default,default'", "'SPRUCE:WHITE,BLACK'", "'WARPED:WHITE,BLACK'"}), + "'ACACIA:default,default'", "'BIRCH:default,default'", "'CRIMSON:inverted,inverted'", "'DARK_OAK:inverted,inverted'", + "'JUNGLE:default,default'", "'OAK:default,default'", "'SPRUCE:inverted,inverted'", "'WARPED:inverted,inverted'"}), /** * Whether to destroy portals when any blocks are broken by explosions diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index ca26f20..7ac1858 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -2,9 +2,12 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.PortalSignDrawer; +import net.knarcraft.stargate.utility.ColorHelper; import net.md_5.bungee.api.ChatColor; +import org.bukkit.Color; import org.bukkit.Material; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -181,27 +184,91 @@ public final class StargateGateConfig { */ private void loadGateConfig() { //Load the sign colors - loadSignColor((String) configOptions.get(ConfigOption.MAIN_SIGN_COLOR), - (String) configOptions.get(ConfigOption.HIGHLIGHT_SIGN_COLOR)); - List perSignColors = (List) configOptions.get(ConfigOption.PER_SIGN_COLORS); + String mainSignColor = (String) configOptions.get(ConfigOption.MAIN_SIGN_COLOR); + String highlightSignColor = (String) configOptions.get(ConfigOption.HIGHLIGHT_SIGN_COLOR); + loadPerSignColor(mainSignColor, highlightSignColor); + loadPerSignColors(); + } + + /** + * Loads the per-sign colors specified in the config file + */ + private void loadPerSignColors() { + List perSignColors = (List) configOptions.get(ConfigOption.PER_SIGN_COLORS); + ChatColor[] defaultColors = new ChatColor[]{PortalSignDrawer.getMainColor(), PortalSignDrawer.getHighlightColor()}; + List> colorMaps = new ArrayList<>(); + colorMaps.add(new HashMap<>()); + colorMaps.add(new HashMap<>()); - Map signMainColors = new HashMap<>(); - Map signHighlightColors = new HashMap<>(); for (Object signColorSpecification : perSignColors) { - String[] specificationData = String.valueOf(signColorSpecification).split(":"); - String[] colors = specificationData[1].split(","); - if (!colors[0].equalsIgnoreCase("default") && ChatColor.of(colors[0]) != null) { - signMainColors.put(Material.matchMaterial(specificationData[0] + "_SIGN"), ChatColor.of(colors[0])); - signMainColors.put(Material.matchMaterial(specificationData[0] + "_WALL_SIGN"), ChatColor.of(colors[0])); - } - if (!colors[1].equalsIgnoreCase("default") && ChatColor.of(colors[1]) != null) { - signHighlightColors.put(Material.matchMaterial(specificationData[0] + "_SIGN"), ChatColor.of(colors[1])); - signHighlightColors.put(Material.matchMaterial(specificationData[0] + "_WALL_SIGN"), ChatColor.of(colors[1])); - } + parsePerSignColors(signColorSpecification, defaultColors, colorMaps); } - PortalSignDrawer.setPerSignMainColors(signMainColors); - PortalSignDrawer.setPerSignHighlightColors(signHighlightColors); + PortalSignDrawer.setPerSignMainColors(colorMaps.get(0)); + PortalSignDrawer.setPerSignHighlightColors(colorMaps.get(1)); + } + + /** + * Parses a per-sign color specification object and stores the result + * + * @param signColorSpecification

The sign color specification to parse

+ * @param defaultColors

The specified default colors

+ * @param colorMaps

The list of color maps to save the resulting colors to

+ */ + private void parsePerSignColors(Object signColorSpecification, ChatColor[] defaultColors, + List> colorMaps) { + String[] specificationData = String.valueOf(signColorSpecification).split(":"); + Material[] signMaterials = new Material[]{Material.matchMaterial(specificationData[0] + "_SIGN"), + Material.matchMaterial(specificationData[0] + "_WALL_SIGN")}; + + if (specificationData.length != 2) { + Stargate.logWarning("You have an invalid per-sign line in your config.yml file. Please fix it!"); + return; + } + String[] colors = specificationData[1].split(","); + if (colors.length != 2) { + Stargate.logWarning("You have an invalid per-sign line in your config.yml file. Please fix it!"); + return; + } + for (int colorIndex = 0; colorIndex < 2; colorIndex++) { + if (colors[colorIndex].equalsIgnoreCase("default")) { + continue; + } + loadPerSignColor(colors, colorIndex, defaultColors, signMaterials, colorMaps); + } + } + + /** + * Loads a per-sign color + * + * @param colors

The colors specified in the config file

+ * @param colorIndex

The index of the color to load

+ * @param defaultColors

The specified default colors

+ * @param signMaterials

The materials to load this color for

+ * @param colorMaps

The list of color maps to save the resulting color to

+ */ + private void loadPerSignColor(String[] colors, int colorIndex, ChatColor[] defaultColors, Material[] signMaterials, + List> colorMaps) { + ChatColor parsedColor; + if (colors[colorIndex].equalsIgnoreCase("inverted")) { + //Convert from ChatColor to awt.Color to Bukkit.Color then invert and convert to ChatColor + java.awt.Color color = defaultColors[colorIndex].getColor(); + parsedColor = ColorHelper.fromColor(ColorHelper.invert(Color.fromRGB(color.getRed(), + color.getGreen(), color.getBlue()))); + } else { + try { + parsedColor = ChatColor.of(colors[colorIndex]); + } catch (IllegalArgumentException | NullPointerException exception) { + Stargate.logWarning("You have specified an invalid per-sign color in your config.yml. Custom color for \"" + + signMaterials[0] + "\" disabled"); + return; + } + } + if (parsedColor != null) { + for (Material signMaterial : signMaterials) { + colorMaps.get(colorIndex).put(signMaterial, parsedColor); + } + } } /** @@ -209,7 +276,7 @@ public final class StargateGateConfig { * * @param mainSignColor

A string representing the main sign color

*/ - private void loadSignColor(String mainSignColor, String highlightSignColor) { + private void loadPerSignColor(String mainSignColor, String highlightSignColor) { try { PortalSignDrawer.setMainColor(ChatColor.of(mainSignColor.toUpperCase())); PortalSignDrawer.setHighlightColor(ChatColor.of(highlightSignColor.toUpperCase())); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 299aad7..2bad4c4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -85,6 +85,24 @@ public class PortalSignDrawer { PortalSignDrawer.perSignHighlightColors = signHighlightColors; } + /** + * Gets the currently used main sign color + * + * @return

The currently used main sign color

+ */ + public static ChatColor getMainColor() { + return mainColor; + } + + /** + * Gets the currently used highlighting sign color + * + * @return

The currently used highlighting sign color

+ */ + public static ChatColor getHighlightColor() { + return highlightColor; + } + /** * Draws the sign of the portal this sign drawer is responsible for */ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 769c35a..46d18d2 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -27,12 +27,12 @@ gates: perSignColors: - 'ACACIA:default,default' - 'BIRCH:default,default' - - 'CRIMSON:WHITE,BLACK' - - 'DARK_OAK:WHITE,BLACK' + - 'CRIMSON:inverted,inverted' + - 'DARK_OAK:inverted,inverted' - 'JUNGLE:default,default' - 'OAK:default,default' - - 'SPRUCE:WHITE,BLACK' - - 'WARPED:WHITE,BLACK' + - 'SPRUCE:inverted,inverted' + - 'WARPED:inverted,inverted' integrity: # destroyedByExplosion - Whether to destroy gates with explosions (Creeper, TNT, etc.) destroyedByExplosion: false From 02f6c6e9fcfb3ddf245fe961b6aa97273d24f455 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 18:17:10 +0100 Subject: [PATCH 316/378] Updates README with recent changes --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 82968f9..7903309 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ can share a network or be split into clusters; they can be hidden on a network o - **API available** -- using the API, a lot of behavior can be changed - **Button customization** -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) - **Config commands** -- All main config values can be changed from the commandline +- **RGB and dye support** -- Signs can use RGB colors as their default colors, and can also be dyed on a per-sign basis ## Background @@ -85,6 +86,7 @@ stargate.admin -- Allow all admin features (Hidden/Private bypass, BungeeCord, R stargate.admin.bungee -- Allow the creation of BungeeCord stargates (U option) stargate.admin.reload -- Allow use of the reload command stargate.admin.config -- Allows the player to change config values from the chat + stargate.admin.dye -- Allows this player to change the dye of any stargate's sign ``` ## Default Permissions @@ -304,8 +306,9 @@ gates: cosmetic: rememberDestination - Whether to set the first destination as the last used destination for all gates sortNetworkDestinations - If true, network lists will be sorted alphabetically. - mainSignColor - This allows you to specify the color of the gate signs. - highlightSignColor - This allows you to specify the color of the sign markings. + mainSignColor - This allows you to specify the color of the gate signs. Use a color code such as WHITE,BLACK,YELLOW or a hex color code such as '#ed76d9'. You need quotes around hex color codes. + highlightSignColor - This allows you to specify the color of the sign markings. Use a color code such as WHITE,BLACK,YELLOW or a hex color code such as '#ed76d9'. You need quotes around hex color codes. + perSignColors: - A list of per-sign color specifications. Format: "SIGN_TYPE:mainColor,highlight_color". The SIGN_TYPE is OAK for an oak sign, DARK_OAK for a dark oak sign and so on. The colors can be "default" to use the color specified in "mainSignColor" or "highlightSignColor", "inverted" to use the inverse color of the default color, a normal color such as BLACK,WHITE,YELLOW or a hex color code such as #ed76d9. integrity: destroyedByExplosion - Whether to destroy a stargate with explosions, or stop an explosion if it contains a gates controls. verifyPortals - Whether or not all the non-sign blocks are checked to match the gate layout when an old stargate is loaded at startup. @@ -390,6 +393,12 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.0] EpicKnarvik97 fork + +- Adds support for RGB colors (use hex color codes) +- Adds support for dyed and glowing signs +- Adds support for specifying sign colors per sign type + #### \[Version 0.9.2.5] EpicKnarvik97 fork - Updates Java version to JDK 17 From 366cd3107e1f90c0ce9a2a3160a2019d03280b09 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 20:30:16 +0100 Subject: [PATCH 317/378] Updates per-sign inverted colors when the main or highlighting color is changed --- README.md | 3 +- .../stargate/command/CommandConfig.java | 33 +++++++++++-------- .../knarcraft/stargate/config/ConfigTag.java | 10 ++++++ .../stargate/config/StargateGateConfig.java | 11 +++++-- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 7903309..200af46 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ can share a network or be split into clusters; they can be hidden on a network o - **API available** -- using the API, a lot of behavior can be changed - **Button customization** -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) - **Config commands** -- All main config values can be changed from the commandline -- **RGB and dye support** -- Signs can use RGB colors as their default colors, and can also be dyed on a per-sign basis +- **RGB and dye support** -- Signs can use RGB colors (using hex codes) as their main and highlighting colors, and can + also be dyed on a per-sign basis ## Background diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 7df2447..19260aa 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -200,20 +200,27 @@ public class CommandConfig implements CommandExecutor { if (ConfigTag.requiresFullReload(configOption)) { //Reload everything Stargate.getStargateConfig().reload(commandSender); - } else if (ConfigTag.requiresPortalReload(configOption)) { - //Just unload and reload the portals - Stargate.getStargateConfig().unloadAllPortals(); - Stargate.getStargateConfig().loadAllPortals(); - } else if (ConfigTag.requiresLanguageReload(configOption)) { - //Reload the language loader - Stargate.getStargateConfig().getLanguageLoader().reload(); - //Re-draw all portal signs - for (Portal portal : PortalRegistry.getAllPortals()) { - portal.drawSign(); + } else { + if (ConfigTag.requiresColorReload(configOption)) { + Stargate.getStargateConfig().getStargateGateConfig().loadPerSignColors(); + } + if (ConfigTag.requiresPortalReload(configOption)) { + //Just unload and reload the portals + Stargate.getStargateConfig().unloadAllPortals(); + Stargate.getStargateConfig().loadAllPortals(); + } + if (ConfigTag.requiresLanguageReload(configOption)) { + //Reload the language loader + Stargate.getStargateConfig().getLanguageLoader().reload(); + //Re-draw all portal signs + for (Portal portal : PortalRegistry.getAllPortals()) { + portal.drawSign(); + } + } + if (ConfigTag.requiresEconomyReload(configOption)) { + //Load or unload Vault and Economy as necessary + Stargate.getStargateConfig().reloadEconomy(); } - } else if (ConfigTag.requiresEconomyReload(configOption)) { - //Load or unload Vault and Economy as necessary - Stargate.getStargateConfig().reloadEconomy(); } } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java index 4896e20..95dea52 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java @@ -31,6 +31,16 @@ public enum ConfigTag { return Arrays.stream(taggedOptions).anyMatch((item) -> item == option); } + /** + * Checks whether a given config option requires a "reload of colors" to take effect + * + * @param configOption

The config option to check

+ * @return

True if changing the config option requires a "reload of colors" to take effect

+ */ + public static boolean requiresColorReload(ConfigOption configOption) { + return COLOR.isTagged(configOption) && configOption != ConfigOption.FREE_GATES_COLOR; + } + /** * Checks whether a given config option requires a full reload to take effect * diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 7ac1858..001ced9 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -193,7 +193,7 @@ public final class StargateGateConfig { /** * Loads the per-sign colors specified in the config file */ - private void loadPerSignColors() { + public void loadPerSignColors() { List perSignColors = (List) configOptions.get(ConfigOption.PER_SIGN_COLORS); ChatColor[] defaultColors = new ChatColor[]{PortalSignDrawer.getMainColor(), PortalSignDrawer.getHighlightColor()}; List> colorMaps = new ArrayList<>(); @@ -279,10 +279,15 @@ public final class StargateGateConfig { private void loadPerSignColor(String mainSignColor, String highlightSignColor) { try { PortalSignDrawer.setMainColor(ChatColor.of(mainSignColor.toUpperCase())); + } catch (IllegalArgumentException | NullPointerException exception) { + Stargate.logWarning("You have specified an invalid main sign color in your config.yml. Defaulting to BLACK"); + PortalSignDrawer.setMainColor(ChatColor.BLACK); + } + + try { PortalSignDrawer.setHighlightColor(ChatColor.of(highlightSignColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException exception) { - Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE"); - PortalSignDrawer.setMainColor(ChatColor.BLACK); + Stargate.logWarning("You have specified an invalid highlighting sign color in your config.yml. Defaulting to WHITE"); PortalSignDrawer.setHighlightColor(ChatColor.WHITE); } } From e86be3e8483658ac8113aa7a5f31cb332cc5bd32 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 23:27:31 +0100 Subject: [PATCH 318/378] Finishes the work required for changing per-sign colors using the /sg config command --- .../stargate/command/CommandConfig.java | 184 +++++++++++++++--- .../stargate/command/ConfigTabCompleter.java | 164 +++++++++++----- .../knarcraft/stargate/config/ConfigTag.java | 5 +- 3 files changed, 269 insertions(+), 84 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 19260aa..0f6dccb 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -9,6 +9,7 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.PortalSignDrawer; import net.md_5.bungee.api.ChatColor; import org.apache.commons.lang.StringUtils; +import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -16,6 +17,9 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + /** * This command represents the config command for changing config values */ @@ -37,7 +41,11 @@ public class CommandConfig implements CommandExecutor { return false; } if (args.length > 1) { - updateConfigValue(selectedOption, commandSender, args[1]); + if (selectedOption.getDataType() == OptionDataType.STRING_LIST) { + updateListConfigValue(selectedOption, commandSender, args); + } else { + updateConfigValue(selectedOption, commandSender, args[1]); + } } else { //Display info and the current value of the given config value printConfigOptionValue(commandSender, selectedOption); @@ -72,14 +80,7 @@ public class CommandConfig implements CommandExecutor { //Store the config values, accounting for the data type switch (selectedOption.getDataType()) { - case BOOLEAN -> { - boolean newValue = Boolean.parseBoolean(value); - if (selectedOption == ConfigOption.ENABLE_BUNGEE && newValue != Stargate.getGateConfig().enableBungee()) { - Stargate.getStargateConfig().startStopBungeeListener(newValue); - } - Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, newValue); - configuration.set(selectedOption.getConfigNode(), newValue); - } + case BOOLEAN -> updateBooleanConfigValue(selectedOption, value, configuration); case INTEGER -> { Integer intValue = getInteger(commandSender, selectedOption, value); if (intValue == null) { @@ -90,35 +91,158 @@ public class CommandConfig implements CommandExecutor { } } case STRING -> { - if (selectedOption == ConfigOption.GATE_FOLDER || selectedOption == ConfigOption.PORTAL_FOLDER || - selectedOption == ConfigOption.DEFAULT_GATE_NETWORK) { - if (value.contains("../") || value.contains("..\\")) { - commandSender.sendMessage(ChatColor.RED + "Path traversal characters cannot be used"); - return; - } - } - if (ConfigTag.COLOR.isTagged(selectedOption)) { - if (!registerColor(selectedOption, value, commandSender)) { - return; - } - } - if (selectedOption == ConfigOption.LANGUAGE) { - Stargate.getStargateConfig().getLanguageLoader().setChosenLanguage(value); - } - Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); + updateStringConfigValue(selectedOption, commandSender, value); configuration.set(selectedOption.getConfigNode(), value); } - case STRING_LIST -> { - if (selectedOption == ConfigOption.PER_SIGN_COLORS) { - commandSender.sendMessage(ChatColor.RED + value); - } - } default -> { Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); configuration.set(selectedOption.getConfigNode(), value); } } + saveAndReload(selectedOption, commandSender); + } + + /** + * Updates a boolean config value + * + * @param selectedOption

The option which should be updated

+ * @param value

The new value of the config option

+ * @param configuration

The configuration file to save to

+ */ + private void updateBooleanConfigValue(ConfigOption selectedOption, String value, FileConfiguration configuration) { + boolean newValue = Boolean.parseBoolean(value); + if (selectedOption == ConfigOption.ENABLE_BUNGEE && newValue != Stargate.getGateConfig().enableBungee()) { + Stargate.getStargateConfig().startStopBungeeListener(newValue); + } + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, newValue); + configuration.set(selectedOption.getConfigNode(), newValue); + } + + /** + * Updates a string config value + * + * @param selectedOption

The option which should be updated

+ * @param commandSender

The command sender that changed the value

+ * @param value

The new value of the config option

+ */ + private void updateStringConfigValue(ConfigOption selectedOption, CommandSender commandSender, String value) { + if (selectedOption == ConfigOption.GATE_FOLDER || selectedOption == ConfigOption.PORTAL_FOLDER || + selectedOption == ConfigOption.DEFAULT_GATE_NETWORK) { + if (value.contains("../") || value.contains("..\\")) { + commandSender.sendMessage(ChatColor.RED + "Path traversal characters cannot be used"); + return; + } + } + if (ConfigTag.COLOR.isTagged(selectedOption)) { + if (!registerColor(selectedOption, value, commandSender)) { + return; + } + } + if (selectedOption == ConfigOption.LANGUAGE) { + Stargate.getStargateConfig().getLanguageLoader().setChosenLanguage(value); + } + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value); + } + + /** + * Updates a config value + * + * @param selectedOption

The option which should be updated

+ * @param commandSender

The command sender that changed the value

+ * @param arguments

The arguments for the new config option

+ */ + private void updateListConfigValue(ConfigOption selectedOption, CommandSender commandSender, String[] arguments) { + FileConfiguration configuration = Stargate.getInstance().getConfig(); + + if (selectedOption == ConfigOption.PER_SIGN_COLORS) { + if (arguments.length < 4) { + Stargate.getMessageSender().sendErrorMessage(commandSender, "Usage: /sg config perSignColors " + + " "); + return; + } + + String colorString = parsePerSignColorInput(commandSender, arguments); + if (colorString == null) { + return; + } + + //Update the per-sign colors according to input + updatePerSignColors(arguments[1], colorString, configuration); + } + + saveAndReload(selectedOption, commandSender); + } + + /** + * Parses the input given for changing the per-color string + * + * @param commandSender

The command sender that triggered the command

+ * @param arguments

The arguments given by the user

+ * @return

The per-sign color string to update with, or null if the input was invalid

+ */ + private String parsePerSignColorInput(CommandSender commandSender, String[] arguments) { + //Make sure the sign type is an actual sign + if (Material.matchMaterial(arguments[1] + "_SIGN") == null) { + Stargate.getMessageSender().sendErrorMessage(commandSender, "The given sign type is invalid"); + return null; + } + String colorString = arguments[1] + ":"; + + //Validate the colors given by the user + String[] errorMessage = new String[]{"The given main sign color is invalid!", "The given highlight sign color is invalid!"}; + String[] newColors = new String[2]; + for (int i = 0; i < 2; i++) { + if (validatePerSignColor(arguments[i + 2])) { + newColors[i] = arguments[i + 2]; + } else { + Stargate.getMessageSender().sendErrorMessage(commandSender, errorMessage[i]); + return null; + } + } + colorString += String.join(",", newColors); + return colorString; + } + + /** + * Updates the per-sign colors with the given input + * + * @param signType

The sign type that is updated

+ * @param colorString

The new color string to replace any previous value with

+ * @param configuration

The file configuration to update with the new per-sign colors

+ */ + private void updatePerSignColors(String signType, String colorString, FileConfiguration configuration) { + List newColorStrings = new ArrayList<>(); + List oldColors = (List) Stargate.getStargateConfig().getConfigOptionsReference().get(ConfigOption.PER_SIGN_COLORS); + for (Object object : oldColors) { + newColorStrings.add(String.valueOf(object)); + } + newColorStrings.removeIf((item) -> item.startsWith(signType)); + newColorStrings.add(colorString); + + Stargate.getStargateConfig().getConfigOptionsReference().put(ConfigOption.PER_SIGN_COLORS, newColorStrings); + configuration.set(ConfigOption.PER_SIGN_COLORS.getConfigNode(), newColorStrings); + } + + /** + * Tries to validate one of the colors given when changing per-sign colors + * + * @param color

The color chosen by the user

+ * @return

True if the given color is valid

+ */ + private boolean validatePerSignColor(String color) { + ChatColor newHighlightColor = parseColor(color); + return newHighlightColor != null || color.equalsIgnoreCase("default") || + color.equalsIgnoreCase("inverted"); + } + + /** + * Saves the configuration file and reloads as necessary + * + * @param selectedOption

The config option that was changed

+ * @param commandSender

The command sender that executed the config command

+ */ + private void saveAndReload(ConfigOption selectedOption, CommandSender commandSender) { //Save the config file and reload if necessary Stargate.getInstance().saveConfig(); diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index a324d39..c37de81 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -3,6 +3,8 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.config.ConfigOption; import net.knarcraft.stargate.config.OptionDataType; import net.md_5.bungee.api.ChatColor; +import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; @@ -17,15 +19,26 @@ import java.util.List; */ public class ConfigTabCompleter implements TabCompleter { + private List signTypes; + private List booleans; + private List numbers; + private List chatColors; + private List languages; + private List extendedColors; + @Nullable @Override public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - + if (signTypes == null || booleans == null || numbers == null || chatColors == null || languages == null) { + initializeAutoCompleteLists(); + } if (args.length > 1) { ConfigOption selectedOption = ConfigOption.getByName(args[0]); if (selectedOption == null) { return new ArrayList<>(); + } else if (selectedOption.getDataType() == OptionDataType.STRING_LIST) { + return getPossibleStringListOptionValues(selectedOption, args); } else { return getPossibleOptionValues(selectedOption, args[1]); } @@ -63,18 +76,10 @@ public class ConfigTabCompleter implements TabCompleter { * @return

Some or all of the valid values for the option

*/ private List getPossibleOptionValues(ConfigOption selectedOption, String typedText) { - List booleans = new ArrayList<>(); - booleans.add("true"); - booleans.add("false"); - - List numbers = new ArrayList<>(); - numbers.add("0"); - numbers.add("5"); - switch (selectedOption) { case LANGUAGE: //Return available languages - return filterMatching(getLanguages(), typedText); + return filterMatching(languages, typedText); case GATE_FOLDER: case PORTAL_FOLDER: case DEFAULT_GATE_NETWORK: @@ -88,7 +93,7 @@ public class ConfigTabCompleter implements TabCompleter { case HIGHLIGHT_SIGN_COLOR: case FREE_GATES_COLOR: //Return all colors - return filterMatching(getColors(), typedText); + return filterMatching(chatColors, typedText); } //If the config value is a boolean, show the two boolean values @@ -104,50 +109,95 @@ public class ConfigTabCompleter implements TabCompleter { return new ArrayList<>(); } } - - //TODO: What to do with per-sign colors? - return null; } /** - * Gets all available languages + * Get possible values for the selected string list option * - * @return

The available languages

+ * @param selectedOption

The selected option

+ * @param args

The arguments given by the user

+ * @return

Some or all of the valid values for the option

*/ - private List getLanguages() { - List languages = new ArrayList<>(); - languages.add("de"); - languages.add("en"); - languages.add("es"); - languages.add("fr"); - languages.add("hu"); - languages.add("it"); - languages.add("nb-no"); - languages.add("nl"); - languages.add("nn-no"); - languages.add("pt-br"); - languages.add("ru"); - return languages; - } - - /** - * Gets all available colors - * - * @return

All available colors

- */ - private List getColors() { - List colors = new ArrayList<>(); - for (ChatColor color : getChatColors()) { - colors.add(color.getName()); + private List getPossibleStringListOptionValues(ConfigOption selectedOption, String[] args) { + if (selectedOption == ConfigOption.PER_SIGN_COLORS) { + return getPerSignColorCompletion(args); + } else { + return null; } - return colors; } /** - * Gets a list of all available chat colors + * Gets the tab completion values for completing the per-sign color text * - * @return

A list of chat colors

+ * @param args

The arguments given by the user

+ * @return

The options to give the user

+ */ + private List getPerSignColorCompletion(String[] args) { + if (args.length < 3) { + return filterMatching(signTypes, args[1]); + } else if (args.length < 4) { + return filterMatching(extendedColors, args[2]); + } else if (args.length < 5) { + return filterMatching(extendedColors, args[3]); + } + return new ArrayList<>(); + } + + /** + * Puts a single string value into a string list + * + * @param value

The string to make into a list

+ * @return

A list containing the string value

+ */ + private List putStringInList(String value) { + List list = new ArrayList<>(); + list.add(value); + return list; + } + + /** + * Initializes all lists of auto-completable values + */ + private void initializeAutoCompleteLists() { + booleans = new ArrayList<>(); + booleans.add("true"); + booleans.add("false"); + + numbers = new ArrayList<>(); + numbers.add("0"); + numbers.add("5"); + + signTypes = new ArrayList<>(); + for (Material material : Material.values()) { + if (Tag.STANDING_SIGNS.isTagged(material)) { + signTypes.add(material.toString().replace("_SIGN", "")); + } + } + + getColors(); + initializeLanguages(); + + extendedColors = new ArrayList<>(chatColors); + extendedColors.add("default"); + extendedColors.add("inverted"); + } + + + /** + * Initializes the list of chat colors + */ + private void getColors() { + chatColors = new ArrayList<>(); + for (ChatColor color : getChatColors()) { + chatColors.add(color.getName()); + } + } + + /** + * Gets available chat colors + * + * @return

The available chat colors

*/ private List getChatColors() { List chatColors = new ArrayList<>(); @@ -167,19 +217,29 @@ public class ConfigTabCompleter implements TabCompleter { chatColors.add(ChatColor.DARK_GRAY); chatColors.add(ChatColor.GRAY); chatColors.add(ChatColor.YELLOW); + chatColors.add(ChatColor.of("#ed76d9")); + chatColors.add(ChatColor.of("#ffecb7")); return chatColors; } /** - * Puts a single string value into a string list - * - * @param value

The string to make into a list

- * @return

A list containing the string value

+ * Initializes the list of all available languages */ - private List putStringInList(String value) { - List list = new ArrayList<>(); - list.add(value); - return list; + private void initializeLanguages() { + languages = new ArrayList<>(); + languages.add("de"); + languages.add("en"); + languages.add("es"); + languages.add("fr"); + languages.add("hu"); + languages.add("it"); + languages.add("nb-no"); + languages.add("nl"); + languages.add("nn-no"); + languages.add("pt-br"); + languages.add("ru"); + //TODO: Generate this list dynamically by listing the language files in the jar and adding the user's custom + // language files } } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java index 95dea52..49c9083 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java @@ -7,7 +7,8 @@ import java.util.Arrays; */ public enum ConfigTag { - COLOR(new ConfigOption[]{ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, ConfigOption.HIGHLIGHT_SIGN_COLOR}), + COLOR(new ConfigOption[]{ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, + ConfigOption.HIGHLIGHT_SIGN_COLOR, ConfigOption.PER_SIGN_COLORS}), FOLDER(new ConfigOption[]{ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER}); private final ConfigOption[] taggedOptions; @@ -38,7 +39,7 @@ public enum ConfigTag { * @return

True if changing the config option requires a "reload of colors" to take effect

*/ public static boolean requiresColorReload(ConfigOption configOption) { - return COLOR.isTagged(configOption) && configOption != ConfigOption.FREE_GATES_COLOR; + return (COLOR.isTagged(configOption) && configOption != ConfigOption.FREE_GATES_COLOR); } /** From a74d47e99911a8063b34e387680787134632f75f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 23:37:34 +0100 Subject: [PATCH 319/378] Makes sure default config values are stored with comments on the first run --- src/main/java/net/knarcraft/stargate/Stargate.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 4da5074..7b4355f 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -339,6 +339,9 @@ public class Stargate extends JavaPlugin { PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); FileConfiguration newConfig = this.getConfig(); + this.saveDefaultConfig(); + newConfig.options().copyDefaults(true); + logger = Logger.getLogger("Minecraft"); Server server = getServer(); stargate = this; From 043c5f2408ae3470c3696d7bb72f9122b561660d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Jan 2022 23:41:05 +0100 Subject: [PATCH 320/378] Updates README and version to 0.9.3.0 --- README.md | 2 ++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 200af46..d2aafba 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,8 @@ portalInfoServer=Server: %server% - Adds support for RGB colors (use hex color codes) - Adds support for dyed and glowing signs - Adds support for specifying sign colors per sign type +- Adds a tab-completable config sub-command for easily changing per-sign colors +- Allows a per-sign color to be set as the inverse of the default color of the given type #### \[Version 0.9.2.5] EpicKnarvik97 fork diff --git a/pom.xml b/pom.xml index 7f2e650..1608dde 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.2.5 + 0.9.3.0 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ac9be07..025c46d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.2.5 +version: 0.9.3.0 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 29fdc8f849d34efd634a9f4e2b31611892f14c0d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 00:44:31 +0100 Subject: [PATCH 321/378] Adds a new feature to the README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d2aafba..e40c91d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ can share a network or be split into clusters; they can be hidden on a network o - **API available** -- using the API, a lot of behavior can be changed - **Button customization** -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests) - **Config commands** -- All main config values can be changed from the commandline +- **Color customization** -- Stargate signs can be colored in many ways. Colors can be set globally, or on a per sign + type basis - **RGB and dye support** -- Signs can use RGB colors (using hex codes) as their main and highlighting colors, and can also be dyed on a per-sign basis From 62952611b8316670ce28f585677eb847cfbfe309 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 00:58:42 +0100 Subject: [PATCH 322/378] Ignores the type of air when verifying a stargate's opening --- .../java/net/knarcraft/stargate/portal/property/gate/Gate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index 684b6d2..bfde5e4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -235,7 +235,7 @@ public class Gate { Material type = topLeft.getRelativeLocation(entranceVector, yaw).getType(); //Ignore entrance if it's air or water, and we're creating a new gate - if (onCreate && (type == Material.AIR || type == Material.WATER)) { + if (onCreate && (type.isAir() || type == Material.WATER)) { continue; } From d9f535cd07f4264f9cb98ad37120cabea1c8eeb8 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 00:59:45 +0100 Subject: [PATCH 323/378] Updates README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e40c91d..ae308f4 100644 --- a/README.md +++ b/README.md @@ -396,6 +396,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.1] EpicKnarvik97 fork + +- Ignores the type of air when checking if a stargate is valid + #### \[Version 0.9.3.0] EpicKnarvik97 fork - Adds support for RGB colors (use hex color codes) From 05a5fb2160204cad0b53dfd46d5005dfe61637f7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 01:32:49 +0100 Subject: [PATCH 324/378] Updates version to 0.9.3.1 --- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1608dde..2dfda2c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.0 + 0.9.3.1 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 025c46d..6460692 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.0 +version: 0.9.3.1 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From bddf8c55d549d3f30d5ce184f37558d2e6dc3b3f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 05:15:43 +0100 Subject: [PATCH 325/378] Adds an option for setting the exit velocity of a teleporting player --- .../stargate/command/CommandConfig.java | 33 +++++++++++++++++++ .../stargate/command/ConfigTabCompleter.java | 28 ++++++++++++---- .../stargate/config/ConfigOption.java | 8 ++++- .../stargate/config/OptionDataType.java | 21 +++++++++--- .../stargate/config/StargateConfig.java | 1 + .../stargate/config/StargateGateConfig.java | 9 +++++ .../portal/teleporter/PlayerTeleporter.java | 13 +++++++- src/main/resources/config.yml | 2 ++ 8 files changed, 102 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 0f6dccb..ca2f2fa 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -90,6 +90,15 @@ public class CommandConfig implements CommandExecutor { configuration.set(selectedOption.getConfigNode(), intValue); } } + case DOUBLE -> { + Double doubleValue = getDouble(commandSender, selectedOption, value); + if (doubleValue == null) { + return; + } else { + Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, doubleValue); + configuration.set(selectedOption.getConfigNode(), doubleValue); + } + } case STRING -> { updateStringConfigValue(selectedOption, commandSender, value); configuration.set(selectedOption.getConfigNode(), value); @@ -314,6 +323,30 @@ public class CommandConfig implements CommandExecutor { } } + /** + * Gets a double from a string + * + * @param commandSender

The command sender that sent the config command

+ * @param selectedOption

The option the command sender is trying to change

+ * @param value

The value given

+ * @return

A double, or null if it was invalid

+ */ + private Double getDouble(CommandSender commandSender, ConfigOption selectedOption, String value) { + try { + double doubleValue = Double.parseDouble(value); + + if (selectedOption == ConfigOption.EXIT_VELOCITY && doubleValue < 0) { + commandSender.sendMessage(ChatColor.RED + "This config option cannot be negative."); + return null; + } + + return doubleValue; + } catch (NumberFormatException exception) { + commandSender.sendMessage(ChatColor.RED + "Invalid number given"); + return null; + } + } + /** * Reloads the config if necessary * diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index c37de81..693fc26 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -21,16 +21,17 @@ public class ConfigTabCompleter implements TabCompleter { private List signTypes; private List booleans; - private List numbers; + private List integers; private List chatColors; private List languages; private List extendedColors; + private List doubles; @Nullable @Override public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - if (signTypes == null || booleans == null || numbers == null || chatColors == null || languages == null) { + if (signTypes == null || booleans == null || integers == null || chatColors == null || languages == null) { initializeAutoCompleteLists(); } if (args.length > 1) { @@ -104,7 +105,16 @@ public class ConfigTabCompleter implements TabCompleter { //If the config value is an integer, display some valid numbers if (selectedOption.getDataType() == OptionDataType.INTEGER) { if (typedText.trim().isEmpty()) { - return numbers; + return integers; + } else { + return new ArrayList<>(); + } + } + + //If the config value is a double, display some valid numbers + if (selectedOption.getDataType() == OptionDataType.DOUBLE) { + if (typedText.trim().isEmpty()) { + return doubles; } else { return new ArrayList<>(); } @@ -164,9 +174,9 @@ public class ConfigTabCompleter implements TabCompleter { booleans.add("true"); booleans.add("false"); - numbers = new ArrayList<>(); - numbers.add("0"); - numbers.add("5"); + integers = new ArrayList<>(); + integers.add("0"); + integers.add("5"); signTypes = new ArrayList<>(); for (Material material : Material.values()) { @@ -181,6 +191,12 @@ public class ConfigTabCompleter implements TabCompleter { extendedColors = new ArrayList<>(chatColors); extendedColors.add("default"); extendedColors.add("inverted"); + + doubles = new ArrayList<>(); + doubles.add("5"); + doubles.add("1"); + doubles.add("0.5"); + doubles.add("0.1"); } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 76d3870..2169d14 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -156,8 +156,12 @@ public enum ConfigOption { /** * Whether to alert admins about new updates */ - ADMIN_UPDATE_ALERT("adminUpdateAlert", "Whether to alert admins about new plugin updates", true); + ADMIN_UPDATE_ALERT("adminUpdateAlert", "Whether to alert admins about new plugin updates", true), + /** + * The velocity of players exiting a stargate, relative to the entry velocity + */ + EXIT_VELOCITY("gates.exitVelocity", "The velocity of players exiting stargates, relative to the entry velocity", 0.1D); private final String configNode; private final String description; @@ -184,6 +188,8 @@ public enum ConfigOption { this.dataType = OptionDataType.BOOLEAN; } else if (defaultValue instanceof Integer) { this.dataType = OptionDataType.INTEGER; + } else if (defaultValue instanceof Double) { + this.dataType = OptionDataType.DOUBLE; } else { throw new IllegalArgumentException("Unknown config data type encountered: " + defaultValue); } diff --git a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java index 5cb8bee..25fcf76 100644 --- a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java +++ b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java @@ -6,17 +6,28 @@ package net.knarcraft.stargate.config; public enum OptionDataType { /** - * The data type for the option is a String + * The data type if the option is a String */ STRING, + /** - * The data type for the option is a Boolean + * The data type if the option is a Boolean */ BOOLEAN, - STRING_LIST, + /** - * The data type for the option is an Integer + * The data type if the option is a string list */ - INTEGER + STRING_LIST, + + /** + * The data type if the option is an Integer + */ + INTEGER, + + /** + * The data type if the option is a double + */ + DOUBLE } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 346bb4d..d8acd65 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -358,6 +358,7 @@ public final class StargateConfig { } case BOOLEAN -> optionValue = newConfig.getBoolean(configNode); case INTEGER -> optionValue = newConfig.getInt(configNode); + case DOUBLE -> optionValue = newConfig.getDouble(configNode); default -> throw new IllegalArgumentException("Invalid config data type encountered"); } configOptions.put(option, optionValue); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 001ced9..1e19865 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -179,6 +179,15 @@ public final class StargateGateConfig { return (String) configOptions.get(ConfigOption.DEFAULT_GATE_NETWORK); } + /** + * Gets the exit velocity of players using stargates, relative to the entry velocity + * + * @return

The relative exit velocity

+ */ + public double getExitVelocity() { + return (double) configOptions.get(ConfigOption.EXIT_VELOCITY); + } + /** * Loads all config values related to gates */ diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index e8232bb..57d6e6d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -3,9 +3,12 @@ package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargatePlayerPortalEvent; import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.utility.DirectionHelper; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; /** * The portal teleporter takes care of the actual portal teleportation for any players @@ -32,6 +35,7 @@ public class PlayerTeleporter extends Teleporter { * @param event

The player move event triggering the event

*/ public void teleport(Portal origin, PlayerMoveEvent event) { + double velocity = player.getVelocity().length(); Location traveller = player.getLocation(); Location exit = getExit(player, traveller); @@ -56,9 +60,16 @@ public class PlayerTeleporter extends Teleporter { if (event == null) { player.teleport(exit); } else { - //The new method to teleport in a move event is set the "to" field. + //Set the exit location of the event event.setTo(exit); } + + //Set the velocity of the teleported player after the teleportation is finished + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> { + Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); + Vector newVelocity = newVelocityDirection.multiply(velocity * Stargate.getGateConfig().getExitVelocity()); + player.setVelocity(newVelocity); + }, 1); } /** diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 46d18d2..9775000 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -15,6 +15,8 @@ gates: maxGatesEachNetwork: 0 # defaultGateNetwork - The default gate network defaultGateNetwork: central + # exitVelocity - The velocity of players exiting stargates, relative to the entry velocity + exitVelocity: 0.1 cosmetic: # rememberDestination - Whether to remember the cursor location between uses rememberDestination: false From 1e06e0e01dc191ea31fd13af44bbf7adc0372814 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 21:35:04 +0100 Subject: [PATCH 326/378] Fixes some rotation problems for teleported passengers --- .../portal/teleporter/VehicleTeleporter.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 87c3288..1215616 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -165,7 +165,7 @@ public class VehicleTeleporter extends EntityTeleporter { private void teleportLivingVehicle(Location exit, List passengers, Portal origin) { teleportingVehicle.eject(); teleportingVehicle.teleport(exit); - handleVehiclePassengers(passengers, teleportingVehicle, 2, origin); + handleVehiclePassengers(passengers, teleportingVehicle, 2, origin, exit.getDirection()); } /** @@ -194,19 +194,20 @@ public class VehicleTeleporter extends EntityTeleporter { teleportingVehicle.remove(); //Set rotation, add passengers and restore velocity newVehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle, 1, origin); + handleVehiclePassengers(passengers, newVehicle, 1, origin, exit.getDirection()); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> newVehicle.setVelocity(newVelocity), 1); } /** * Ejects, teleports and adds all passengers to the target vehicle * - * @param passengers

The passengers to handle

- * @param vehicle

The vehicle the passengers should be put into

- * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

- * @param origin

The portal the vehicle teleported from

+ * @param passengers

The passengers to handle

+ * @param vehicle

The vehicle the passengers should be put into

+ * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

+ * @param origin

The portal the vehicle teleported from

+ * @param exitRotation

The rotation of any passengers exiting the stargate

*/ - private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay, Portal origin) { + private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay, Portal origin, Vector exitRotation) { for (Entity passenger : passengers) { passenger.eject(); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { @@ -214,7 +215,7 @@ public class VehicleTeleporter extends EntityTeleporter { //Teleport any creatures leashed by the player in a 15-block range teleportLeashedCreatures(player, origin); } - teleportAndAddPassenger(vehicle, passenger); + teleportAndAddPassenger(vehicle, passenger, exitRotation); }, delay); } } @@ -227,9 +228,10 @@ public class VehicleTeleporter extends EntityTeleporter { * * @param targetVehicle

The vehicle to add the passenger to

* @param passenger

The passenger to teleport and add

+ * @param exitDirection

The direction of any passengers exiting the stargate

*/ - private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) { - if (!passenger.teleport(targetVehicle.getLocation())) { + private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger, Vector exitDirection) { + if (!passenger.teleport(targetVehicle.getLocation().clone().setDirection(exitDirection))) { Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); } if (!targetVehicle.addPassenger(passenger)) { From f95ee0b85d0326103d38594433d5df01f96fbcc0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 21:35:40 +0100 Subject: [PATCH 327/378] Reduces the outwards offset of teleported entities --- .../stargate/portal/teleporter/Teleporter.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 5ffd9f4..77e7845 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -13,7 +13,6 @@ import org.bukkit.Material; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Slab; -import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -59,7 +58,7 @@ public abstract class Teleporter { } float newYaw = (portal.getYaw() + adjust) % 360; Stargate.debug("Portal::adjustRotation", "Setting exit yaw to " + newYaw); - exit.setYaw(newYaw); + exit.setDirection(DirectionHelper.getDirectionVectorFromYaw(newYaw)); } /** @@ -141,14 +140,9 @@ public abstract class Teleporter { if (entitySize > 1) { double entityOffset; if (portal.getOptions().isAlwaysOn()) { - entityOffset = entityBoxSize / 2D; + entityOffset = (entityBoxSize / 2D) - 1; } else { - entityOffset = (entitySize / 2D) - 1; - } - //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's - // moved one block out. - if (entity instanceof AbstractHorse) { - entityOffset += 1; + entityOffset = (entitySize / 2D) - 2; } exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, entityOffset, portal.getYaw()); } @@ -217,8 +211,8 @@ public abstract class Teleporter { protected void loadChunks() { for (Chunk chunk : getChunksToLoad()) { chunk.addPluginChunkTicket(Stargate.getInstance()); - //Allow the chunk to unload after 3 seconds - Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L)); + //Allow the chunk to unload after 10 seconds + Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 10000L)); } } From 2bf5422b2a9c75d257c0a5977bee8d2e2dcf3c9c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 21:37:59 +0100 Subject: [PATCH 328/378] Updates README with recent changes --- README.md | 7 +++++++ src/main/resources/config.yml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ae308f4..5a6fb62 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,7 @@ folders: gates: maxGatesEachNetwork - If non-zero, will define the maximum amount of gates allowed on any network. defaultGateNetwork - The default gate network + exitVelocity - The velocity to give players exiting stargates, relative to the entry velocity (1 = same as entry velocity) cosmetic: rememberDestination - Whether to set the first destination as the last used destination for all gates sortNetworkDestinations - If true, network lists will be sorted alphabetically. @@ -396,6 +397,12 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.2] EpicKnarvik97 fork + +- Adds a config option to set the exit velocity of any players exiting a stargate +- Adjusts vehicle teleportation a bit to prevent passengers' exit rotation from being wrong +- Reduces the outwards offset of teleported entities + #### \[Version 0.9.3.1] EpicKnarvik97 fork - Ignores the type of air when checking if a stargate is valid diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9775000..e3ad5a8 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -15,7 +15,7 @@ gates: maxGatesEachNetwork: 0 # defaultGateNetwork - The default gate network defaultGateNetwork: central - # exitVelocity - The velocity of players exiting stargates, relative to the entry velocity + # exitVelocity - The velocity to give players exiting stargates, relative to the entry velocity exitVelocity: 0.1 cosmetic: # rememberDestination - Whether to remember the cursor location between uses From f6438eb87278ba4baf4006ad07ffbd3952799ed2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 21:39:13 +0100 Subject: [PATCH 329/378] Updates the plugin version to 0.9.3.2 --- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2dfda2c..ef2c4d7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.1 + 0.9.3.2 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6460692..14ee468 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.1 +version: 0.9.3.2 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From f70ba24e9531376f0730d7582bfebe4a6970b187 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 21:56:19 +0100 Subject: [PATCH 330/378] Un-does the outwards offset reduction for teleported entities --- README.md | 1 - .../stargate/portal/teleporter/Teleporter.java | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5a6fb62..1e0b6a6 100644 --- a/README.md +++ b/README.md @@ -401,7 +401,6 @@ portalInfoServer=Server: %server% - Adds a config option to set the exit velocity of any players exiting a stargate - Adjusts vehicle teleportation a bit to prevent passengers' exit rotation from being wrong -- Reduces the outwards offset of teleported entities #### \[Version 0.9.3.1] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 77e7845..4773902 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -13,6 +13,7 @@ import org.bukkit.Material; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Slab; +import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -140,9 +141,14 @@ public abstract class Teleporter { if (entitySize > 1) { double entityOffset; if (portal.getOptions().isAlwaysOn()) { - entityOffset = (entityBoxSize / 2D) - 1; + entityOffset = (entityBoxSize / 2D); } else { - entityOffset = (entitySize / 2D) - 2; + entityOffset = (entitySize / 2D) - 1; + } + //If a horse has a player riding it, the player will spawn inside the roof of a standard portal unless it's + // moved one block out. + if (entity instanceof AbstractHorse) { + entityOffset += 1; } exitLocation = DirectionHelper.moveLocation(exitLocation, 0, 0, entityOffset, portal.getYaw()); } From a3ed1058e65c9f3265869150656ba04362c97fd4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 27 Jan 2022 22:20:38 +0100 Subject: [PATCH 331/378] Improves the double click prevention by accounting for heavy concurrent usage and server lag --- README.md | 1 + .../listener/PlayerEventListener.java | 24 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1e0b6a6..ce8d504 100644 --- a/README.md +++ b/README.md @@ -401,6 +401,7 @@ portalInfoServer=Server: %server% - Adds a config option to set the exit velocity of any players exiting a stargate - Adjusts vehicle teleportation a bit to prevent passengers' exit rotation from being wrong +- Improves the checking for buggy double-clicks on non-button blocks #### \[Version 0.9.3.1] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index b182690..8261673 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -34,14 +34,16 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import java.util.HashMap; +import java.util.Map; + /** * This listener listens to any player-related events related to stargates */ @SuppressWarnings("unused") public class PlayerEventListener implements Listener { - private static long eventTime; - private static PlayerInteractEvent previousEvent; + private static final Map previousEventTimes = new HashMap<>(); /** * This event handler handles detection of any player teleporting through a bungee gate @@ -295,7 +297,7 @@ public class PlayerEventListener implements Listener { } //Prevent a double click caused by a Spigot bug - if (clickIsBug(event, block)) { + if (clickIsBug(event.getPlayer(), block)) { return; } @@ -366,19 +368,17 @@ public class PlayerEventListener implements Listener { * immediately, or causing portal information printing twice. This fix should detect the bug without breaking * clicking once the bug is fixed.

* - * @param event

The event causing the right click

- * @param block

The block to check

+ * @param player

The player performing the right-click

+ * @param block

The block to check

* @return

True if the click is a bug and should be cancelled

*/ - private boolean clickIsBug(PlayerInteractEvent event, Block block) { - if (previousEvent != null && - event.getPlayer() == previousEvent.getPlayer() && eventTime + 15 > System.currentTimeMillis()) { - previousEvent = null; - eventTime = 0; + private boolean clickIsBug(Player player, Block block) { + Long previousEventTime = previousEventTimes.get(player); + if (previousEventTime != null && previousEventTime + 50 > System.currentTimeMillis()) { + previousEventTimes.put(player, null); return true; } - previousEvent = event; - eventTime = System.currentTimeMillis(); + previousEventTimes.put(player, System.currentTimeMillis()); return false; } From 5e79df9f448978b2c9ab8fe0bea13b6232ad768c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 28 Jan 2022 00:13:00 +0100 Subject: [PATCH 332/378] Adds an entity spawn listener for preventing Zombified Piglin spawns --- .../java/net/knarcraft/stargate/Stargate.java | 2 ++ .../listener/EntitySpawnListener.java | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 7b4355f..7cb5415 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.listener.BlockEventListener; import net.knarcraft.stargate.listener.EntityEventListener; +import net.knarcraft.stargate.listener.EntitySpawnListener; import net.knarcraft.stargate.listener.PlayerEventListener; import net.knarcraft.stargate.listener.PluginEventListener; import net.knarcraft.stargate.listener.PortalEventListener; @@ -388,6 +389,7 @@ public class Stargate extends JavaPlugin { pluginManager.registerEvents(new WorldEventListener(), this); pluginManager.registerEvents(new PluginEventListener(this), this); pluginManager.registerEvents(new TeleportEventListener(), this); + pluginManager.registerEvents(new EntitySpawnListener(), this); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java b/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java new file mode 100644 index 0000000..b4c0b2c --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java @@ -0,0 +1,25 @@ +package net.knarcraft.stargate.listener; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.PortalHandler; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; + +/** + * A listener that listens for any relevant events causing entities to spawn + */ +public class EntitySpawnListener implements Listener { + + @EventHandler + public void onCreatureSpawn(CreatureSpawnEvent event) { + //Prevent Zombified Piglins and other creatures form spawning at stargates + if (event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.NETHER_PORTAL) { + if (PortalHandler.getByEntrance(event.getLocation()) != null) { + event.setCancelled(true); + Stargate.debug("EntitySpawnListener", "Prevented creature from spawning at Stargate"); + } + } + } + +} From 8a5c094ce100e1f3d17e0c0440042c5b280c0a9a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 28 Jan 2022 00:13:32 +0100 Subject: [PATCH 333/378] Updates README with changes and version to 0.9.3.3 --- README.md | 4 ++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce8d504..691ffe7 100644 --- a/README.md +++ b/README.md @@ -397,6 +397,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.3] EpicKnarvik97 fork + +- Prevents Zombified Piglins from randomly spawning at Stargates + #### \[Version 0.9.3.2] EpicKnarvik97 fork - Adds a config option to set the exit velocity of any players exiting a stargate diff --git a/pom.xml b/pom.xml index ef2c4d7..ec9c840 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.2 + 0.9.3.3 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 14ee468..0a9a6ed 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.2 +version: 0.9.3.3 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 95293204d5b519309e121ed52c584b1c00a90502 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 28 Jan 2022 22:58:02 +0100 Subject: [PATCH 334/378] Adds a new StargateTeleportEvent to combine some duplicated code --- .../event/StargateEntityPortalEvent.java | 3 ++- .../event/StargatePlayerPortalEvent.java | 3 ++- .../stargate/event/StargateTeleportEvent.java | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java index 0cf3448..cd34504 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java @@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull; *

This event can be used to overwrite the location the entity is teleported to.

*/ @SuppressWarnings("unused") -public class StargateEntityPortalEvent extends StargateEvent { +public class StargateEntityPortalEvent extends StargateEvent implements StargateTeleportEvent { private static final HandlerList handlers = new HandlerList(); final Entity travellingEntity; @@ -58,6 +58,7 @@ public class StargateEntityPortalEvent extends StargateEvent { * * @return

Location of the exit point

*/ + @Override public Location getExit() { return exit; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java index 05d474b..3d2526a 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java @@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull; *

This event can be used to overwrite the location the player is teleported to.

*/ @SuppressWarnings("unused") -public class StargatePlayerPortalEvent extends StargatePlayerEvent { +public class StargatePlayerPortalEvent extends StargatePlayerEvent implements StargateTeleportEvent { private static final HandlerList handlers = new HandlerList(); private final Portal destination; @@ -47,6 +47,7 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent { * * @return

Location of the exit point

*/ + @Override public Location getExit() { return exit; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java new file mode 100644 index 0000000..e440828 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java @@ -0,0 +1,18 @@ +package net.knarcraft.stargate.event; + +import org.bukkit.Location; +import org.bukkit.event.Cancellable; + +/** + * A generic teleportation event + */ +public interface StargateTeleportEvent extends Cancellable { + + /** + * Return the location of the players exit point + * + * @return

Location of the exit point

+ */ + Location getExit(); + +} From 7f08763624f8238da0a073f04dd037cddbc76147 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 28 Jan 2022 23:23:09 +0100 Subject: [PATCH 335/378] Changes a lot of teleportation code to be able to teleport entities with passengers Moves some teleportation code to the TeleportHelper class Changes some teleportation method names Tries to reduce some code duplication between teleporters Recursively teleports entities to make sure the teleported entity will arrive in the same shape it entered as Makes player checks for teleported vehicles account for any number of players riding any entity in the stack --- .../listener/PlayerEventListener.java | 8 +- .../listener/VehicleEventListener.java | 94 ++++--- .../portal/teleporter/EntityTeleporter.java | 48 +--- .../portal/teleporter/PlayerTeleporter.java | 48 ++-- .../portal/teleporter/Teleporter.java | 244 +++++++++--------- .../portal/teleporter/VehicleTeleporter.java | 113 ++------ .../stargate/utility/BungeeHelper.java | 2 +- .../stargate/utility/PermissionHelper.java | 4 +- .../stargate/utility/TeleportHelper.java | 199 ++++++++++++++ 9 files changed, 407 insertions(+), 353 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 8261673..4076be2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -7,11 +7,11 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalActivator; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; -import net.knarcraft.stargate.portal.teleporter.Teleporter; import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.TeleportHelper; import net.knarcraft.stargate.utility.UUIDMigrationHelper; import net.knarcraft.stargate.utility.UpdateChecker; import net.md_5.bungee.api.ChatColor; @@ -131,10 +131,10 @@ public class PlayerEventListener implements Listener { horse.setOwner(player); } //Teleport the player's vehicle - new VehicleTeleporter(destination, (Vehicle) playerVehicle).teleport(entrancePortal); + new VehicleTeleporter(destination, (Vehicle) playerVehicle).teleportEntity(entrancePortal); } else { //Just teleport the player like normal - new PlayerTeleporter(destination, player).teleport(entrancePortal, event); + new PlayerTeleporter(destination, player).teleportPlayer(entrancePortal, event); } if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); @@ -185,7 +185,7 @@ public class PlayerEventListener implements Listener { } //Make sure to check if the player has any leashed creatures, even though leashed teleportation is disabled - return Teleporter.noLeashedCreaturesPreventTeleportation(player); + return TeleportHelper.noLeashedCreaturesPreventTeleportation(player); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 0b263a2..d6d2a52 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,11 +3,11 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; -import net.knarcraft.stargate.portal.teleporter.Teleporter; import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.TeleportHelper; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; @@ -62,11 +62,11 @@ public class VehicleEventListener implements Listener { private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { String route = "VehicleEventListener::teleportVehicle"; - if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { + if (!passengers.isEmpty() && TeleportHelper.containsPlayer(passengers)) { Stargate.debug(route, "Found passenger vehicle"); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Stargate.debug(route, "Found empty vehicle"); + Stargate.debug(route, "Found vehicle without players"); Portal destinationPortal = entrancePortal.getPortalActivator().getDestination(); if (destinationPortal == null) { Stargate.debug(route, "Unable to find portal destination"); @@ -74,7 +74,7 @@ public class VehicleEventListener implements Listener { } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); - new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); + new VehicleTeleporter(destinationPortal, vehicle).teleportEntity(entrancePortal); } } @@ -86,66 +86,62 @@ public class VehicleEventListener implements Listener { * @param passengers

Any entities sitting in the minecart

*/ private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { - Player player = (Player) passengers.get(0); - //On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open - // to one player at a time, we only need to check if the portal is open to the driver. - if (!entrancePortal.getPortalOpener().isOpenFor(player)) { - if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + List players = TeleportHelper.getPlayers(passengers); + Portal destinationPortal = null; + + for (Player player : players) { + //The entrance portal must be open for one player for the teleportation to happen + if (!entrancePortal.getPortalOpener().isOpenFor(player)) { + continue; } - return; - } - //If no destination exists, the teleportation cannot happen - Portal destinationPortal = entrancePortal.getPortalActivator().getDestination(player); - if (destinationPortal == null) { - return; - } - - //Make sure all player passengers are allowed to, and can afford to, enter the portal - for (Entity entity : passengers) { - if (entity instanceof Player && !playerCanTeleport((Player) entity, entrancePortal, destinationPortal)) { - return; + //Check if any of the players has selected the destination + Portal possibleDestinationPortal = entrancePortal.getPortalActivator().getDestination(player); + if (possibleDestinationPortal != null) { + destinationPortal = possibleDestinationPortal; } } - //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be - // run after it has been confirmed that all passengers are able to pay - int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); - if (cost > 0) { - if (!takePlayerPayment(passengers, entrancePortal, cost)) { - return; + //Cancel the teleport if no players activated the portal, or if any players are denied access + boolean cancelTeleport = false; + for (Player player : players) { + if (destinationPortal == null) { + cancelTeleport = true; + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); + } + } else if (!playerCanTeleport(player, entrancePortal, destinationPortal)) { + cancelTeleport = true; + } + } + if (cancelTeleport) { + return; + } + + //Take payment from all players + for (Player player : players) { + //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be + // run after it has been confirmed that all passengers are able to pay + int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); + if (cost > 0) { + if (EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost)) { + return; + } } } //Teleport the vehicle and inform the user if the vehicle was teleported - boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal); + boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleportEntity(entrancePortal); if (teleported) { if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + for (Player player : players) { + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + } } entrancePortal.getPortalOpener().closePortal(false); } } - /** - * Takes payment from all player passengers - * - * @param passengers

All passengers in the teleporting vehicle

- * @param entrancePortal

The portal the vehicle is entering from

- * @param cost

The cost each player has to pay

- * @return

True if all player passengers paid successfully

- */ - private static boolean takePlayerPayment(List passengers, Portal entrancePortal, int cost) { - for (Entity entity : passengers) { - //If the passenger is a player, make it pay - if (entity instanceof Player && EconomyHelper.cannotPayTeleportFee(entrancePortal, (Player) entity, cost)) { - return false; - } - } - return true; - } - /** * Checks whether the given player is allowed to and can afford to teleport * @@ -174,7 +170,7 @@ public class VehicleEventListener implements Listener { return false; } - return Teleporter.noLeashedCreaturesPreventTeleportation(player); + return TeleportHelper.noLeashedCreaturesPreventTeleportation(player); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java index df12f74..e963c92 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java @@ -1,9 +1,7 @@ package net.knarcraft.stargate.portal.teleporter; -import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateEntityPortalEvent; import net.knarcraft.stargate.portal.Portal; -import org.bukkit.Location; import org.bukkit.entity.Entity; /** @@ -16,10 +14,10 @@ public class EntityTeleporter extends Teleporter { /** * Instantiates a new portal teleporter * - * @param portal

The portal which is the target of the teleportation

+ * @param targetPortal

The portal which is the target of the teleportation

*/ - public EntityTeleporter(Portal portal, Entity teleportingEntity) { - super(portal); + public EntityTeleporter(Portal targetPortal, Entity teleportingEntity) { + super(targetPortal, teleportingEntity); this.teleportingEntity = teleportingEntity; } @@ -29,44 +27,8 @@ public class EntityTeleporter extends Teleporter { * @param origin

The portal the entity is teleporting from

* @return

True if the entity was teleported. False otherwise

*/ - public boolean teleport(Portal origin) { - Location traveller = teleportingEntity.getLocation(); - Location exit = getExit(teleportingEntity, traveller); - - //Rotate the entity to face out from the portal - adjustRotation(exit); - - //Call the StargateEntityPortalEvent to allow plugins to change destination - if (!origin.equals(portal)) { - exit = triggerEntityPortalEvent(origin, exit); - if (exit == null) { - return false; - } - } - - //Load chunks to make sure not to teleport to the void - loadChunks(); - - teleportingEntity.teleport(exit); - return true; + public boolean teleportEntity(Portal origin) { + return teleport(origin, new StargateEntityPortalEvent(teleportingEntity, origin, portal, exit)); } - /** - * Triggers the entity portal event to allow plugins to change the exit location - * - * @param origin

The origin portal teleported from

- * @param exit

The exit location to teleport the entity to

- * @return

The location the entity should be teleported to, or null if the event was cancelled

- */ - protected Location triggerEntityPortalEvent(Portal origin, Location exit) { - StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingEntity, origin, - portal, exit); - Stargate.getInstance().getServer().getPluginManager().callEvent(stargateEntityPortalEvent); - //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake - if (stargateEntityPortalEvent.isCancelled()) { - new EntityTeleporter(origin, teleportingEntity).teleport(origin); - return null; - } - return stargateEntityPortalEvent.getExit(); - } } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index 57d6e6d..12b7f55 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -4,12 +4,15 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargatePlayerPortalEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.utility.DirectionHelper; +import net.knarcraft.stargate.utility.TeleportHelper; import org.bukkit.Bukkit; -import org.bukkit.Location; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.util.Vector; +import java.util.List; + /** * The portal teleporter takes care of the actual portal teleportation for any players */ @@ -20,11 +23,11 @@ public class PlayerTeleporter extends Teleporter { /** * Instantiates a new player teleporter * - * @param portal

The portal which is the target of the teleportation

- * @param player

The teleporting player

+ * @param targetPortal

The portal which is the target of the teleportation

+ * @param player

The teleporting player

*/ - public PlayerTeleporter(Portal portal, Player player) { - super(portal); + public PlayerTeleporter(Portal targetPortal, Player player) { + super(targetPortal, player); this.player = player; } @@ -34,17 +37,13 @@ public class PlayerTeleporter extends Teleporter { * @param origin

The portal the player teleports from

* @param event

The player move event triggering the event

*/ - public void teleport(Portal origin, PlayerMoveEvent event) { + public void teleportPlayer(Portal origin, PlayerMoveEvent event) { double velocity = player.getVelocity().length(); - Location traveller = player.getLocation(); - Location exit = getExit(player, traveller); - - //Rotate the player to face out from the portal - adjustRotation(exit); + List passengers = player.getPassengers(); //Call the StargatePlayerPortalEvent to allow plugins to change destination if (!origin.equals(portal)) { - exit = triggerPlayerPortalEvent(origin, exit, event); + exit = triggerPortalEvent(origin, new StargatePlayerPortalEvent(player, origin, portal, exit)); if (exit == null) { return; } @@ -54,7 +53,11 @@ public class PlayerTeleporter extends Teleporter { loadChunks(); //Teleport any creatures leashed by the player in a 15-block range - teleportLeashedCreatures(player, origin); + TeleportHelper.teleportLeashedCreatures(player, origin, portal); + + if (player.eject()) { + TeleportHelper.handleEntityPassengers(passengers, player, origin, portal, exit.getDirection()); + } //If no event is passed in, assume it's a teleport, and act as such if (event == null) { @@ -72,23 +75,4 @@ public class PlayerTeleporter extends Teleporter { }, 1); } - /** - * Triggers the player portal event to allow plugins to change the exit location - * - * @param origin

The origin portal teleported from

- * @param exit

The exit location to teleport the player to

- * @param event

The player move event which triggered the teleportation

- * @return

The location the player should be teleported to, or null if the event was cancelled

- */ - private Location triggerPlayerPortalEvent(Portal origin, Location exit, PlayerMoveEvent event) { - StargatePlayerPortalEvent stargatePlayerPortalEvent = new StargatePlayerPortalEvent(player, origin, portal, exit); - Stargate.getInstance().getServer().getPluginManager().callEvent(stargatePlayerPortalEvent); - //Teleport is cancelled. Teleport the player back to where it came from - if (stargatePlayerPortalEvent.isCancelled()) { - new PlayerTeleporter(origin, player).teleport(origin, event); - return null; - } - return stargatePlayerPortalEvent.getExit(); - } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 4773902..edaef09 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -4,9 +4,11 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.ChunkUnloadRequest; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.event.StargateTeleportEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EntityHelper; +import net.knarcraft.stargate.utility.TeleportHelper; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; @@ -14,9 +16,8 @@ import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Slab; import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.bukkit.scheduler.BukkitScheduler; import java.util.ArrayList; @@ -31,28 +32,95 @@ public abstract class Teleporter { * The portal the entity is teleporting to */ protected final Portal portal; + /** * The scheduler to use for delaying tasks */ protected final BukkitScheduler scheduler; + /** + * The exit location any entities will be teleported to + */ + protected Location exit; + + /** + * The entity being teleported by this teleporter + */ + protected final Entity teleportedEntity; + /** * Instantiates a new portal teleporter * - * @param portal

The portal which is the target of the teleportation

+ * @param portal

The portal which is the target of the teleportation

+ * @param teleportedEntity

The entity teleported by this teleporter

*/ - public Teleporter(Portal portal) { + public Teleporter(Portal portal, Entity teleportedEntity) { this.portal = portal; this.scheduler = Stargate.getInstance().getServer().getScheduler(); + this.teleportedEntity = teleportedEntity; + this.exit = getExit(teleportedEntity); } + /** + * Teleports an entity + * + * @param origin

The portal the entity teleported from

+ * @param stargateTeleportEvent

The event to call to make sure the teleportation is valid

+ * @return

True if the teleportation was successfully performed

+ */ + public boolean teleport(Portal origin, StargateTeleportEvent stargateTeleportEvent) { + List passengers = teleportedEntity.getPassengers(); + + //Call the StargateEntityPortalEvent to allow plugins to change destination + if (!origin.equals(portal)) { + exit = triggerPortalEvent(origin, stargateTeleportEvent); + if (exit == null) { + return false; + } + } + + //Load chunks to make sure not to teleport to the void + loadChunks(); + + if (teleportedEntity.eject()) { + TeleportHelper.handleEntityPassengers(passengers, teleportedEntity, origin, portal, exit.getDirection()); + } + teleportedEntity.teleport(exit); + return true; + } + + /** + * Gets the exit location of this teleporter + * + * @return

The exit location of this teleporter

+ */ + public Location getExit() { + return exit.clone(); + } + + /** + * Triggers the entity portal event to allow plugins to change the exit location + * + * @param origin

The origin portal teleported from

+ * @param stargateTeleportEvent

The exit location to teleport the entity to

+ * @return

The location the entity should be teleported to, or null if the event was cancelled

+ */ + protected Location triggerPortalEvent(Portal origin, StargateTeleportEvent stargateTeleportEvent) { + Stargate.getInstance().getServer().getPluginManager().callEvent((Event) stargateTeleportEvent); + //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake + if (stargateTeleportEvent.isCancelled()) { + new EntityTeleporter(origin, teleportedEntity).teleportEntity(origin); + return null; + } + return stargateTeleportEvent.getExit(); + } /** * Adjusts the rotation of the exit to make the teleporting entity face directly out from the portal * * @param exit

The location the entity will exit from

*/ - protected void adjustRotation(Location exit) { + protected void adjustExitLocationRotation(Location exit) { int adjust = 0; if (portal.getOptions().isBackwards()) { adjust = 180; @@ -63,39 +131,14 @@ public abstract class Teleporter { } /** - * 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.

+ * Loads the chunks outside the portal's entrance */ - public Location getExit(Entity entity, Location traveller) { - Location exitLocation = null; - RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); - if (relativeExit != null) { - BlockLocation exit = portal.getBlockAt(relativeExit); - - //Move one block out to prevent exiting inside the portal - float portalYaw = portal.getYaw(); - if (portal.getOptions().isBackwards()) { - portalYaw += 180; - } - exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); - - if (entity != null) { - double entitySize = EntityHelper.getEntityMaxSize(entity); - //Prevent exit suffocation for players riding horses or similar - if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); - } - } - } else { - Stargate.logWarning(String.format("Missing destination point in .gate file %s", - portal.getGate().getFilename())); + protected void loadChunks() { + for (Chunk chunk : getChunksToLoad()) { + chunk.addPluginChunkTicket(Stargate.getInstance()); + //Allow the chunk to unload after 10 seconds + Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 10000L)); } - - //Adjust pitch and height - return adjustExitLocation(traveller, exitLocation); } /** @@ -185,41 +228,62 @@ public abstract class Teleporter { * slab check is necessary to prevent the player from clipping through the slab and spawning beneath it. The water * check is necessary when teleporting boats to prevent it from becoming a submarine.

* - * @param traveller

The location of the travelling entity

+ * @param entity

The travelling entity

* @param exitLocation

The exit location generated

* @return

The location the travelling entity should be teleported to

*/ - private Location adjustExitLocation(Location traveller, Location exitLocation) { + private Location adjustExitLocationHeight(Entity entity, Location exitLocation) { if (exitLocation != null) { BlockData blockData = exitLocation.getBlock().getBlockData(); if ((blockData instanceof Bisected bisected && bisected.getHalf() == Bisected.Half.BOTTOM) || - (blockData instanceof Slab slab && slab.getType() == Slab.Type.BOTTOM)) { - //Prevent traveller from spawning inside a slab - Stargate.debug("adjustExitLocation", "Added a block to get above a slab"); - exitLocation.add(0, 1, 0); - } else if (blockData.getMaterial() == Material.WATER) { - //If there's water outside, go one up to allow for boat teleportation - Stargate.debug("adjustExitLocation", "Added a block to get above a block of water"); + (blockData instanceof Slab slab && slab.getType() == Slab.Type.BOTTOM) || + blockData.getMaterial() == Material.WATER) { + //Prevent traveller from spawning inside a slab, or a boat from spawning inside water + Stargate.debug("adjustExitLocation", "Added a block to get above a slab or a block of water"); exitLocation.add(0, 1, 0); } - - exitLocation.setPitch(traveller.getPitch()); return exitLocation; } else { Stargate.logWarning("Unable to generate exit location"); - return traveller; + return entity.getLocation(); } } /** - * Loads the chunks outside the portal's entrance + * 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)

+ * @return

The location the entity should be teleported to.

*/ - protected void loadChunks() { - for (Chunk chunk : getChunksToLoad()) { - chunk.addPluginChunkTicket(Stargate.getInstance()); - //Allow the chunk to unload after 10 seconds - Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 10000L)); + private Location getExit(Entity entity) { + Location exitLocation = null; + RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); + if (relativeExit != null) { + BlockLocation exit = portal.getBlockAt(relativeExit); + + //Move one block out to prevent exiting inside the portal + float portalYaw = portal.getYaw(); + if (portal.getOptions().isBackwards()) { + portalYaw += 180; + } + exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); + + if (entity != null) { + double entitySize = EntityHelper.getEntityMaxSize(entity); + //Prevent exit suffocation for players riding horses or similar + if (entitySize > 1) { + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); + } + } + } else { + Stargate.logWarning(String.format("Missing destination point in .gate file %s", + portal.getGate().getFilename())); } + + //Adjust height and rotation + Location adjusted = adjustExitLocationHeight(entity, exitLocation); + adjustExitLocationRotation(adjusted); + return adjusted; } /** @@ -250,76 +314,4 @@ public abstract class Teleporter { return chunksToLoad; } - /** - * Checks whether a player has leashed creatures that block the teleportation - * - * @param player

The player trying to teleport

- * @return

False if the player has leashed any creatures that cannot go through the portal

- */ - public static boolean noLeashedCreaturesPreventTeleportation(Player player) { - //Find any nearby leashed entities to teleport with the player - List nearbyCreatures = getLeashedCreatures(player); - - //Disallow creatures with passengers to prevent smuggling - for (Creature creature : nearbyCreatures) { - if (!creature.getPassengers().isEmpty()) { - return false; - } - } - - //If it's enabled, there is no problem - if (Stargate.getGateConfig().handleLeashedCreatures()) { - return true; - } else { - return nearbyCreatures.isEmpty(); - } - } - - /** - * Teleports any creatures leashed by the player - * - *

Will return false if the teleportation should be aborted because the player has leashed creatures that - * aren't allowed to be teleported with the player.

- * - * @param player

The player which is teleported

- * @param origin

The portal the player is teleporting from

- */ - protected void teleportLeashedCreatures(Player player, Portal origin) { - //If this feature is disabled, just return - if (!Stargate.getGateConfig().handleLeashedCreatures()) { - return; - } - - //Find any nearby leashed entities to teleport with the player - List nearbyEntities = getLeashedCreatures(player); - - //Teleport all creatures leashed by the player to the portal the player is to exit from - for (Creature creature : nearbyEntities) { - creature.setLeashHolder(null); - scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { - new EntityTeleporter(portal, creature).teleport(origin); - scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 6); - }, 2); - } - } - - /** - * Gets all creatures leashed by a player within the given range - * - * @param player

The player to check

- * @return

A list of all creatures the player is holding in a leash (lead)

- */ - protected static List getLeashedCreatures(Player player) { - List leashedCreatures = new ArrayList<>(); - //Find any nearby leashed entities to teleport with the player - List nearbyEntities = player.getNearbyEntities(15, 15, 15); - //Teleport all creatures leashed by the player to the portal the player is to exit from - for (Entity entity : nearbyEntities) { - if (entity instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder() == player) { - leashedCreatures.add(creature); - } - } - return leashedCreatures; - } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 1215616..9a5dc50 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -2,13 +2,14 @@ package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.StargateGateConfig; +import net.knarcraft.stargate.event.StargateEntityPortalEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.utility.DirectionHelper; +import net.knarcraft.stargate.utility.TeleportHelper; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; import org.bukkit.util.Vector; @@ -24,11 +25,11 @@ public class VehicleTeleporter extends EntityTeleporter { /** * Instantiates a new vehicle teleporter * - * @param portal

The portal which is the target of the teleportation

+ * @param targetPortal

The targetPortal which is the target of the teleportation

* @param teleportingVehicle

The teleporting vehicle

*/ - public VehicleTeleporter(Portal portal, Vehicle teleportingVehicle) { - super(portal, teleportingVehicle); + public VehicleTeleporter(Portal targetPortal, Vehicle teleportingVehicle) { + super(targetPortal, teleportingVehicle); this.teleportingVehicle = teleportingVehicle; } @@ -42,29 +43,20 @@ public class VehicleTeleporter extends EntityTeleporter { * @return

True if the vehicle was teleported. False otherwise

*/ @Override - public boolean teleport(Portal origin) { - Location traveller = teleportingVehicle.getLocation(); - Location exit = getExit(teleportingVehicle, traveller); + public boolean teleportEntity(Portal origin) { + Stargate.debug("VehicleTeleporter::teleport", "Preparing to teleport: " + teleportingVehicle); double velocity = teleportingVehicle.getVelocity().length(); - //Stop and teleport + //Stop the vehicle before teleporting teleportingVehicle.setVelocity(new Vector()); //Get new velocity Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); Vector newVelocity = newVelocityDirection.multiply(velocity); - //Make sure the vehicle points out from the portal - adjustRotation(exit); - //Call the StargateEntityPortalEvent to allow plugins to change destination - if (!origin.equals(portal)) { - exit = triggerEntityPortalEvent(origin, exit); - if (exit == null) { - return false; - } - } + triggerPortalEvent(origin, new StargateEntityPortalEvent(teleportingVehicle, origin, portal, exit)); //Teleport the vehicle return teleportVehicle(exit, newVelocity, origin); @@ -118,41 +110,11 @@ public class VehicleTeleporter extends EntityTeleporter { private boolean vehiclePassengersAllowed(List passengers) { StargateGateConfig config = Stargate.getGateConfig(); //Don't teleport if the vehicle contains a creature and creature transportation is disabled - if (containsNonPlayer(passengers) && !config.handleCreatureTransportation()) { + if (TeleportHelper.containsNonPlayer(passengers) && !config.handleCreatureTransportation()) { return false; } //Don't teleport if the player does not contain a player and non-player vehicles is disabled - return containsPlayer(passengers) || config.handleNonPlayerVehicles(); - } - - /** - * Checks whether a list of entities contains any non-players - * - * @param entities

The list of entities to check

- * @return

True if at least one entity is not a player

- */ - private boolean containsNonPlayer(List entities) { - for (Entity entity : entities) { - if (!(entity instanceof Player)) { - return true; - } - } - return false; - } - - /** - * Checks whether a list of entities contains at least one player - * - * @param entities

The list of entities to check

- * @return

True if at least one player is present among the passengers

- */ - private boolean containsPlayer(List entities) { - for (Entity entity : entities) { - if (entity instanceof Player) { - return true; - } - } - return false; + return TeleportHelper.containsPlayer(passengers) || config.handleNonPlayerVehicles(); } /** @@ -163,9 +125,10 @@ public class VehicleTeleporter extends EntityTeleporter { * @param origin

The portal the vehicle teleported from

*/ private void teleportLivingVehicle(Location exit, List passengers, Portal origin) { - teleportingVehicle.eject(); + if (teleportingVehicle.eject()) { + TeleportHelper.handleEntityPassengers(passengers, teleportingVehicle, origin, portal, exit.getDirection()); + } teleportingVehicle.teleport(exit); - handleVehiclePassengers(passengers, teleportingVehicle, 2, origin, exit.getDirection()); } /** @@ -190,53 +153,11 @@ public class VehicleTeleporter extends EntityTeleporter { //Spawn a new vehicle Vehicle newVehicle = vehicleWorld.spawn(exit, teleportingVehicle.getClass()); //Remove the old vehicle - teleportingVehicle.eject(); + if (teleportingVehicle.eject()) { + TeleportHelper.handleEntityPassengers(passengers, newVehicle, origin, portal, exit.getDirection()); + } teleportingVehicle.remove(); - //Set rotation, add passengers and restore velocity - newVehicle.setRotation(exit.getYaw(), exit.getPitch()); - handleVehiclePassengers(passengers, newVehicle, 1, origin, exit.getDirection()); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> newVehicle.setVelocity(newVelocity), 1); } - /** - * Ejects, teleports and adds all passengers to the target vehicle - * - * @param passengers

The passengers to handle

- * @param vehicle

The vehicle the passengers should be put into

- * @param delay

The amount of milliseconds to wait before adding the vehicle passengers

- * @param origin

The portal the vehicle teleported from

- * @param exitRotation

The rotation of any passengers exiting the stargate

- */ - private void handleVehiclePassengers(List passengers, Vehicle vehicle, long delay, Portal origin, Vector exitRotation) { - for (Entity passenger : passengers) { - passenger.eject(); - scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { - if (passenger instanceof Player player) { - //Teleport any creatures leashed by the player in a 15-block range - teleportLeashedCreatures(player, origin); - } - teleportAndAddPassenger(vehicle, passenger, exitRotation); - }, delay); - } - } - - /** - * Teleports and adds a passenger to a vehicle - * - *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, - * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

- * - * @param targetVehicle

The vehicle to add the passenger to

- * @param passenger

The passenger to teleport and add

- * @param exitDirection

The direction of any passengers exiting the stargate

- */ - private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger, Vector exitDirection) { - if (!passenger.teleport(targetVehicle.getLocation().clone().setDirection(exitDirection))) { - Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger"); - } - if (!targetVehicle.addPassenger(passenger)) { - Stargate.debug("handleVehiclePassengers", "Failed to add passenger"); - } - } - } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 00ee6db..677e80f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -190,7 +190,7 @@ public final class BungeeHelper { } //Teleport the player back to this gate, for sanity's sake - new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); + new PlayerTeleporter(entrancePortal, player).teleportPlayer(entrancePortal, event); //Send the SGBungee packet first, it will be queued by BC if required if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 2a8c1ce..f87dc41 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -387,7 +387,7 @@ public final class PermissionHelper { if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); } - new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); + new PlayerTeleporter(entrancePortal, player).teleportPlayer(entrancePortal, event); return true; } @@ -401,7 +401,7 @@ public final class PermissionHelper { if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); } - new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); + new PlayerTeleporter(entrancePortal, player).teleportPlayer(entrancePortal, event); entrancePortal.getPortalOpener().closePortal(false); return true; } diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java new file mode 100644 index 0000000..caef004 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -0,0 +1,199 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.teleporter.EntityTeleporter; +import org.bukkit.Bukkit; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +/** + * A helper class with methods for various teleportation tasks + * + *

The teleport helper mainly helps with passengers and leashed creatures

+ */ +public final class TeleportHelper { + + private TeleportHelper() { + + } + + /** + * Checks whether a player has leashed creatures that block the teleportation + * + * @param player

The player trying to teleport

+ * @return

False if the player has leashed any creatures that cannot go through the portal

+ */ + public static boolean noLeashedCreaturesPreventTeleportation(Player player) { + //Find any nearby leashed entities to teleport with the player + List nearbyCreatures = getLeashedCreatures(player); + + //Disallow creatures with passengers to prevent smuggling + for (Creature creature : nearbyCreatures) { + if (!creature.getPassengers().isEmpty()) { + return false; + } + } + //TODO: Improve this to account for any players sitting on any of the lead creatures + + //If it's enabled, there is no problem + if (Stargate.getGateConfig().handleLeashedCreatures()) { + return true; + } else { + return nearbyCreatures.isEmpty(); + } + } + + /** + * Gets all creatures leashed by a player within the given range + * + * @param player

The player to check

+ * @return

A list of all creatures the player is holding in a leash (lead)

+ */ + public static List getLeashedCreatures(Player player) { + List leashedCreatures = new ArrayList<>(); + //Find any nearby leashed entities to teleport with the player + List nearbyEntities = player.getNearbyEntities(15, 15, 15); + //Teleport all creatures leashed by the player to the portal the player is to exit from + for (Entity entity : nearbyEntities) { + if (entity instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder() == player) { + leashedCreatures.add(creature); + } + } + return leashedCreatures; + } + + /** + * Teleports and adds a passenger to an entity + * + *

Teleportation of living vehicles is really buggy if you wait between the teleportation and passenger adding, + * but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.

+ * + * @param targetVehicle

The entity to add the passenger to

+ * @param passenger

The passenger to teleport and add

+ * @param exitDirection

The direction of any passengers exiting the stargate

+ */ + public static void teleportAndAddPassenger(Entity targetVehicle, Entity passenger, Vector exitDirection) { + if (!passenger.teleport(targetVehicle.getLocation().clone().setDirection(exitDirection))) { + Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger" + passenger); + } + if (!targetVehicle.addPassenger(passenger)) { + Stargate.debug("handleVehiclePassengers", "Failed to add passenger" + passenger); + } + } + + /** + * Ejects, teleports and adds all passengers to the target entity + * + * @param passengers

The passengers to handle

+ * @param entity

The entity the passengers should be put into

The portal the entity teleported from

+ * @param target

The portal the entity is teleporting to

+ * @param exitRotation

The rotation of any passengers exiting the stargate

+ */ + public static void handleEntityPassengers(List passengers, Entity entity, Portal origin, Portal target, + Vector exitRotation) { + for (Entity passenger : passengers) { + List passengerPassengers = passenger.getPassengers(); + if (!passengerPassengers.isEmpty()) { + Stargate.debug("Teleporter::handleEntityPassengers", "Found the entities: " + + passengerPassengers + " as passengers of " + entity); + } + if (passenger.eject()) { + //Teleport any passengers of the passenger + handleEntityPassengers(passengerPassengers, passenger, origin, target, exitRotation); + } + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> { + if (passenger instanceof Player player) { + //Teleport any creatures leashed by the player in a 15-block range + teleportLeashedCreatures(player, origin, target); + } + TeleportHelper.teleportAndAddPassenger(entity, passenger, exitRotation); + }, passenger instanceof Player ? 6 : 0); + } + } + + /** + * Teleports any creatures leashed by the player + * + *

Will return false if the teleportation should be aborted because the player has leashed creatures that + * aren't allowed to be teleported with the player.

+ * + * @param player

The player which is teleported

+ * @param origin

The portal the player is teleporting from

+ * @param target

The portal the player is teleporting to

+ */ + public static void teleportLeashedCreatures(Player player, Portal origin, Portal target) { + //If this feature is disabled, just return + if (!Stargate.getGateConfig().handleLeashedCreatures()) { + return; + } + BukkitScheduler scheduler = Bukkit.getScheduler(); + + //Find any nearby leashed entities to teleport with the player + List nearbyEntities = TeleportHelper.getLeashedCreatures(player); + + //Teleport all creatures leashed by the player to the portal the player is to exit from + for (Creature creature : nearbyEntities) { + creature.setLeashHolder(null); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { + new EntityTeleporter(target, creature).teleportEntity(origin); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 6); + }, 2); + } + } + + /** + * Checks whether a list of entities or any of their passengers contains any non-players + * + * @param entities

The list of entities to check

+ * @return

True if at least one entity is not a player

+ */ + public static boolean containsNonPlayer(List entities) { + for (Entity entity : entities) { + if (!(entity instanceof Player) || containsNonPlayer(entity.getPassengers())) { + return true; + } + } + return false; + } + + /** + * Checks whether a list of entities of their passengers contains at least one player + * + * @param entities

The list of entities to check

+ * @return

True if at least one player is present among the passengers

+ */ + public static boolean containsPlayer(List entities) { + for (Entity entity : entities) { + if (entity instanceof Player || containsPlayer(entity.getPassengers())) { + return true; + } + } + return false; + } + + /** + * Gets all players recursively from a list of entities + * + * @param entities

The entities to check for players

+ * @return

The found players

+ */ + public static List getPlayers(List entities) { + List players = new ArrayList<>(5); + for (Entity entity : entities) { + if (entity instanceof Player) { + players.add((Player) entity); + } + players.addAll(getPlayers(entity.getPassengers())); + } + return players; + } + +} From 248caee620858ba2b1ef0865f0da8183e54c0839 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 28 Jan 2022 23:23:33 +0100 Subject: [PATCH 336/378] Fixes some minor formatting issues --- .../knarcraft/stargate/config/StargateGateConfig.java | 4 ++-- .../knarcraft/stargate/listener/PortalEventListener.java | 3 +-- .../java/net/knarcraft/stargate/utility/ColorHelper.java | 9 ++++++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 1e19865..85e8d86 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -262,8 +262,8 @@ public final class StargateGateConfig { if (colors[colorIndex].equalsIgnoreCase("inverted")) { //Convert from ChatColor to awt.Color to Bukkit.Color then invert and convert to ChatColor java.awt.Color color = defaultColors[colorIndex].getColor(); - parsedColor = ColorHelper.fromColor(ColorHelper.invert(Color.fromRGB(color.getRed(), - color.getGreen(), color.getBlue()))); + parsedColor = ColorHelper.fromColor(ColorHelper.invert(Color.fromRGB(color.getRed(), color.getGreen(), + color.getBlue()))); } else { try { parsedColor = ChatColor.of(colors[colorIndex]); diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 8510b9e..146f87a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -95,8 +95,7 @@ public class PortalEventListener implements Listener { Portal exitPortal = teleportation.getExit(); //Overwrite respawn location to respawn in front of the portal - event.setRespawnLocation(new PlayerTeleporter(exitPortal, respawningPlayer).getExit(respawningPlayer, - respawningPlayer.getLocation())); + event.setRespawnLocation(new PlayerTeleporter(exitPortal, respawningPlayer).getExit()); //Properly close the portal to prevent it from staying in a locked state until it times out exitPortal.getPortalOpener().closePortal(false); } diff --git a/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java b/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java index 027bd66..0886b94 100644 --- a/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java @@ -6,7 +6,14 @@ import org.bukkit.Color; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ColorHelper { +/** + * A helper class for dealing with colors + */ +public final class ColorHelper { + + private ColorHelper() { + + } /** * Inverts the given color From 56d59f0d2a3197337a3062d085bcbf128339642b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 29 Jan 2022 00:30:26 +0100 Subject: [PATCH 337/378] Makes sure to check player passengers from the root entity --- .../knarcraft/stargate/config/StargateGateConfig.java | 2 +- .../stargate/listener/VehicleEventListener.java | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 85e8d86..2448f9b 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -262,7 +262,7 @@ public final class StargateGateConfig { if (colors[colorIndex].equalsIgnoreCase("inverted")) { //Convert from ChatColor to awt.Color to Bukkit.Color then invert and convert to ChatColor java.awt.Color color = defaultColors[colorIndex].getColor(); - parsedColor = ColorHelper.fromColor(ColorHelper.invert(Color.fromRGB(color.getRed(), color.getGreen(), + parsedColor = ColorHelper.fromColor(ColorHelper.invert(Color.fromRGB(color.getRed(), color.getGreen(), color.getBlue()))); } else { try { diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index d6d2a52..161401d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -64,7 +64,7 @@ public class VehicleEventListener implements Listener { if (!passengers.isEmpty() && TeleportHelper.containsPlayer(passengers)) { Stargate.debug(route, "Found passenger vehicle"); - teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); + teleportPlayerAndVehicle(entrancePortal, vehicle); } else { Stargate.debug(route, "Found vehicle without players"); Portal destinationPortal = entrancePortal.getPortalActivator().getDestination(); @@ -83,10 +83,13 @@ public class VehicleEventListener implements Listener { * * @param entrancePortal

The portal the minecart entered

* @param vehicle

The vehicle to teleport

- * @param passengers

Any entities sitting in the minecart

*/ - private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { - List players = TeleportHelper.getPlayers(passengers); + private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle) { + Entity rootEntity = vehicle; + while (rootEntity.getVehicle() != null) { + rootEntity = rootEntity.getVehicle(); + } + List players = TeleportHelper.getPlayers(rootEntity.getPassengers()); Portal destinationPortal = null; for (Player player : players) { From e7b711efcffb27e7ce688e87083999f8111915ea Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 7 Feb 2022 22:51:09 +0100 Subject: [PATCH 338/378] Makes sure to stop polling the block change thread once it's empty instead of continuing doing nothing --- .../knarcraft/stargate/thread/BlockChangeThread.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index d177a0b..faa14fc 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -21,18 +21,22 @@ public class BlockChangeThread implements Runnable { long sTime = System.nanoTime(); //Repeat for at most 0.025 seconds while (System.nanoTime() - sTime < 25000000) { - pollQueue(); + if (pollQueue()) { + break; + } } } /** * Polls the block change request queue for any waiting requests + * + * @return

True if the queue is empty and it's safe to quit

*/ - public static void pollQueue() { + public static boolean pollQueue() { //Abort if there's no work to be done BlockChangeRequest blockChangeRequest = Stargate.getBlockChangeRequestQueue().poll(); if (blockChangeRequest == null) { - return; + return true; } //Change the material of the pulled block @@ -46,6 +50,7 @@ public class BlockChangeThread implements Runnable { //If orientation is relevant, adjust the block's orientation orientBlock(block, blockChangeRequest.getAxis()); } + return false; } /** From 8643a44df610c50e8746976ba15f62cb4375a7e2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 8 Feb 2022 16:24:47 +0100 Subject: [PATCH 339/378] Moves some code to TeleportHelper --- .../stargate/command/CommandAbout.java | 3 +- .../listener/VehicleEventListener.java | 34 +------------------ .../stargate/utility/TeleportHelper.java | 31 +++++++++++++++++ 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 3e5b441..f0acd50 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -23,8 +23,9 @@ public class CommandAbout implements CommandExecutor { commandSender.sendMessage(textColor + "Go to " + highlightColor + "https://git.knarcraft.net/EpicKnarvik97/Stargate " + textColor + "for the official repository"); String author = Stargate.getStargateConfig().getLanguageLoader().getString("author"); - if (!author.isEmpty()) + if (!author.isEmpty()) { commandSender.sendMessage(textColor + "Language created by " + highlightColor + author); + } return true; } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 161401d..42c1102 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -6,7 +6,6 @@ import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; -import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.TeleportHelper; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -113,7 +112,7 @@ public class VehicleEventListener implements Listener { if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); } - } else if (!playerCanTeleport(player, entrancePortal, destinationPortal)) { + } else if (!TeleportHelper.playerCanTeleport(player, entrancePortal, destinationPortal)) { cancelTeleport = true; } } @@ -145,35 +144,4 @@ public class VehicleEventListener implements Listener { } } - /** - * Checks whether the given player is allowed to and can afford to teleport - * - * @param player

The player trying to teleport

- * @param entrancePortal

The portal the player is entering

- * @param destinationPortal

The portal the player is to exit from

- * @return

True if the player is allowed to teleport and is able to pay necessary fees

- */ - private static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { - //Make sure the user can access the portal - if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { - if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); - } - entrancePortal.getPortalOpener().closePortal(false); - return false; - } - - //Check if the player is able to afford the teleport fee - int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); - boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); - if (!canAffordFee) { - if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); - } - return false; - } - - return TeleportHelper.noLeashedCreaturesPreventTeleportation(player); - } - } diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java index caef004..e8ef4eb 100644 --- a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -196,4 +196,35 @@ public final class TeleportHelper { return players; } + /** + * Checks whether the given player is allowed to and can afford to teleport + * + * @param player

The player trying to teleport

+ * @param entrancePortal

The portal the player is entering

+ * @param destinationPortal

The portal the player is to exit from

+ * @return

True if the player is allowed to teleport and is able to pay necessary fees

+ */ + public static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { + //Make sure the user can access the portal + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + } + entrancePortal.getPortalOpener().closePortal(false); + return false; + } + + //Check if the player is able to afford the teleport fee + int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); + boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); + if (!canAffordFee) { + if (!entrancePortal.getOptions().isSilent()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); + } + return false; + } + + return TeleportHelper.noLeashedCreaturesPreventTeleportation(player); + } + } From 497551d889f6852015d2589748c893896d918125 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 8 Feb 2022 18:10:02 +0100 Subject: [PATCH 340/378] Makes the CraftBook remove on eject fix optional --- .../knarcraft/stargate/config/ConfigOption.java | 10 ++++++++++ .../stargate/config/StargateGateConfig.java | 11 +++++++++++ .../portal/teleporter/VehicleTeleporter.java | 16 ++++++++++------ src/main/resources/config.yml | 2 ++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 2169d14..19418e9 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -50,6 +50,9 @@ public enum ConfigOption { */ HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"), + /** + * The colors to use for each type of sign + */ PER_SIGN_COLORS("gates.cosmetic.perSignColors", "The per-sign color specification", new String[]{ "'ACACIA:default,default'", "'BIRCH:default,default'", "'CRIMSON:inverted,inverted'", "'DARK_OAK:inverted,inverted'", "'JUNGLE:default,default'", "'OAK:default,default'", "'SPRUCE:inverted,inverted'", "'WARPED:inverted,inverted'"}), @@ -102,6 +105,13 @@ public enum ConfigOption { HANDLE_LEASHED_CREATURES("gates.functionality.handleLeashedCreatures", "Whether to enable players to teleport a creature on a leash", true), + /** + * Whether to enable a fix that makes teleportation of minecarts/boats work even with craftbook's vehicle removal + */ + ENABLE_CRAFT_BOOK_REMOVE_ON_EJECT_FIX("gates.functionality.enableCraftBookRemoveOnEjectFix", + "Whether to enable a fix that causes loss of NBT data, but allows vehicle teleportation to work " + + "when CraftBook's remove minecart/boat on eject setting is enabled", false), + /** * Whether to enable economy support for taking payment from players creating/destroying/using stargates */ diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 2448f9b..89c9c6a 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -125,6 +125,17 @@ public final class StargateGateConfig { return (boolean) configOptions.get(ConfigOption.HANDLE_LEASHED_CREATURES); } + /** + * Gets whether the CraftBook vehicle removal fix is enabled + * + *

If enabled, minecarts and boats should be re-created instead of teleported.

+ * + * @return

True if the CraftBook vehicle removal fix is enabled

+ */ + public boolean enableCraftBookRemoveOnEjectFix() { + return (boolean) configOptions.get(ConfigOption.ENABLE_CRAFT_BOOK_REMOVE_ON_EJECT_FIX); + } + /** * Gets whether the list of destinations within a network should be sorted * diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 9a5dc50..dd77f28 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -81,12 +81,13 @@ public class VehicleTeleporter extends EntityTeleporter { return false; } - if (!(teleportingVehicle instanceof LivingEntity)) { + if (!(teleportingVehicle instanceof LivingEntity) && + Stargate.getGateConfig().enableCraftBookRemoveOnEjectFix()) { //Teleport a normal vehicle with passengers (minecart or boat) putPassengersInNewVehicle(passengers, exit, newVelocity, origin); } else { //Teleport a living vehicle with passengers (pig, horse, donkey, strider) - teleportLivingVehicle(exit, passengers, origin); + teleportVehicle(passengers, exit, newVelocity, origin); } } else { //Check if teleportation of empty vehicles is enabled @@ -120,15 +121,18 @@ public class VehicleTeleporter extends EntityTeleporter { /** * Teleport a vehicle which is not a minecart or a boat * - * @param exit

The location the vehicle will exit

- * @param passengers

The passengers of the vehicle

- * @param origin

The portal the vehicle teleported from

+ * @param passengers

The passengers of the vehicle

+ * @param exit

The location the vehicle will exit

+ * @param newVelocity

The new velocity of the teleported vehicle

+ * @param origin

The portal the vehicle teleported from

*/ - private void teleportLivingVehicle(Location exit, List passengers, Portal origin) { + private void teleportVehicle(List passengers, Location exit, Vector newVelocity, Portal origin) { if (teleportingVehicle.eject()) { TeleportHelper.handleEntityPassengers(passengers, teleportingVehicle, origin, portal, exit.getDirection()); } teleportingVehicle.teleport(exit); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), + () -> teleportingVehicle.setVelocity(newVelocity), 1); } /** diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index e3ad5a8..a612b36 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -54,6 +54,8 @@ gates: handleNonPlayerVehicles: true # handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player handleLeashedCreatures: true + # enableCraftBookRemoveOnEjectFix - Whether to enable a fix that causes loss of NBT data, but allows vehicle teleportation to work when CraftBook's remove minecart/boat on eject setting is enabled + enableCraftBookRemoveOnEjectFix: false # I------------I-------------I # # stargate economy options # From 6c32de59a891f915b957adf1a65779fd38064958 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 8 Feb 2022 18:31:26 +0100 Subject: [PATCH 341/378] Makes the delay to prevent client errors configurable --- .../java/net/knarcraft/stargate/config/ConfigOption.java | 7 +++++++ .../knarcraft/stargate/config/StargateGateConfig.java | 9 +++++++++ .../net/knarcraft/stargate/utility/TeleportHelper.java | 5 +++-- src/main/resources/config.yml | 5 ++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index 19418e9..d460492 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -112,6 +112,13 @@ public enum ConfigOption { "Whether to enable a fix that causes loss of NBT data, but allows vehicle teleportation to work " + "when CraftBook's remove minecart/boat on eject setting is enabled", false), + /** + * The delay between teleporting a vehicle and adding the player as passenger + */ + WAIT_FOR_PLAYER_AFTER_TELEPORT_DELAY("advanced.waitForPlayerAfterTeleportDelay", + "The amount of ticks to wait before adding a player as passenger of a vehicle. On slow servers, " + + "a value of 6 is required to avoid client glitches after teleporting on a vehicle.", 1), + /** * Whether to enable economy support for taking payment from players creating/destroying/using stargates */ diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 89c9c6a..47542bd 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -136,6 +136,15 @@ public final class StargateGateConfig { return (boolean) configOptions.get(ConfigOption.ENABLE_CRAFT_BOOK_REMOVE_ON_EJECT_FIX); } + /** + * Gets the delay to use before adding a player as passenger of a teleported vehicle + * + * @return

The delay to use before adding a player as passenger of a teleported vehicle

+ */ + public int waitForPlayerAfterTeleportDelay() { + return (int) configOptions.get(ConfigOption.WAIT_FOR_PLAYER_AFTER_TELEPORT_DELAY); + } + /** * Gets whether the list of destinations within a network should be sorted * diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java index e8ef4eb..381a76b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -115,7 +115,7 @@ public final class TeleportHelper { teleportLeashedCreatures(player, origin, target); } TeleportHelper.teleportAndAddPassenger(entity, passenger, exitRotation); - }, passenger instanceof Player ? 6 : 0); + }, passenger instanceof Player ? Stargate.getGateConfig().waitForPlayerAfterTeleportDelay() : 0); } } @@ -144,7 +144,8 @@ public final class TeleportHelper { creature.setLeashHolder(null); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> { new EntityTeleporter(target, creature).teleportEntity(origin); - scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 6); + scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), + Stargate.getGateConfig().waitForPlayerAfterTeleportDelay()); }, 2); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a612b36..a4252e4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -85,4 +85,7 @@ debugging: # debug - Debug -- Only enable if you have issues, massive console output debug: false # permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) - permissionDebug: false \ No newline at end of file + permissionDebug: false +advanced: + # waitForPlayerAfterTeleportDelay - The amount of ticks to wait before adding a player as passenger of a vehicle. On slow servers, a value of 6 is required to avoid client glitches after teleporting on a vehicle. + waitForPlayerAfterTeleportDelay: 6 \ No newline at end of file From a521454020a5acdfeca818b33d2666ef1497ff12 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 8 Feb 2022 18:43:04 +0100 Subject: [PATCH 342/378] Updates README and version to 0.9.3.4 --- README.md | 11 +++++++++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 691ffe7..eba5e85 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,7 @@ gates: handleCreatureTransportation - Whether or not to handle players that transport creatures by sending vehicles (minecarts, boats) through gates. handleNonPlayerVehicles - Whether or not to handle vehicles with a passenger which is not a player going through gates (pigs, horses, villagers, creepers, etc.). handleCreatureTransportation must be enabled. handleLeashedCreatures - Whether or not to handle creatures leashed by a player going through gates. Set to false to disallow leashed creatures going through gates. + enableCraftBookRemoveOnEjectFix - Whether to enable a fix that causes loss of NBT data, but allows vehicle teleportation to work when CraftBook's remove minecart/boat on eject setting is enabled economy: useEconomy - Whether or not to enable Economy using Vault (must have the Vault plugin) createCost - The cost to create a stargate @@ -336,6 +337,8 @@ economy: debugging: debug - Whether to show massive debug output permissionDebug - Whether to show massive permission debug output +advanced: + waitForPlayerAfterTeleportDelay - The amount of ticks to wait before adding a player as passenger of a vehicle. On slow servers, a value of 6 is required to avoid client glitches after teleporting on a vehicle. ``` # Message Customization @@ -397,6 +400,14 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.4] EpicKnarvik97 fork + +- Includes passengers of passengers when teleporting entities +- Fixes a bug which caused Stargate to use more CPU for no reason +- Teleports boats/minecarts like other vehicles unless *enableCraftBookRemoveOnEjectFix* is enabled +- Adds the *waitForPlayerAfterTeleportDelay* config option which allows changing the delay between vehicle teleportation + and the player being teleported to the vehicle + #### \[Version 0.9.3.3] EpicKnarvik97 fork - Prevents Zombified Piglins from randomly spawning at Stargates diff --git a/pom.xml b/pom.xml index ec9c840..31bcea6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.3 + 0.9.3.4 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0a9a6ed..8bba37f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.3 +version: 0.9.3.4 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 99bceb91655f096ddbe2d33a8d9d11a8d3b25ca5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 8 Feb 2022 18:44:44 +0100 Subject: [PATCH 343/378] Updates some test dependencies --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 31bcea6..08017ba 100644 --- a/pom.xml +++ b/pom.xml @@ -44,25 +44,25 @@ org.junit.jupiter junit-jupiter-api - 5.8.0-M1 + 5.8.2 test com.github.seeseemelk MockBukkit-v1.18 - 1.14.0 + 1.15.5 test org.jetbrains annotations - 19.0.0 + 22.0.0 compile junit junit - 4.13.1 + 4.13.2 test From 28d84450fb7d3a19a7a7727e969da8ce44fee4ce Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 8 Feb 2022 19:00:44 +0100 Subject: [PATCH 344/378] Makes boats keep their boat type when teleported using the CraftBook fix --- README.md | 1 + .../stargate/portal/teleporter/VehicleTeleporter.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index eba5e85..930c3e8 100644 --- a/README.md +++ b/README.md @@ -407,6 +407,7 @@ portalInfoServer=Server: %server% - Teleports boats/minecarts like other vehicles unless *enableCraftBookRemoveOnEjectFix* is enabled - Adds the *waitForPlayerAfterTeleportDelay* config option which allows changing the delay between vehicle teleportation and the player being teleported to the vehicle +- Makes boats keep their wood type even when re-created #### \[Version 0.9.3.3] EpicKnarvik97 fork diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index dd77f28..22f313f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -8,6 +8,7 @@ import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.TeleportHelper; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Vehicle; @@ -156,6 +157,9 @@ public class VehicleTeleporter extends EntityTeleporter { } //Spawn a new vehicle Vehicle newVehicle = vehicleWorld.spawn(exit, teleportingVehicle.getClass()); + if (teleportingVehicle instanceof Boat boat) { + ((Boat) newVehicle).setWoodType(boat.getWoodType()); + } //Remove the old vehicle if (teleportingVehicle.eject()) { TeleportHelper.handleEntityPassengers(passengers, newVehicle, origin, portal, exit.getDirection()); From a481ccf017e6f9a7a39b55eab9e5c4ff851de1f0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 05:54:57 +0100 Subject: [PATCH 345/378] Adds some debug messages and makes sure to listen to the vehicle teleport event result --- .../stargate/listener/PlayerEventListener.java | 2 ++ .../portal/teleporter/VehicleTeleporter.java | 16 +++++++++++++--- .../stargate/utility/TeleportHelper.java | 18 ++++++++++++++---- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 4076be2..ff28930 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -33,6 +33,7 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; import java.util.HashMap; import java.util.Map; @@ -131,6 +132,7 @@ public class PlayerEventListener implements Listener { horse.setOwner(player); } //Teleport the player's vehicle + player.setVelocity(new Vector()); new VehicleTeleporter(destination, (Vehicle) playerVehicle).teleportEntity(entrancePortal); } else { //Just teleport the player like normal diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 22f313f..6110764 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -12,6 +12,7 @@ import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Vehicle; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.util.Vector; import java.util.List; @@ -57,7 +58,10 @@ public class VehicleTeleporter extends EntityTeleporter { Vector newVelocity = newVelocityDirection.multiply(velocity); //Call the StargateEntityPortalEvent to allow plugins to change destination - triggerPortalEvent(origin, new StargateEntityPortalEvent(teleportingVehicle, origin, portal, exit)); + exit = triggerPortalEvent(origin, new StargateEntityPortalEvent(teleportingVehicle, origin, portal, exit)); + if (exit == null) { + return false; + } //Teleport the vehicle return teleportVehicle(exit, newVelocity, origin); @@ -131,9 +135,15 @@ public class VehicleTeleporter extends EntityTeleporter { if (teleportingVehicle.eject()) { TeleportHelper.handleEntityPassengers(passengers, teleportingVehicle, origin, portal, exit.getDirection()); } - teleportingVehicle.teleport(exit); + Stargate.debug("VehicleTeleporter::teleportVehicle", "Teleporting " + teleportingVehicle + + " to final location " + exit + " with direction " + exit.getDirection()); + teleportingVehicle.teleport(exit, PlayerTeleportEvent.TeleportCause.PLUGIN); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), - () -> teleportingVehicle.setVelocity(newVelocity), 1); + () -> { + Stargate.debug("VehicleTeleporter::teleportVehicle", "Setting velocity " + newVelocity + + " for vehicle " + teleportingVehicle); + teleportingVehicle.setVelocity(newVelocity); + }, 1); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java index 381a76b..989effd 100644 --- a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.teleporter.EntityTeleporter; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -80,11 +81,20 @@ public final class TeleportHelper { * @param exitDirection

The direction of any passengers exiting the stargate

*/ public static void teleportAndAddPassenger(Entity targetVehicle, Entity passenger, Vector exitDirection) { - if (!passenger.teleport(targetVehicle.getLocation().clone().setDirection(exitDirection))) { - Stargate.debug("handleVehiclePassengers", "Failed to teleport passenger" + passenger); + Location passengerExit = targetVehicle.getLocation().clone().setDirection(exitDirection); + if (!passenger.teleport(passengerExit)) { + Stargate.debug("TeleportHelper::handleVehiclePassengers", "Failed to teleport passenger" + + passenger); + } else { + Stargate.debug("TeleportHelper::handleVehiclePassengers", "Teleported " + passenger + + " to " + passengerExit); } if (!targetVehicle.addPassenger(passenger)) { - Stargate.debug("handleVehiclePassengers", "Failed to add passenger" + passenger); + Stargate.debug("TeleportHelper::handleVehiclePassengers", "Failed to add passenger" + + passenger); + } else { + Stargate.debug("TeleportHelper::handleVehiclePassengers", "Added passenger " + passenger + + " to " + targetVehicle); } } @@ -114,7 +124,7 @@ public final class TeleportHelper { //Teleport any creatures leashed by the player in a 15-block range teleportLeashedCreatures(player, origin, target); } - TeleportHelper.teleportAndAddPassenger(entity, passenger, exitRotation); + teleportAndAddPassenger(entity, passenger, exitRotation); }, passenger instanceof Player ? Stargate.getGateConfig().waitForPlayerAfterTeleportDelay() : 0); } } From 5f4a90aabbc46850dad2b4de7722da587d506335 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 16:23:45 +0100 Subject: [PATCH 346/378] Gives all passengers the same exit velocity as the root vehicle --- .../portal/teleporter/PlayerTeleporter.java | 8 +++++--- .../stargate/portal/teleporter/Teleporter.java | 4 +++- .../portal/teleporter/VehicleTeleporter.java | 6 ++++-- .../knarcraft/stargate/utility/TeleportHelper.java | 14 ++++++++++---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index 12b7f55..4c936bc 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -49,6 +49,10 @@ public class PlayerTeleporter extends Teleporter { } } + //Calculate the exit velocity of the player + Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); + Vector newVelocity = newVelocityDirection.multiply(velocity * Stargate.getGateConfig().getExitVelocity()); + //Load chunks to make sure not to teleport to the void loadChunks(); @@ -56,7 +60,7 @@ public class PlayerTeleporter extends Teleporter { TeleportHelper.teleportLeashedCreatures(player, origin, portal); if (player.eject()) { - TeleportHelper.handleEntityPassengers(passengers, player, origin, portal, exit.getDirection()); + TeleportHelper.handleEntityPassengers(passengers, player, origin, portal, exit.getDirection(), newVelocity); } //If no event is passed in, assume it's a teleport, and act as such @@ -69,8 +73,6 @@ public class PlayerTeleporter extends Teleporter { //Set the velocity of the teleported player after the teleportation is finished Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> { - Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw()); - Vector newVelocity = newVelocityDirection.multiply(velocity * Stargate.getGateConfig().getExitVelocity()); player.setVelocity(newVelocity); }, 1); } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index edaef09..7e1f7ee 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -19,6 +19,7 @@ import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.List; @@ -83,7 +84,8 @@ public abstract class Teleporter { loadChunks(); if (teleportedEntity.eject()) { - TeleportHelper.handleEntityPassengers(passengers, teleportedEntity, origin, portal, exit.getDirection()); + TeleportHelper.handleEntityPassengers(passengers, teleportedEntity, origin, portal, exit.getDirection(), + new Vector()); } teleportedEntity.teleport(exit); return true; diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 6110764..20d4353 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -133,7 +133,8 @@ public class VehicleTeleporter extends EntityTeleporter { */ private void teleportVehicle(List passengers, Location exit, Vector newVelocity, Portal origin) { if (teleportingVehicle.eject()) { - TeleportHelper.handleEntityPassengers(passengers, teleportingVehicle, origin, portal, exit.getDirection()); + TeleportHelper.handleEntityPassengers(passengers, teleportingVehicle, origin, portal, exit.getDirection(), + newVelocity); } Stargate.debug("VehicleTeleporter::teleportVehicle", "Teleporting " + teleportingVehicle + " to final location " + exit + " with direction " + exit.getDirection()); @@ -172,7 +173,8 @@ public class VehicleTeleporter extends EntityTeleporter { } //Remove the old vehicle if (teleportingVehicle.eject()) { - TeleportHelper.handleEntityPassengers(passengers, newVehicle, origin, portal, exit.getDirection()); + TeleportHelper.handleEntityPassengers(passengers, newVehicle, origin, portal, exit.getDirection(), + newVelocity); } teleportingVehicle.remove(); scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> newVehicle.setVelocity(newVelocity), 1); diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java index 989effd..97d7868 100644 --- a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -79,8 +79,10 @@ public final class TeleportHelper { * @param targetVehicle

The entity to add the passenger to

* @param passenger

The passenger to teleport and add

* @param exitDirection

The direction of any passengers exiting the stargate

+ * @param newVelocity

The new velocity of the teleported passenger

*/ - public static void teleportAndAddPassenger(Entity targetVehicle, Entity passenger, Vector exitDirection) { + public static void teleportAndAddPassenger(Entity targetVehicle, Entity passenger, Vector exitDirection, + Vector newVelocity) { Location passengerExit = targetVehicle.getLocation().clone().setDirection(exitDirection); if (!passenger.teleport(passengerExit)) { Stargate.debug("TeleportHelper::handleVehiclePassengers", "Failed to teleport passenger" + @@ -96,6 +98,9 @@ public final class TeleportHelper { Stargate.debug("TeleportHelper::handleVehiclePassengers", "Added passenger " + passenger + " to " + targetVehicle); } + Stargate.debug("VehicleTeleporter::teleportVehicle", "Setting velocity " + newVelocity + + " for passenger " + passenger); + passenger.setVelocity(newVelocity); } /** @@ -106,9 +111,10 @@ public final class TeleportHelper { * @param origin

The portal the entity teleported from

* @param target

The portal the entity is teleporting to

* @param exitRotation

The rotation of any passengers exiting the stargate

+ * @param newVelocity

The new velocity of the teleported passengers

*/ public static void handleEntityPassengers(List passengers, Entity entity, Portal origin, Portal target, - Vector exitRotation) { + Vector exitRotation, Vector newVelocity) { for (Entity passenger : passengers) { List passengerPassengers = passenger.getPassengers(); if (!passengerPassengers.isEmpty()) { @@ -117,14 +123,14 @@ public final class TeleportHelper { } if (passenger.eject()) { //Teleport any passengers of the passenger - handleEntityPassengers(passengerPassengers, passenger, origin, target, exitRotation); + handleEntityPassengers(passengerPassengers, passenger, origin, target, exitRotation, newVelocity); } Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> { if (passenger instanceof Player player) { //Teleport any creatures leashed by the player in a 15-block range teleportLeashedCreatures(player, origin, target); } - teleportAndAddPassenger(entity, passenger, exitRotation); + teleportAndAddPassenger(entity, passenger, exitRotation, newVelocity); }, passenger instanceof Player ? Stargate.getGateConfig().waitForPlayerAfterTeleportDelay() : 0); } } From 61b05bcce9b0a3141c34682f19821e2c7cfa7bac Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 16:47:37 +0100 Subject: [PATCH 347/378] Improves some code --- .../stargate/container/RelativeBlockVector.java | 15 +++++---------- .../portal/teleporter/PlayerTeleporter.java | 4 +--- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 925764d..847c7ff 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -58,16 +58,11 @@ public class RelativeBlockVector { * @return

A new relative block vector with the property altered

*/ public RelativeBlockVector addToVector(Property propertyToAddTo, int valueToAdd) { - switch (propertyToAddTo) { - case RIGHT: - return new RelativeBlockVector(this.right + valueToAdd, this.down, this.out); - case DOWN: - return new RelativeBlockVector(this.right, this.down + valueToAdd, this.out); - case OUT: - return new RelativeBlockVector(this.right, this.down, this.out + valueToAdd); - default: - throw new IllegalArgumentException("Invalid relative block vector property given"); - } + return switch (propertyToAddTo) { + case RIGHT -> new RelativeBlockVector(this.right + valueToAdd, this.down, this.out); + case DOWN -> new RelativeBlockVector(this.right, this.down + valueToAdd, this.out); + case OUT -> new RelativeBlockVector(this.right, this.down, this.out + valueToAdd); + }; } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index 4c936bc..3460340 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -72,9 +72,7 @@ public class PlayerTeleporter extends Teleporter { } //Set the velocity of the teleported player after the teleportation is finished - Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> { - player.setVelocity(newVelocity); - }, 1); + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> player.setVelocity(newVelocity), 1); } } From 28bb6f2109c27ec1f8fb26d0a81d367913ee8763 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 17:19:51 +0100 Subject: [PATCH 348/378] Improves the generation of the list of available chat colors --- .../java/net/knarcraft/stargate/Stargate.java | 5 +---- .../stargate/command/CommandStarGate.java | 1 + .../stargate/command/ConfigTabCompleter.java | 20 ++++--------------- .../stargate/config/StargateConfig.java | 1 + .../stargate/config/StargateGateConfig.java | 2 ++ .../listener/PluginEventListener.java | 1 + .../stargate/listener/WorldEventListener.java | 1 + .../net/knarcraft/stargate/portal/Portal.java | 1 + .../stargate/portal/PortalHandler.java | 1 + 9 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 7cb5415..2b659c0 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -45,18 +45,14 @@ import java.util.logging.Logger; @SuppressWarnings("unused") public class Stargate extends JavaPlugin { - //Used for changing gate open/closed material. private static final Queue blockChangeRequestQueue = new LinkedList<>(); private static final Queue chunkUnloadQueue = new PriorityQueue<>(); private static Logger logger; private static Stargate stargate; - private static String pluginVersion; - private static PluginManager pluginManager; private static StargateConfig stargateConfig; - private static String updateAvailable = null; /** @@ -430,4 +426,5 @@ public class Stargate extends JavaPlugin { public static StargateConfig getStargateConfig() { return stargateConfig; } + } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index bd82080..0e759f2 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -35,4 +35,5 @@ public class CommandStarGate implements CommandExecutor { return true; } } + } diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index 693fc26..82b2d79 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -217,22 +217,10 @@ public class ConfigTabCompleter implements TabCompleter { */ private List getChatColors() { List chatColors = new ArrayList<>(); - chatColors.add(ChatColor.WHITE); - chatColors.add(ChatColor.BLUE); - chatColors.add(ChatColor.DARK_BLUE); - chatColors.add(ChatColor.DARK_PURPLE); - chatColors.add(ChatColor.LIGHT_PURPLE); - chatColors.add(ChatColor.GOLD); - chatColors.add(ChatColor.GREEN); - chatColors.add(ChatColor.BLACK); - chatColors.add(ChatColor.DARK_GREEN); - chatColors.add(ChatColor.DARK_RED); - chatColors.add(ChatColor.RED); - chatColors.add(ChatColor.AQUA); - chatColors.add(ChatColor.DARK_AQUA); - chatColors.add(ChatColor.DARK_GRAY); - chatColors.add(ChatColor.GRAY); - chatColors.add(ChatColor.YELLOW); + char[] colors = new char[]{'a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + for (char color : colors) { + chatColors.add(ChatColor.getByChar(color)); + } chatColors.add(ChatColor.of("#ed76d9")); chatColors.add(ChatColor.of("#ffecb7")); return chatColors; diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index d8acd65..7c94a30 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -520,4 +520,5 @@ public final class StargateConfig { public LanguageLoader getLanguageLoader() { return languageLoader; } + } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 47542bd..c848f9d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -16,6 +16,7 @@ import java.util.Map; * The Stargate gate config keeps track of all global config values related to gates */ public final class StargateGateConfig { + private static final int activeTime = 10; private static final int openTime = 10; private final Map configOptions; @@ -320,4 +321,5 @@ public final class StargateGateConfig { PortalSignDrawer.setHighlightColor(ChatColor.WHITE); } } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index a6e0dba..2f70de3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -49,4 +49,5 @@ public class PluginEventListener implements Listener { Stargate.logInfo("Vault plugin lost."); } } + } diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index bd4ccc5..6329d6d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -46,4 +46,5 @@ public class WorldEventListener implements Listener { PortalRegistry.clearPortals(world); } } + } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 93e664f..f42ddb2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -345,4 +345,5 @@ public class Portal { return cleanNetwork.equalsIgnoreCase(other.cleanNetwork); } } + } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index cabff97..44ffb81 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -448,4 +448,5 @@ public class PortalHandler { } return input.replaceAll("[|:#]", "").trim(); } + } From 9e78e32db41e692da45c9f91acf1af536dd73ffc Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 17:20:28 +0100 Subject: [PATCH 349/378] Fixes some spacing --- src/main/java/net/knarcraft/stargate/Stargate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2b659c0..be35747 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -426,5 +426,5 @@ public class Stargate extends JavaPlugin { public static StargateConfig getStargateConfig() { return stargateConfig; } - + } From 00462799b91b2c5b385889e1f87f409c565efcb3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 18:28:47 +0100 Subject: [PATCH 350/378] Fixes the default wait for player after teleport delay --- src/main/java/net/knarcraft/stargate/config/ConfigOption.java | 2 +- .../java/net/knarcraft/stargate/config/StargateGateConfig.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index d460492..f208ed6 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -117,7 +117,7 @@ public enum ConfigOption { */ WAIT_FOR_PLAYER_AFTER_TELEPORT_DELAY("advanced.waitForPlayerAfterTeleportDelay", "The amount of ticks to wait before adding a player as passenger of a vehicle. On slow servers, " + - "a value of 6 is required to avoid client glitches after teleporting on a vehicle.", 1), + "a value of 6 is required to avoid client glitches after teleporting on a vehicle.", 6), /** * Whether to enable economy support for taking payment from players creating/destroying/using stargates diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index c848f9d..053d4b6 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -143,6 +143,9 @@ public final class StargateGateConfig { * @return

The delay to use before adding a player as passenger of a teleported vehicle

*/ public int waitForPlayerAfterTeleportDelay() { + if ((int) configOptions.get(ConfigOption.WAIT_FOR_PLAYER_AFTER_TELEPORT_DELAY) < 2) { + configOptions.put(ConfigOption.WAIT_FOR_PLAYER_AFTER_TELEPORT_DELAY, 6); + } return (int) configOptions.get(ConfigOption.WAIT_FOR_PLAYER_AFTER_TELEPORT_DELAY); } From 4dfce3d3256c8e46d285dc7916155351ad6ecfe2 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 9 Feb 2022 18:37:04 +0100 Subject: [PATCH 351/378] Updates README and version --- README.md | 5 +++++ pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 930c3e8..412929b 100644 --- a/README.md +++ b/README.md @@ -400,6 +400,11 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.5] EpicKnarvik97 fork + +- Fixes the wait for player delay being too low by default +- Performs some minor code optimizations and restructuring + #### \[Version 0.9.3.4] EpicKnarvik97 fork - Includes passengers of passengers when teleporting entities diff --git a/pom.xml b/pom.xml index 08017ba..0626d5a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.4 + 0.9.3.5 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8bba37f..8b0c3c7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.4 +version: 0.9.3.5 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 8c334ff5f0a1e59764573b29c391686b3ed60172 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 15 Feb 2022 18:15:22 +0100 Subject: [PATCH 352/378] Adds simplified chinese, courtesy of YKDZ --- README.md | 6 ++- pom.xml | 2 +- .../stargate/command/CommandAbout.java | 3 +- .../stargate/command/ConfigTabCompleter.java | 1 + src/main/resources/config.yml | 2 +- src/main/resources/lang/zh_cn.txt | 39 +++++++++++++++++++ src/main/resources/plugin.yml | 2 +- 7 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/lang/zh_cn.txt diff --git a/README.md b/README.md index 691ffe7..7413a2c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ can share a network or be split into clusters; they can be hidden on a network o - **Vault economy support** -- can add costs for create, destroy and use. - **Ability to create custom gate configurations**. Four different default gate configurations are available. - **Message customization** -- **Multiple built-in languages** (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) +- **Multiple built-in languages** (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru, zh_cn) - **Teleport across worlds or servers** (BungeeCord supported) - **Vehicle teleportation** -- teleport minecarts, boats, horses, pigs and striders - **Leashed teleportation** -- teleport any creature in a leash with the player @@ -397,6 +397,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.6] EpicKnarvik97 fork + +- Adds the simplified Chinese language file provided by spigot user YKDZ + #### \[Version 0.9.3.3] EpicKnarvik97 fork - Prevents Zombified Piglins from randomly spawning at Stargates diff --git a/pom.xml b/pom.xml index ec9c840..3986d33 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.3 + 0.9.3.6 diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 3e5b441..f0acd50 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -23,8 +23,9 @@ public class CommandAbout implements CommandExecutor { commandSender.sendMessage(textColor + "Go to " + highlightColor + "https://git.knarcraft.net/EpicKnarvik97/Stargate " + textColor + "for the official repository"); String author = Stargate.getStargateConfig().getLanguageLoader().getString("author"); - if (!author.isEmpty()) + if (!author.isEmpty()) { commandSender.sendMessage(textColor + "Language created by " + highlightColor + author); + } return true; } diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index 693fc26..ad32b1b 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -254,6 +254,7 @@ public class ConfigTabCompleter implements TabCompleter { languages.add("nn-no"); languages.add("pt-br"); languages.add("ru"); + languages.add("zh_cn"); //TODO: Generate this list dynamically by listing the language files in the jar and adding the user's custom // language files } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index e3ad5a8..868f139 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ # stargate Configuration File # Main stargate config -# language - The language file to load for messages +# language - The language file to load for messages (de,en,es,fr,hu,it,nb-no,nl,nn-no,pt-br,ru,zh_cn) language: en # adminUpdateAlert - Whether to alert admins about new plugin updates adminUpdateAlert: true diff --git a/src/main/resources/lang/zh_cn.txt b/src/main/resources/lang/zh_cn.txt new file mode 100644 index 0000000..095fa24 --- /dev/null +++ b/src/main/resources/lang/zh_cn.txt @@ -0,0 +1,39 @@ +author=YKDZ +signRightClick=ๅณ้”ฎ +ecoLoadError=Vault ๅทฒๅŠ ่ฝฝ, ไฝ†ๆœชๆฃ€ๆต‹ๅˆฐๅˆ้€‚็š„็ปๆตŽๆ’ไปถ +createConflict=ๆ˜Ÿ้—จไธŽ็Žฐๆœ‰ๆ˜Ÿ้—จๅ†ฒ็ช +invalidMsg=ๆ— ๆ•ˆ็š„็›ฎ็š„ๅœฐ +prefix=[ๆ˜Ÿ้—จ] +ecoObtain=ไปŽๆ˜Ÿ้—จ %portal% ๆ”ถๅ–ไบ† %cost% +vaultLoaded=ๆฃ€ๆต‹ๅˆฐ Vault v%version% +reloaded=ๆ˜Ÿ้—จๆ’ไปถๅทฒ้‡่ฝฝ +bungeeDeny=ไฝ ๆฒกๆœ‰ๅˆ›ๅปบ่ทจๆœๆ˜Ÿ้—จ็š„ๆƒ้™. +signToUse=ไปฅไฝฟ็”จๆ˜Ÿ้—จ +signInvalidGate=ๆœช็Ÿฅๆ˜Ÿ้—จ +bungeeEmpty=่ทจๆœๆ˜Ÿ้—จ้œ€่ฆๆไพ›็›ฎ็š„ๅœฐๅ’Œ็ฝ‘็ปœ. +createMsg=ๆ˜Ÿ้—จๅทฒๅˆ›ๅปบ +bungeeDisabled=่ทจๆœๅŠŸ่ƒฝๅทฒ่ขซ็ฆ็”จ. +blockMsg=็›ฎ็š„ๅœฐ่ขซ้˜ปๆŒก +ecoInFunds=ไฝ™้ขไธ่ถณ +createNameLength=ๅ็งฐ่ฟ‡็Ÿญๆˆ–่ฟ‡้•ฟ. +vaultLoadError=ๆœชๆฃ€ๆต‹ๅˆฐVault. ็ปๆตŽๆจกๅ—ๅทฒ็ฆ็”จ +denyMsg=่ฎฟ้—ฎ่ขซๆ‹’ +ecoDeduct=่Šฑ่ดน %cost% +signDisconnected=ๅทฒๅ–ๆถˆ้“พๆŽฅ +createNetDeny=ไฝ ๆฒกๆœ‰่ฟ™ไธชๆ˜Ÿ้—จ็ฝ‘็ปœ็š„่ฎธๅฏ +bungeeSign=ไผ ้€ๅˆฐ +portalInfoName=ๅ็งฐ: %name% +destroyMsg=ๆ˜Ÿ้—จๅทฒ่ขซ็ ดๅ +portalInfoTitle=[ๆ˜Ÿ้—จไฟกๆฏ] +createExists=ไธŽๅทฒๆœ‰ๆ˜Ÿ้—จ้‡ๅ +teleportMsg=ๅทฒไผ ้€ +createGateDeny=ไฝ ๆฒกๆœ‰ไฝฟ็”จ่ฟ™ไธชๆ˜Ÿ้—จ็ป“ๆž„็š„ๆƒ้™ +signRandom=้šๆœบ +portalInfoServer=ๆœๅŠกๅ™จ: %server% +createWorldDeny=ไฝ ๆฒกๆœ‰้“พๆŽฅ่ฟ™ไธชไธ–็•Œ็š„ๆƒ้™ +portalInfoDestination=็›ฎ็š„ๅœฐ: %destination% +portalInfoNetwork=ๆ˜Ÿ้—จ็ฝ‘็ปœ: %network% +destEmpty=็›ฎ็š„ๅœฐๅˆ—่กจไธบ็ฉบ +createPersonal=ๅœจ็งไบบ็ฝ‘็ปœไธญๅˆ›ๅปบๆ˜Ÿ้—จ +ecoRefund=้€€ๆฌพ %cost% +createFull=ๆญคๆ˜Ÿ้—จ็ฝ‘็ปœๅทฒๆปก \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0a9a6ed..dcab0db 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.3 +version: 0.9.3.6 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 8488c5abdb0e65fd369946ffb56cb676b39b72c1 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 15 Feb 2022 18:21:42 +0100 Subject: [PATCH 353/378] Fixes some after-merge problems --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b4912cc..a72ad3d 100644 --- a/README.md +++ b/README.md @@ -343,7 +343,7 @@ advanced: # Message Customization -It is possible to customize all the messages Stargate displays, including the [Stargate] prefix. You can find the +It is possible to customize all the messages Stargate displays, including the \[Stargate] prefix. You can find the strings in plugins/Stargate/lang/chosenLanguage.txt. If a string is removed, or left blank, it will default to the default english string. There are some special cases @@ -400,6 +400,15 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.6] EpicKnarvik97 fork + +- Adds the simplified Chinese language file provided by spigot user YKDZ + +#### \[Version 0.9.3.5] EpicKnarvik97 fork + +- Fixes the wait for player delay being too low by default +- Performs some minor code optimizations and restructuring + #### \[Version 0.9.3.4] EpicKnarvik97 fork - Includes passengers of passengers when teleporting entities @@ -409,10 +418,6 @@ portalInfoServer=Server: %server% and the player being teleported to the vehicle - Makes boats keep their wood type even when re-created -#### \[Version 0.9.3.6] EpicKnarvik97 fork - -- Adds the simplified Chinese language file provided by spigot user YKDZ - #### \[Version 0.9.3.3] EpicKnarvik97 fork - Prevents Zombified Piglins from randomly spawning at Stargates From 0c69dc8991840f800b83f99cd73c5cb2cf973d7d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 17 Feb 2022 20:08:24 +0100 Subject: [PATCH 354/378] Adds the Japanese language file provided by spigot user furplag (0.9.3.7) --- README.md | 8 +++- pom.xml | 2 +- .../stargate/command/ConfigTabCompleter.java | 1 + src/main/resources/config.yml | 2 +- src/main/resources/lang/ja.txt | 44 +++++++++++++++++++ src/main/resources/plugin.yml | 2 +- 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/lang/ja.txt diff --git a/README.md b/README.md index a72ad3d..86cb561 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ can share a network or be split into clusters; they can be hidden on a network o - **Vault economy support** -- can add costs for create, destroy and use. - **Ability to create custom gate configurations**. Four different default gate configurations are available. - **Message customization** -- **Multiple built-in languages** (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru, zh_cn) +- **Multiple built-in languages** (de, en, es, fr, hu, it, ja, nb-no, nl, nn-no, pt-br, ru, zh_cn) - **Teleport across worlds or servers** (BungeeCord supported) - **Vehicle teleportation** -- teleport minecarts, boats, horses, pigs and striders - **Leashed teleportation** -- teleport any creature in a leash with the player @@ -298,7 +298,7 @@ while the per-gate costs re defined in the .gate files. To define a certain cost # Configuration ``` -language - The language to use (Included languages: en, de, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru) +language - The language to use (Included languages: en, de, es, fr, hu, it, ja, nb-no, nl, nn-no, pt-br, ru, zh_cn) adminUpdateAlert - Whether to alert admins about an available update when joining the server folders: portalFolder - The folder your portal databases are saved in @@ -400,6 +400,10 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.3.7] EpicKnarvik97 fork + +- Adds the Japanese language file provided by spigot user furplag + #### \[Version 0.9.3.6] EpicKnarvik97 fork - Adds the simplified Chinese language file provided by spigot user YKDZ diff --git a/pom.xml b/pom.xml index 31c5a3e..38a5365 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.6 + 0.9.3.7 diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index 50fb387..cb5447d 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -237,6 +237,7 @@ public class ConfigTabCompleter implements TabCompleter { languages.add("fr"); languages.add("hu"); languages.add("it"); + languages.add("ja"); languages.add("nb-no"); languages.add("nl"); languages.add("nn-no"); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6d52efb..f78aaed 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ # stargate Configuration File # Main stargate config -# language - The language file to load for messages (de,en,es,fr,hu,it,nb-no,nl,nn-no,pt-br,ru,zh_cn) +# language - The language file to load for messages (de,en,es,fr,hu,it,ja,nb-no,nl,nn-no,pt-br,ru,zh_cn) language: en # adminUpdateAlert - Whether to alert admins about new plugin updates adminUpdateAlert: true diff --git a/src/main/resources/lang/ja.txt b/src/main/resources/lang/ja.txt new file mode 100644 index 0000000..56c2b1d --- /dev/null +++ b/src/main/resources/lang/ja.txt @@ -0,0 +1,44 @@ +author=furplag +prefix=[Stargate] +teleportMsg=ใƒ†ใƒฌใƒใƒผใƒˆ +destroyMsg=ใ‚ฒใƒผใƒˆใŒ็ ดๅฃŠใ•ใ‚Œใพใ—ใŸ +invalidMsg=็„กๅŠนใช่กŒใๅ…ˆ +blockMsg=ใƒ–ใƒญใƒƒใ‚ฏใ•ใ‚ŒใŸ่กŒใๅ…ˆ +destEmpty=่กŒใๅ…ˆใƒชใ‚นใƒˆใŒ็ฉบใงใ™ +denyMsg=ใ‚ขใ‚ฏใ‚ปใ‚นใŒๆ‹’ๅฆใ•ใ‚Œใพใ—ใŸ +reloaded= Stargate ใ‚’ใƒชใƒญใƒผใƒ‰ใ—ใพใ—ใŸ + +ecoDeduct=๏ผ…cost๏ผ… ใฎๅ€คๅผ•ใ +ecoRefund=๏ผ…cost๏ผ… ใฎ่ฟ”้‡‘ +ecoObtain= Stargate ๏ผ…portal๏ผ… ใ‹ใ‚‰ ๏ผ…cost๏ผ… ใ‚’ๅพ—ใพใ—ใŸ +ecoInFunds=่ณ‡้‡‘ใฎไธ่ถณ +ecoLoadError= Vault ใŒ่ชญใฟ่พผใพใ‚Œใพใ—ใŸใŒใ€Economy ใƒ—ใƒฉใ‚ฐใ‚คใƒณใ‚’ใƒ•ใƒƒใ‚ฏใงใใพใ›ใ‚“ใงใ—ใŸ +vaultLoadError=Economy ใฏๆœ‰ๅŠนใซใชใฃใฆใ„ใพใ™ใŒใ€Vault ใ‚’ใƒญใƒผใƒ‰ใงใใชใ„ใŸใ‚ Economy ใฏ็„กๅŠนๅŒ–ใ•ใ‚Œใพใ—ใŸ +vaultLoaded= Vault v๏ผ…version๏ผ… ใŒ่ฆ‹ใคใ‹ใ‚Šใพใ—ใŸ + +createMsg=ใ‚ฒใƒผใƒˆใŒไฝœๆˆใ•ใ‚Œใพใ—ใŸ +createNetDeny=ๅฏพ่ฑกใฎใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใซใ‚ขใ‚ฏใ‚ปใ‚นใงใใพใ›ใ‚“ +createGateDeny=ๅฏพ่ฑกใฎใ‚ฒใƒผใƒˆใƒฌใ‚คใ‚ขใ‚ฆใƒˆใซใ‚ขใ‚ฏใ‚ปใ‚นใงใใพใ›ใ‚“ +createPersonal=ใƒ‘ใƒผใ‚ฝใƒŠใƒซใƒใƒƒใƒˆใƒฏใƒผใ‚ฏไธŠใซใ‚ฒใƒผใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ +createNameLength=ใ‚ฒใƒผใƒˆๅใŒ็Ÿญใ™ใŽใ‚‹ใ‹้•ทใ™ใŽใพใ™ +createExists=ใ™ใงใซๅญ˜ๅœจใ™ใ‚‹ใ‚ฒใƒผใƒˆๅใงใ™ +createFull=ๅฏพ่ฑกใฎใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใฏใ„ใฃใฑใ„ใงใ™ +createWorldDeny=ใ‚ใชใŸใฏใใฎไธ–็•Œใซใ‚ขใ‚ฏใ‚ปใ‚นใงใใพใ›ใ‚“ +createConflict=ใ‚ฒใƒผใƒˆใŒๆ—ขๅญ˜ใฎใ‚ฒใƒผใƒˆใจ็ซถๅˆใ—ใฆใ„ใพใ™ + +signRightClick=ๅณใ‚ฏใƒชใƒƒใ‚ฏ +signToUse=ใ‚ฒใƒผใƒˆใ‚’ไฝฟ็”จใ™ใ‚‹ +signRandom=ใƒฉใƒณใƒ€ใƒ  +signDisconnected=ๅˆ‡ๆ–ญ +signInvalidGate=็„กๅŠนใชใ‚ฒใƒผใƒˆ + +bungeeDisabled=BungeeCord ใ‚ตใƒใƒผใƒˆใฏ็„กๅŠนใซใชใฃใฆใ„ใพใ™ +bungeeDeny=BungeeCord ใ‚ฒใƒผใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ๆจฉ้™ใŒใ‚ใ‚Šใพใ›ใ‚“ +bungeeEmpty=BungeeCord ใ‚ฒใƒผใƒˆใซใฏใ€่กŒใๅ…ˆใจใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใฎไธกๆ–นใŒๅฟ…่ฆใงใ™ +bungeeSign=ใƒ†ใƒฌใƒใƒผใƒˆๅ…ˆ: + +portalInfoTitle=[STARGATE INFO] +portalInfoName=ใ‚ฒใƒผใƒˆๅ: ๏ผ…name๏ผ… +portalInfoDestination=่กŒใๅ…ˆ: ๏ผ…destination๏ผ… +portalInfoNetwork=ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏ: ๏ผ…network๏ผ… +portalInfoServer=ใ‚ตใƒผใƒใƒผ: ๏ผ…server๏ผ… diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index dcab0db..460e2bf 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.6 +version: 0.9.3.7 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 6eb7649e0dbe94b188651d01a2f2606ec4f0a0e3 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 11 Mar 2022 17:10:10 +0100 Subject: [PATCH 355/378] Clarifies license to prevent any disputes --- HEADER | 19 +++++++++++++++ README.md | 5 ++++ .../java/net/knarcraft/stargate/Stargate.java | 24 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 HEADER diff --git a/HEADER b/HEADER new file mode 100644 index 0000000..126ab6a --- /dev/null +++ b/HEADER @@ -0,0 +1,19 @@ +Stargate - A portal plugin for Bukkit +Copyright (C) 2011 Shaun (sturmeh) +Copyright (C) 2011 Dinnerbone +Copyright (C) 2011-2013 Steven "Drakia" Scott +Copyright (C) 2015-2020 Michael Smith (PseudoKnight) +Copyright (C) 2021-2022 Kristian Knarvik (EpicKnarvik97) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . \ No newline at end of file diff --git a/README.md b/README.md index 86cb561..4a4ebcd 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,11 @@ This was originally TheDgtl's Bukkit port of the Stargate plugin for hMod by Din of [PseudoKnight's fork](https://github.com/PseudoKnight/Stargate-Bukkit). This fork's main purpose is to create a clean version of Stargate compliant with Spigot 1.17, even if it means changing the entire project's previous structure. +## License + +Stargate is licensed under GNU Lesser General Public License. This includes every source and resource file. See the +HEADER file for a more detailed license description. + ## Migration This plugin should be compatible with configurations from the Stargate plugin all the way back. The nethergate.gate diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index be35747..b9ed27d 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -39,6 +39,30 @@ import java.util.Queue; import java.util.logging.Level; import java.util.logging.Logger; +/* +Stargate - A portal plugin for Bukkit +Copyright (C) 2011 Shaun (sturmeh) +Copyright (C) 2011 Dinnerbone +Copyright (C) 2011-2013 Steven "Drakia" Scott +Copyright (C) 2015-2020 Michael Smith (PseudoKnight) +Copyright (C) 2021-2022 Kristian Knarvik (EpicKnarvik97) + +The following license notice applies to all source and resource files in the Stargate project: + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . + */ + /** * The main class of the Stargate plugin */ From 92f452df002cdd62a624ab8b0c03a065cf9056ad Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 11 Mar 2022 17:16:26 +0100 Subject: [PATCH 356/378] Adds LGPL version to the README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a4ebcd..de6d2a0 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ version of Stargate compliant with Spigot 1.17, even if it means changing the en ## License -Stargate is licensed under GNU Lesser General Public License. This includes every source and resource file. See the -HEADER file for a more detailed license description. +Stargate is licensed under the GNU Lesser General Public License Version 3.0. This includes every source and resource +file. See the HEADER file for a more detailed license description. ## Migration From 92c3eadf8f2e1f8b99ddddd3bb0ec4b8bfac0903 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 17 Jun 2022 12:40:15 +0200 Subject: [PATCH 357/378] Updates Stargate for Spigot 1.19 --- README.md | 2 +- pom.xml | 4 ++-- .../knarcraft/stargate/command/CommandConfig.java | 3 +-- .../stargate/command/CommandStarGate.java | 5 +++-- .../stargate/command/StarGateTabCompleter.java | 4 ++-- .../stargate/listener/PlayerEventListener.java | 15 +++++++++------ src/main/resources/config.yml | 8 ++++---- src/main/resources/plugin.yml | 4 ++-- 8 files changed, 24 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index de6d2a0..05785ef 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ version of Stargate compliant with Spigot 1.17, even if it means changing the en ## License -Stargate is licensed under the GNU Lesser General Public License Version 3.0. This includes every source and resource +Stargate is licensed under the GNU Lesser General Public License Version 3.0. This includes every source and resource file. See the HEADER file for a more detailed license description. ## Migration diff --git a/pom.xml b/pom.xml index 38a5365..2bbc01f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.3.7 + 0.9.4.0 @@ -34,7 +34,7 @@ org.spigotmc spigot-api - 1.18.1-R0.1-SNAPSHOT + 1.19-R0.1-SNAPSHOT net.milkbowl.vault diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index ca2f2fa..35d3c1c 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -8,7 +8,6 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.PortalSignDrawer; import net.md_5.bungee.api.ChatColor; -import org.apache.commons.lang.StringUtils; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -416,7 +415,7 @@ public class CommandConfig implements CommandExecutor { Object defaultValue = option.getDefaultValue(); String stringValue = String.valueOf(defaultValue); if (option.getDataType() == OptionDataType.STRING_LIST) { - stringValue = "[" + StringUtils.join((String[]) defaultValue, ",") + "]"; + stringValue = "[" + String.join(",", (String[]) defaultValue) + "]"; } return ChatColor.GOLD + option.getName() + ChatColor.WHITE + " - " + ChatColor.GREEN + option.getDescription() + ChatColor.DARK_GRAY + " (Default: " + ChatColor.GRAY + stringValue + ChatColor.DARK_GRAY + ")"; diff --git a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java index 0e759f2..2185b54 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandStarGate.java @@ -2,12 +2,13 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; import net.md_5.bungee.api.ChatColor; -import org.apache.commons.lang.ArrayUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; + /** * This command represents any command which starts with stargate * @@ -25,7 +26,7 @@ public class CommandStarGate implements CommandExecutor { } else if (args[0].equalsIgnoreCase("reload")) { return new CommandReload().onCommand(commandSender, command, s, args); } else if (args[0].equalsIgnoreCase("config")) { - String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + String[] subArgs = Arrays.copyOfRange(args, 1, args.length); return new CommandConfig().onCommand(commandSender, command, s, subArgs); } return false; diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index d67b4db..96ecd3d 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -1,6 +1,5 @@ package net.knarcraft.stargate.command; -import org.apache.commons.lang.ArrayUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; @@ -9,6 +8,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -29,7 +29,7 @@ public class StarGateTabCompleter implements TabCompleter { } return matchingCommands; } else if (args.length > 1 && args[0].equalsIgnoreCase("config")) { - String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + String[] subArgs = Arrays.copyOfRange(args, 1, args.length); return new ConfigTabCompleter().onTabComplete(commandSender, command, s, subArgs); } else { return new ArrayList<>(); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index ff28930..254a24d 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -230,11 +230,14 @@ public class PlayerEventListener implements Listener { EquipmentSlot hand = event.getHand(); if (hand != null && (PermissionHelper.hasPermission(player, "stargate.admin.dye") || portal.isOwner(player))) { - String itemName = player.getInventory().getItem(hand).getType().toString(); - if (itemName.endsWith("DYE") || itemName.endsWith("INK_SAC")) { - event.setUseInteractedBlock(Event.Result.ALLOW); - Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), portal::drawSign, 1); - return; + ItemStack item = player.getInventory().getItem(hand); + if (item != null) { + String itemName = item.getType().toString(); + if (itemName.endsWith("DYE") || itemName.endsWith("INK_SAC")) { + event.setUseInteractedBlock(Event.Result.ALLOW); + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), portal::drawSign, 1); + return; + } } } @@ -325,7 +328,7 @@ public class PlayerEventListener implements Listener { } else { //Display information about the portal if it has no sign ItemStack heldItem = player.getInventory().getItem(hand); - if (heldItem.getType().isAir() || !heldItem.getType().isBlock()) { + if (heldItem != null && (heldItem.getType().isAir() || !heldItem.getType().isBlock())) { displayPortalInfo(block, player); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f78aaed..66c790a 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -57,9 +57,9 @@ gates: # enableCraftBookRemoveOnEjectFix - Whether to enable a fix that causes loss of NBT data, but allows vehicle teleportation to work when CraftBook's remove minecart/boat on eject setting is enabled enableCraftBookRemoveOnEjectFix: false -# I------------I-------------I # +############################# # stargate economy options # -# I------------I-------------I # +############################ economy: # useEconomy - Whether to use an economy plugin useEconomy: false @@ -78,9 +78,9 @@ economy: # freeGatesColor - The color to use for marking free gates freeGatesColor: DARK_GREEN -# I-------I-------I # +################# # Debug options # -# I-------I-------I # +################# debugging: # debug - Debug -- Only enable if you have issues, massive console output debug: false diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 460e2bf..f2bbaa1 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,11 +1,11 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.3.7 +version: 0.9.4.0 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] website: https://git.knarcraft.net/EpicKnarvik97/Stargate -api-version: 1.18 +api-version: 1.19 softdepend: [ Vault ] commands: stargate: From 643a48392b083a255611e71ade8065ddf0c5f1fd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 18 Jun 2022 16:05:05 +0200 Subject: [PATCH 358/378] Adds Dynmap integration This adds Dynmap integration for displaying Stargates in Dynmap API version is changed back to 1.18 as 1.19 is still kind of new Version is now 0.9.4.1 --- pom.xml | 11 +- .../stargate/command/CommandConfig.java | 5 + .../stargate/config/ConfigOption.java | 13 +- .../knarcraft/stargate/config/ConfigTag.java | 13 +- .../stargate/config/DynmapManager.java | 124 ++++++++++++++++++ .../stargate/config/StargateConfig.java | 27 ++++ .../stargate/portal/PortalRegistry.java | 3 + src/main/resources/config.yml | 38 ++++-- src/main/resources/plugin.yml | 6 +- 9 files changed, 223 insertions(+), 17 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/config/DynmapManager.java diff --git a/pom.xml b/pom.xml index 2bbc01f..313190c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.4.0 + 0.9.4.1 @@ -28,6 +28,10 @@ vault-repo http://nexus.hc.to/content/repositories/pub_releases + + dynmap + https://repo.mikeprimm.com/ +
@@ -65,6 +69,11 @@ 4.13.2 test + + us.dynmap + dynmap-api + 3.1-beta-2 + diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 35d3c1c..6374518 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.command; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.ConfigOption; import net.knarcraft.stargate.config.ConfigTag; +import net.knarcraft.stargate.config.DynmapManager; import net.knarcraft.stargate.config.OptionDataType; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalRegistry; @@ -377,6 +378,10 @@ public class CommandConfig implements CommandExecutor { //Load or unload Vault and Economy as necessary Stargate.getStargateConfig().reloadEconomy(); } + if (ConfigTag.requiresDynmapReload(configOption)) { + //Regenerate all Dynmap markers + DynmapManager.addAllPortalMarkers(); + } } } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index f208ed6..e12ea59 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -178,7 +178,18 @@ public enum ConfigOption { /** * The velocity of players exiting a stargate, relative to the entry velocity */ - EXIT_VELOCITY("gates.exitVelocity", "The velocity of players exiting stargates, relative to the entry velocity", 0.1D); + EXIT_VELOCITY("gates.exitVelocity", "The velocity of players exiting stargates, relative to the entry velocity", 0.1D), + + /** + * Whether to enable showing Stargates in Dynmap + */ + ENABLE_DYNMAP("dynmap.enableDynmap", "Whether to display Stargates in Dynmap's map", true), + + /** + * Whether to hide Dynmap icons by default + */ + DYNMAP_ICONS_DEFAULT_HIDDEN("dynmap.dynmapIconsHiddenByDefault", + "Whether to hide Stargate's Dynmap icons by default, requiring the user to enable them.", true); private final String configNode; private final String description; diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java index 49c9083..024b205 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java @@ -9,7 +9,8 @@ public enum ConfigTag { COLOR(new ConfigOption[]{ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, ConfigOption.HIGHLIGHT_SIGN_COLOR, ConfigOption.PER_SIGN_COLORS}), - FOLDER(new ConfigOption[]{ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER}); + FOLDER(new ConfigOption[]{ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER}), + DYNMAP(new ConfigOption[]{ConfigOption.ENABLE_DYNMAP, ConfigOption.DYNMAP_ICONS_DEFAULT_HIDDEN}); private final ConfigOption[] taggedOptions; @@ -52,6 +53,16 @@ public enum ConfigTag { return FOLDER.isTagged(option); } + /** + * Checks whether a given config option requires a re-load of all Dynmap markers + * + * @param configOption

The config option to check

+ * @return

True if changing the config option requires a reload of all dynmap markers

+ */ + public static boolean requiresDynmapReload(ConfigOption configOption) { + return DYNMAP.isTagged(configOption); + } + /** * Checks whether a given config option requires a portal reload to take effect * diff --git a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java new file mode 100644 index 0000000..a649a1a --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java @@ -0,0 +1,124 @@ +package net.knarcraft.stargate.config; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalRegistry; +import org.bukkit.Location; +import org.bukkit.World; +import org.dynmap.DynmapAPI; +import org.dynmap.markers.GenericMarker; +import org.dynmap.markers.Marker; +import org.dynmap.markers.MarkerIcon; +import org.dynmap.markers.MarkerSet; + +/** + * A manager for dealing with everything Dynmap + */ +public final class DynmapManager { + + private static MarkerSet markerSet; + private static MarkerIcon portalIcon; + + private DynmapManager() { + + } + + /** + * Initializes the dynmap manager + * + * @param dynmapAPI

A reference

+ */ + public static void initialize(DynmapAPI dynmapAPI) { + if (dynmapAPI == null) { + markerSet = null; + portalIcon = null; + } else { + markerSet = dynmapAPI.getMarkerAPI().createMarkerSet("stargate", "Stargate", null, false); + markerSet.setHideByDefault(Stargate.getStargateConfig().hideDynmapIcons()); + portalIcon = dynmapAPI.getMarkerAPI().getMarkerIcon("portal"); + } + } + + /** + * Adds all portal markers for all current portals + */ + public static void addAllPortalMarkers() { + if (markerSet == null || Stargate.getStargateConfig().isDynmapDisabled()) { + //Remove any existing markers if dynmap has been disabled after startup + if (markerSet != null) { + markerSet.getMarkers().forEach(GenericMarker::deleteMarker); + } + return; + } + markerSet.setHideByDefault(Stargate.getStargateConfig().hideDynmapIcons()); + //Remove all existing markers for a clean start + markerSet.getMarkers().forEach(GenericMarker::deleteMarker); + + for (Portal portal : PortalRegistry.getAllPortals()) { + addPortalMarker(portal); + } + } + + /** + * Adds a portal marker for the given portal + * + * @param portal

The portal to add a marker for

+ */ + public static void addPortalMarker(Portal portal) { + if (markerSet == null || Stargate.getStargateConfig().isDynmapDisabled()) { + return; + } + World world = portal.getWorld(); + if (portal.getOptions().isHidden() || world == null) { + return; + } + + Location location = portal.getBlockAt(portal.getGate().getLayout().getExit()); + Marker marker = markerSet.createMarker(getPortalMarkerId(portal), portal.getName(), world.getName(), + location.getX(), location.getY(), location.getZ(), portalIcon, false); + if (marker == null) { + Stargate.logWarning(String.format( + """ + Unable to create marker for portal + Portal marker id: %s + Portal name: %s + Portal world: %s + Portal location: %s,%s,%s""", + getPortalMarkerId(portal), portal.getName(), world.getName(), location.getX(), location.getY(), + location.getZ())); + return; + } + String markerDescription = String.format("Name: %s
Network: %s
Destination: " + + "%s
Owner: %s
", portal.getName(), portal.getNetwork(), + portal.getDestinationName(), portal.getOwner().getName()); + marker.setDescription(markerDescription); + marker.setLabel(portal.getName(), true); + marker.setMarkerIcon(portalIcon); + } + + /** + * Removes the portal marker for the given portal + * + * @param portal

The portal to remove the marker for

+ */ + public static void removePortalMarker(Portal portal) { + if (markerSet == null || Stargate.getStargateConfig().isDynmapDisabled()) { + return; + } + Marker marker = markerSet.findMarker(getPortalMarkerId(portal)); + if (marker != null) { + marker.deleteMarker(); + } + } + + /** + * Gets the id used for the given portal's marker + * + * @param portal

The portal to get a marker id for

+ * @return

+ */ + private static String getPortalMarkerId(Portal portal) { + return portal.getNetwork() + "-:-" + portal.getName(); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 7c94a30..b718d8b 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -15,6 +15,7 @@ import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.messaging.Messenger; +import org.dynmap.DynmapAPI; import java.io.File; import java.io.IOException; @@ -101,6 +102,11 @@ public final class StargateConfig { //Set up vault economy if vault has been loaded setupVaultEconomy(); + DynmapAPI dynmapAPI = (DynmapAPI) Bukkit.getPluginManager().getPlugin("dynmap"); + if (dynmapAPI != null) { + DynmapManager.initialize(dynmapAPI); + DynmapManager.addAllPortalMarkers(); + } } /** @@ -152,6 +158,24 @@ public final class StargateConfig { return (boolean) configOptions.get(ConfigOption.PERMISSION_DEBUG); } + /** + * Gets whether Dynmap integration is disabled + * + * @return

Whether Dynmap integration is disabled

+ */ + public boolean isDynmapDisabled() { + return !((boolean) configOptions.get(ConfigOption.ENABLE_DYNMAP)); + } + + /** + * Gets whether Dynmap icons should be hidden by default + * + * @return

Whether Dynmap icons should be hidden by default

+ */ + public boolean hideDynmapIcons() { + return (boolean) configOptions.get(ConfigOption.DYNMAP_ICONS_DEFAULT_HIDDEN); + } + /** * Gets the object containing economy config values * @@ -189,6 +213,9 @@ public final class StargateConfig { startStopBungeeListener(stargateGateConfig.enableBungee()); } + //Reload portal markers + DynmapManager.addAllPortalMarkers(); + messageSender.sendErrorMessage(sender, languageLoader.getString("reloaded")); } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index 74faa96..fe07562 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.DynmapManager; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.World; @@ -224,6 +225,7 @@ public class PortalRegistry { PortalFileHelper.saveAllPortals(portal.getWorld()); portal.setRegistered(false); + DynmapManager.removePortalMarker(portal); } /** @@ -289,6 +291,7 @@ public class PortalRegistry { allPortals.add(portal); portal.setRegistered(true); + DynmapManager.addPortalMarker(portal); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 66c790a..b8d6dbc 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -40,7 +40,8 @@ gates: destroyedByExplosion: false # verifyPortals - Whether all the non-sign blocks are checked to match the gate layout when a stargate is loaded. verifyPortals: false - # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material) + # protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using + # destroyable open/closed material) protectEntrance: false functionality: enableBungee: false @@ -48,18 +49,21 @@ gates: handleVehicles: true # handleEmptyVehicles - Whether to allow empty vehicles through gates (chest/hopper/tnt/furnace minecarts included) handleEmptyVehicles: true - # handleCreatureTransportation - Whether to allow players to transport creatures by sending vehicles (minecarts, boats) through gates + # handleCreatureTransportation - Whether to allow players to transport creatures by sending vehicles (minecarts, + # boats) through gates handleCreatureTransportation: true - # handleNonPlayerVehicles - Whether to allow vehicles with a passenger which is not a player through gates. handleCreatureTransportation must be enabled + # handleNonPlayerVehicles - Whether to allow vehicles with a passenger which is not a player through gates. + # handleCreatureTransportation must be enabled handleNonPlayerVehicles: true # handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player handleLeashedCreatures: true - # enableCraftBookRemoveOnEjectFix - Whether to enable a fix that causes loss of NBT data, but allows vehicle teleportation to work when CraftBook's remove minecart/boat on eject setting is enabled + # enableCraftBookRemoveOnEjectFix - Whether to enable a fix that causes loss of NBT data, but allows vehicle + # teleportation to work when CraftBook's remove minecart/boat on eject setting is enabled enableCraftBookRemoveOnEjectFix: false -############################# +# ######################## # # stargate economy options # -############################ +# ######################## # economy: # useEconomy - Whether to use an economy plugin useEconomy: false @@ -78,14 +82,26 @@ economy: # freeGatesColor - The color to use for marking free gates freeGatesColor: DARK_GREEN -################# +# ############# # # Debug options # -################# +# ############# # debugging: # debug - Debug -- Only enable if you have issues, massive console output debug: false - # permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging (Requires debug: true) + # permissionDebug - This will output any and all Permissions checks to console, used for permissions debugging + # (Requires debug: true) permissionDebug: false advanced: - # waitForPlayerAfterTeleportDelay - The amount of ticks to wait before adding a player as passenger of a vehicle. On slow servers, a value of 6 is required to avoid client glitches after teleporting on a vehicle. - waitForPlayerAfterTeleportDelay: 6 \ No newline at end of file + # waitForPlayerAfterTeleportDelay - The amount of ticks to wait before adding a player as passenger of a vehicle. + # On slow servers, a value of 6 is required to avoid client glitches after teleporting on a vehicle. + waitForPlayerAfterTeleportDelay: 6 + +# ############## # +# Dynmap options # +# ############## # +dynmap: + # enableDynmap - Whether to display Stargates in Dynmap's map + enableDynmap: true + # dynmapIconsHiddenByDefault - Whether to hide the set of Stargate icons by default, requiring users to + # manually enable them with a checkbox. + dynmapIconsHiddenByDefault: true \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f2bbaa1..c717434 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,12 +1,12 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.4.0 +version: 0.9.4.1 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] website: https://git.knarcraft.net/EpicKnarvik97/Stargate -api-version: 1.19 -softdepend: [ Vault ] +api-version: 1.18 +softdepend: [ Vault, dynmap ] commands: stargate: aliases: From cae34d395b3ec3be621cd4868cf08bca1c1438eb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 18 Jun 2022 16:16:36 +0200 Subject: [PATCH 359/378] Displays bungee markers properly --- .../net/knarcraft/stargate/config/DynmapManager.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java index a649a1a..781b7c6 100644 --- a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java +++ b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java @@ -88,8 +88,14 @@ public final class DynmapManager { location.getZ())); return; } - String markerDescription = String.format("Name: %s
Network: %s
Destination: " + - "%s
Owner: %s
", portal.getName(), portal.getNetwork(), + String networkPrompt; + if (portal.getOptions().isBungee()) { + networkPrompt = "Server"; + } else { + networkPrompt = "Network"; + } + String markerDescription = String.format("Name: %s
%s: %s
Destination: " + + "%s
Owner: %s
", portal.getName(), networkPrompt, portal.getNetwork(), portal.getDestinationName(), portal.getOwner().getName()); marker.setDescription(markerDescription); marker.setLabel(portal.getName(), true); From ce5f3ef52fb81059c0b968b5ba343f039c77330a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 24 Jun 2022 03:23:59 +0200 Subject: [PATCH 360/378] Avoids a NullPointerException if dynmap is present, but isn't loaded properly --- src/main/java/net/knarcraft/stargate/config/DynmapManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java index 781b7c6..edfc70c 100644 --- a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java +++ b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java @@ -29,7 +29,7 @@ public final class DynmapManager { * @param dynmapAPI

A reference

*/ public static void initialize(DynmapAPI dynmapAPI) { - if (dynmapAPI == null) { + if (dynmapAPI == null || dynmapAPI.getMarkerAPI() == null) { markerSet = null; portalIcon = null; } else { From 524130c4e0b9616b1e50f70e2d4cd6f43634c9b4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 24 Jun 2022 03:33:49 +0200 Subject: [PATCH 361/378] Avoids some potential NullPointerExceptions related to dynmap integration --- .../java/net/knarcraft/stargate/config/DynmapManager.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java index edfc70c..5eaa0c9 100644 --- a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java +++ b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java @@ -34,7 +34,9 @@ public final class DynmapManager { portalIcon = null; } else { markerSet = dynmapAPI.getMarkerAPI().createMarkerSet("stargate", "Stargate", null, false); - markerSet.setHideByDefault(Stargate.getStargateConfig().hideDynmapIcons()); + if (markerSet != null) { + markerSet.setHideByDefault(Stargate.getStargateConfig().hideDynmapIcons()); + } portalIcon = dynmapAPI.getMarkerAPI().getMarkerIcon("portal"); } } @@ -99,7 +101,9 @@ public final class DynmapManager { portal.getDestinationName(), portal.getOwner().getName()); marker.setDescription(markerDescription); marker.setLabel(portal.getName(), true); - marker.setMarkerIcon(portalIcon); + if (portalIcon != null) { + marker.setMarkerIcon(portalIcon); + } } /** From 2076fda4d1f9439cdbb9e62fb2f5d9a3f1754c48 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 25 Jun 2022 10:54:19 +0200 Subject: [PATCH 362/378] Fixes end portals completely hijacking BungeeCord teleportation --- .../knarcraft/stargate/listener/PortalEventListener.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 146f87a..4ceff5c 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -70,11 +70,13 @@ public class PortalEventListener implements Listener { //Remove any old player teleportations in case weird things happen playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player)); //Decide if the anything stops the player from teleporting - if (PermissionHelper.playerCannotTeleport(portal, portal.getPortalActivator().getDestination(), player, null)) { + if (PermissionHelper.playerCannotTeleport(portal, portal.getPortalActivator().getDestination(), player, null) || + portal.getOptions().isBungee()) { //Teleport the player back to the portal they came in, just in case playersFromTheEnd.add(new FromTheEndTeleportation(player, portal)); + } else { + playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getPortalActivator().getDestination())); } - playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getPortalActivator().getDestination())); } } From 1c87d803ffcaa4d71334088e573c8c21d6134bbe Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 25 Jun 2022 11:53:52 +0200 Subject: [PATCH 363/378] Adds a delayed teleport to really force the player respawn for end_portal Stargate --- .../listener/PortalEventListener.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index 4ceff5c..c81640f 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -6,6 +6,7 @@ import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import net.knarcraft.stargate.utility.PermissionHelper; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -67,6 +68,9 @@ public class PortalEventListener implements Listener { return; } + Stargate.debug("PortalEventListener::onEntityPortalEnter", + "Found player " + player + " entering END_PORTAL " + portal); + //Remove any old player teleportations in case weird things happen playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player)); //Decide if the anything stops the player from teleporting @@ -74,8 +78,12 @@ public class PortalEventListener implements Listener { portal.getOptions().isBungee()) { //Teleport the player back to the portal they came in, just in case playersFromTheEnd.add(new FromTheEndTeleportation(player, portal)); + Stargate.debug("PortalEventListener::onEntityPortalEnter", + "Sending player back to the entrance"); } else { playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getPortalActivator().getDestination())); + Stargate.debug("PortalEventListener::onEntityPortalEnter", + "Sending player to destination"); } } } @@ -97,9 +105,18 @@ public class PortalEventListener implements Listener { Portal exitPortal = teleportation.getExit(); //Overwrite respawn location to respawn in front of the portal - event.setRespawnLocation(new PlayerTeleporter(exitPortal, respawningPlayer).getExit()); + PlayerTeleporter teleporter = new PlayerTeleporter(exitPortal, respawningPlayer); + Location respawnLocation = teleporter.getExit(); + event.setRespawnLocation(respawnLocation); + //Try and force the player if for some reason the changing of respawn location isn't properly handled + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> + respawningPlayer.teleport(respawnLocation), 1); + //Properly close the portal to prevent it from staying in a locked state until it times out exitPortal.getPortalOpener().closePortal(false); + + Stargate.debug("PortalEventListener::onRespawn", "Overwriting respawn for " + respawningPlayer + + " to " + respawnLocation.getWorld() + ":" + respawnLocation); } } From 11d3dc7a9233f3891b1eb81435fa906eac244073 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 25 Jun 2022 12:11:37 +0200 Subject: [PATCH 364/378] Increases hitbox of bungee portals using END_PORTAL to fix server change not triggering --- .../stargate/listener/PlayerEventListener.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 254a24d..82438a8 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -17,6 +17,7 @@ import net.knarcraft.stargate.utility.UpdateChecker; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.AbstractHorse; @@ -104,6 +105,11 @@ public class PlayerEventListener implements Listener { return; } Portal entrancePortal = PortalHandler.getByEntrance(toLocation); + //Check an additional block away in case the portal is a bungee portal using END_PORTAL + if (entrancePortal == null) { + entrancePortal = PortalHandler.getByAdjacentEntrance(toLocation); + } + Portal destination = entrancePortal.getPortalActivator().getDestination(player); Entity playerVehicle = player.getVehicle(); @@ -163,7 +169,12 @@ public class PlayerEventListener implements Listener { //Check if the player moved from a portal Portal entrancePortal = PortalHandler.getByEntrance(toLocation); if (entrancePortal == null) { - return false; + //Check an additional block away for BungeeCord portals using END_PORTAL as its material + entrancePortal = PortalHandler.getByAdjacentEntrance(toLocation); + if (entrancePortal == null || !entrancePortal.getOptions().isBungee() || + entrancePortal.getGate().getPortalOpenBlock() != Material.END_PORTAL) { + return false; + } } Portal destination = entrancePortal.getPortalActivator().getDestination(player); From b5e256562640f7b37be054f7fcf6146409699e83 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 9 Oct 2022 10:44:30 +0200 Subject: [PATCH 365/378] Fixes use of depreciated setWoodType and getWoodType --- .../knarcraft/stargate/portal/teleporter/VehicleTeleporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 20d4353..4f3e42c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -169,7 +169,7 @@ public class VehicleTeleporter extends EntityTeleporter { //Spawn a new vehicle Vehicle newVehicle = vehicleWorld.spawn(exit, teleportingVehicle.getClass()); if (teleportingVehicle instanceof Boat boat) { - ((Boat) newVehicle).setWoodType(boat.getWoodType()); + ((Boat) newVehicle).setBoatType(boat.getBoatType()); } //Remove the old vehicle if (teleportingVehicle.eject()) { From c09063c49e26374533fab8656f2ef33861c1e523 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 9 Oct 2022 10:46:49 +0200 Subject: [PATCH 366/378] Updates README and version to 0.9.4.2 --- README.md | 17 +++++++++++++++++ pom.xml | 4 ++-- src/main/resources/plugin.yml | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05785ef..5d4f412 100644 --- a/README.md +++ b/README.md @@ -405,6 +405,23 @@ portalInfoServer=Server: %server% # Changes +#### \[Version 0.9.4.2] EpicKnarvik97 fork + +- Avoids a NullPointerException if Dynmap is present, but isn't properly loaded. +- Avoids some potential NullPointerExceptions related to Dynmap integration +- Fixes end portals hijacking BungeeCord teleportation +- Fixes a problem where a player might not be properly teleported from an end portal Stargate in the end to the + over-world. + +#### \[Version 0.9.4.1] EpicKnarvik97 fork + +- Reverts to Spigot API 1.18 +- Adds Dynmap integration + +#### \[Version 0.9.4.0] EpicKnarvik97 fork + +- Updates Stargate to 1.19 + #### \[Version 0.9.3.7] EpicKnarvik97 fork - Adds the Japanese language file provided by spigot user furplag diff --git a/pom.xml b/pom.xml index 313190c..fdb33cf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.4.1 + 0.9.4.2 @@ -38,7 +38,7 @@ org.spigotmc spigot-api - 1.19-R0.1-SNAPSHOT + 1.19.2-R0.1-SNAPSHOT net.milkbowl.vault diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c717434..ebd6bf9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.4.1 +version: 0.9.4.2 description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From 2b23e6fc567520d648bfb66e61c70b19fcb02975 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 7 Nov 2022 09:57:32 +0100 Subject: [PATCH 367/378] Uses KnarLib where possible --- pom.xml | 48 ++++++- .../java/net/knarcraft/stargate/Stargate.java | 5 +- .../stargate/command/ConfigTabCompleter.java | 33 ++--- .../stargate/config/LanguageLoader.java | 8 +- .../stargate/config/StargateConfig.java | 6 +- .../stargate/config/StargateGateConfig.java | 2 +- .../stargate/container/SignData.java | 2 +- .../listener/PlayerEventListener.java | 2 +- .../stargate/portal/PortalSignDrawer.java | 14 +- .../stargate/utility/ColorHelper.java | 54 -------- .../stargate/utility/FileHelper.java | 127 ------------------ .../stargate/utility/UpdateChecker.java | 87 ------------ 12 files changed, 79 insertions(+), 309 deletions(-) delete mode 100644 src/main/java/net/knarcraft/stargate/utility/ColorHelper.java delete mode 100644 src/main/java/net/knarcraft/stargate/utility/FileHelper.java delete mode 100644 src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java diff --git a/pom.xml b/pom.xml index fdb33cf..3f187d2 100644 --- a/pom.xml +++ b/pom.xml @@ -15,8 +15,7 @@ UTF-8 - 17 - 17 + 16 @@ -39,11 +38,13 @@ org.spigotmc spigot-api 1.19.2-R0.1-SNAPSHOT + provided net.milkbowl.vault VaultAPI 1.7 + provided org.junit.jupiter @@ -61,7 +62,7 @@ org.jetbrains annotations 22.0.0 - compile + provided junit @@ -73,6 +74,13 @@ us.dynmap dynmap-api 3.1-beta-2 + provided + + + net.knarcraft + knarlib + 1.0-SNAPSHOT + compile @@ -84,10 +92,40 @@ maven-compiler-plugin 3.6.1 - 17 - 17 + ${java.version} + ${java.version} + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + net.knarcraft:knarlib + + net/knarcraft/knarlib/** + + + + + *.MF + *.yml + + + + + + +
\ No newline at end of file diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index b9ed27d..2daf831 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate; +import net.knarcraft.knarlib.util.UpdateChecker; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.config.EconomyConfig; @@ -22,7 +23,6 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.thread.BlockChangeThread; import net.knarcraft.stargate.thread.ChunkUnloadThread; import net.knarcraft.stargate.thread.StarGateThread; -import net.knarcraft.stargate.utility.UpdateChecker; import org.bukkit.Server; import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; @@ -383,7 +383,8 @@ public class Stargate extends JavaPlugin { this.registerCommands(); //Check for any available updates - UpdateChecker.checkForUpdate(); + UpdateChecker.checkForUpdate(this, "https://api.spigotmc.org/legacy/update.php?resource=97784", + Stargate::getPluginVersion, Stargate::setUpdateAvailable); } /** diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index cb5447d..ff09aa9 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -14,6 +14,8 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingStartsWith; + /** * This is the completer for stargates config sub-command (/sg config) */ @@ -48,27 +50,10 @@ public class ConfigTabCompleter implements TabCompleter { for (ConfigOption option : ConfigOption.values()) { configOptionNames.add(option.getName()); } - return filterMatching(configOptionNames, args[0]); + return filterMatchingStartsWith(configOptionNames, args[0]); } } - /** - * Find completable strings which match the text typed by the command's sender - * - * @param values

The values to filter

- * @param typedText

The text the player has started typing

- * @return

The given string values which start with the player's typed text

- */ - private List filterMatching(List values, String typedText) { - List configValues = new ArrayList<>(); - for (String value : values) { - if (value.toLowerCase().startsWith(typedText.toLowerCase())) { - configValues.add(value); - } - } - return configValues; - } - /** * Get possible values for the selected option * @@ -80,7 +65,7 @@ public class ConfigTabCompleter implements TabCompleter { switch (selectedOption) { case LANGUAGE: //Return available languages - return filterMatching(languages, typedText); + return filterMatchingStartsWith(languages, typedText); case GATE_FOLDER: case PORTAL_FOLDER: case DEFAULT_GATE_NETWORK: @@ -94,12 +79,12 @@ public class ConfigTabCompleter implements TabCompleter { case HIGHLIGHT_SIGN_COLOR: case FREE_GATES_COLOR: //Return all colors - return filterMatching(chatColors, typedText); + return filterMatchingStartsWith(chatColors, typedText); } //If the config value is a boolean, show the two boolean values if (selectedOption.getDataType() == OptionDataType.BOOLEAN) { - return filterMatching(booleans, typedText); + return filterMatchingStartsWith(booleans, typedText); } //If the config value is an integer, display some valid numbers @@ -145,11 +130,11 @@ public class ConfigTabCompleter implements TabCompleter { */ private List getPerSignColorCompletion(String[] args) { if (args.length < 3) { - return filterMatching(signTypes, args[1]); + return filterMatchingStartsWith(signTypes, args[1]); } else if (args.length < 4) { - return filterMatching(extendedColors, args[2]); + return filterMatchingStartsWith(extendedColors, args[2]); } else if (args.length < 5) { - return filterMatching(extendedColors, args[3]); + return filterMatchingStartsWith(extendedColors, args[3]); } return new ArrayList<>(); } diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index f5ca821..0383794 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -1,7 +1,8 @@ package net.knarcraft.stargate.config; +import net.knarcraft.knarlib.property.ColorConversion; +import net.knarcraft.knarlib.util.FileHelper; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.utility.FileHelper; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -136,7 +137,8 @@ public final class LanguageLoader { String> currentLanguageValues) throws IOException { //Get language values BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); - Map internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader); + Map internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader, "=", + ColorConversion.NORMAL); //If currentLanguageValues is null; the chosen language has not been used before if (currentLanguageValues == null) { @@ -221,7 +223,7 @@ public final class LanguageLoader { } else { bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); } - strings = FileHelper.readKeyValuePairs(bufferedReader); + strings = FileHelper.readKeyValuePairs(bufferedReader, "=", ColorConversion.NORMAL); } catch (Exception e) { if (Stargate.getStargateConfig().isDebuggingEnabled()) { Stargate.getConsoleLogger().info("[Stargate] Unable to load language " + lang); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index b718d8b..f03b852 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -1,5 +1,7 @@ package net.knarcraft.stargate.config; +import net.knarcraft.knarlib.property.ColorConversion; +import net.knarcraft.knarlib.util.FileHelper; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.listener.BungeeCordListener; @@ -8,7 +10,6 @@ import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.thread.BlockChangeThread; -import net.knarcraft.stargate.utility.FileHelper; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; import org.bukkit.World; @@ -448,7 +449,8 @@ public final class StargateConfig { Map migrationFields; try { migrationFields = FileHelper.readKeyValuePairs(FileHelper.getBufferedReaderFromInputStream( - FileHelper.getInputStreamForInternalFile("/config-migrations.txt"))); + FileHelper.getInputStreamForInternalFile("/config-migrations.txt")), "=", + ColorConversion.NORMAL); } catch (IOException e) { Stargate.debug("Stargate::migrateConfig", "Unable to load config migration file"); e.printStackTrace(); diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index 053d4b6..f1dc7ca 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -1,8 +1,8 @@ package net.knarcraft.stargate.config; +import net.knarcraft.knarlib.util.ColorHelper; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.PortalSignDrawer; -import net.knarcraft.stargate.utility.ColorHelper; import net.md_5.bungee.api.ChatColor; import org.bukkit.Color; import org.bukkit.Material; diff --git a/src/main/java/net/knarcraft/stargate/container/SignData.java b/src/main/java/net/knarcraft/stargate/container/SignData.java index 38b3076..1b4bd31 100644 --- a/src/main/java/net/knarcraft/stargate/container/SignData.java +++ b/src/main/java/net/knarcraft/stargate/container/SignData.java @@ -1,6 +1,6 @@ package net.knarcraft.stargate.container; -import net.knarcraft.stargate.utility.ColorHelper; +import net.knarcraft.knarlib.util.ColorHelper; import net.md_5.bungee.api.ChatColor; import org.bukkit.DyeColor; import org.bukkit.block.Sign; diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 82438a8..6fd69b0 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate.listener; +import net.knarcraft.knarlib.util.UpdateChecker; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.MessageSender; import net.knarcraft.stargate.container.BlockLocation; @@ -13,7 +14,6 @@ import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.TeleportHelper; import net.knarcraft.stargate.utility.UUIDMigrationHelper; -import net.knarcraft.stargate.utility.UpdateChecker; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; import org.bukkit.GameMode; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 2bad4c4..3dabc9e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -1,5 +1,7 @@ package net.knarcraft.stargate.portal; +import net.knarcraft.knarlib.property.ColorConversion; +import net.knarcraft.knarlib.util.ColorHelper; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.SignData; import net.knarcraft.stargate.portal.property.PortalLocation; @@ -12,8 +14,6 @@ import org.bukkit.block.Sign; import java.util.Map; -import static net.knarcraft.stargate.utility.ColorHelper.translateAllColorCodes; - /** * The portal sign drawer draws the sing of a given portal */ @@ -393,4 +393,14 @@ public class PortalSignDrawer { } } + /** + * Translates all normal and RGB color codes in the given input + * + * @param input

The input to translate color codes for

+ * @return

The input with color codes converted translated from & to ยง

+ */ + private String translateAllColorCodes(String input) { + return ColorHelper.translateColorCodes(input, ColorConversion.RGB); + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java b/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java deleted file mode 100644 index 0886b94..0000000 --- a/src/main/java/net/knarcraft/stargate/utility/ColorHelper.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.knarcraft.stargate.utility; - -import net.md_5.bungee.api.ChatColor; -import org.bukkit.Color; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A helper class for dealing with colors - */ -public final class ColorHelper { - - private ColorHelper() { - - } - - /** - * Inverts the given color - * - * @param color

The color to invert

- * @return

The inverted color

- */ - public static Color invert(Color color) { - return color.setRed(255 - color.getRed()).setGreen(255 - color.getGreen()).setBlue(255 - color.getBlue()); - } - - /** - * Gets the chat color corresponding to the given color - * - * @param color

The color to convert into a chat color

- * @return

The resulting chat color

- */ - public static ChatColor fromColor(Color color) { - return ChatColor.of(String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue())); - } - - /** - * Translates all found color codes to formatting in a string - * - * @param message

The string to search for color codes

- * @return

The message with color codes translated

- */ - public static String translateAllColorCodes(String message) { - message = ChatColor.translateAlternateColorCodes('&', message); - Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})"); - Matcher matcher = pattern.matcher(message); - while (matcher.find()) { - message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group())); - } - return message; - } - -} diff --git a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java deleted file mode 100644 index b4cdac5..0000000 --- a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java +++ /dev/null @@ -1,127 +0,0 @@ -package net.knarcraft.stargate.utility; - -import net.md_5.bungee.api.ChatColor; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; - -/** - * Helper class for reading files - */ -public final class FileHelper { - - private FileHelper() { - - } - - /** - * Gets an input stream from a string pointing to an internal file - * - *

This is used for getting an input stream for reading a file contained within the compiled .jar file. The file - * should be in the resources directory, and the file path should start with a forward slash ("/") character.

- * - * @param file

The file to read

- * @return

An input stream for the file

- */ - public static InputStream getInputStreamForInternalFile(String file) { - return FileHelper.class.getResourceAsStream(file); - } - - /** - * Gets a buffered reader from a string pointing to a file - * - * @param file

The file to read

- * @return

A buffered reader reading the file

- * @throws FileNotFoundException

If the given file does not exist

- */ - public static BufferedReader getBufferedReaderFromString(String file) throws FileNotFoundException { - FileInputStream fileInputStream = new FileInputStream(file); - return getBufferedReaderFromInputStream(fileInputStream); - } - - /** - * Gets a buffered reader given an input stream - * - * @param inputStream

The input stream to read

- * @return

A buffered reader reading the input stream

- */ - public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) { - InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); - return new BufferedReader(inputStreamReader); - } - - /** - * Gets a buffered writer from a string pointing to a file - * - * @param file

The file to write to

- * @return

A buffered writer writing to the file

- * @throws FileNotFoundException

If the file does not exist

- */ - public static BufferedWriter getBufferedWriterFromString(String file) throws FileNotFoundException { - FileOutputStream fileOutputStream = new FileOutputStream(file); - OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8); - return new BufferedWriter(outputStreamWriter); - } - - /** - * Reads key/value pairs from an input stream - * - * @param bufferedReader

The buffered reader to read

- * @return

A map containing the read pairs

- * @throws IOException

If unable to read from the stream

- */ - public static Map readKeyValuePairs(BufferedReader bufferedReader) throws IOException { - Map readPairs = new HashMap<>(); - - String line = bufferedReader.readLine(); - boolean firstLine = true; - while (line != null) { - //Strip UTF BOM from the first line - if (firstLine) { - line = removeUTF8BOM(line); - firstLine = false; - } - //Split at first "=" - int equalSignIndex = line.indexOf('='); - if (equalSignIndex == -1) { - line = bufferedReader.readLine(); - continue; - } - - //Read the line - String key = line.substring(0, equalSignIndex); - String value = ChatColor.translateAlternateColorCodes('&', line.substring(equalSignIndex + 1)); - readPairs.put(key, value); - - line = bufferedReader.readLine(); - } - bufferedReader.close(); - - return readPairs; - } - - /** - * Removes the UTF-8 Byte Order Mark if present - * - * @param string

The string to remove the BOM from

- * @return

A string guaranteed without a BOM

- */ - private static String removeUTF8BOM(String string) { - String UTF8_BOM = "\uFEFF"; - if (string.startsWith(UTF8_BOM)) { - string = string.substring(1); - } - return string; - } - -} diff --git a/src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java b/src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java deleted file mode 100644 index 2df40f4..0000000 --- a/src/main/java/net/knarcraft/stargate/utility/UpdateChecker.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.knarcraft.stargate.utility; - -import net.knarcraft.stargate.Stargate; -import org.bukkit.scheduler.BukkitScheduler; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.logging.Level; - -/** - * The update checker is responsible for looking for new updates - */ -public final class UpdateChecker { - - private final static String APIResourceURL = "https://api.spigotmc.org/legacy/update.php?resource=97784"; - private final static String updateNotice = "A new update is available: %s (You are still on %s)"; - - private UpdateChecker() { - - } - - /** - * Checks if there's a new update available, and alerts the user if necessary - */ - public static void checkForUpdate() { - BukkitScheduler scheduler = Stargate.getInstance().getServer().getScheduler(); - scheduler.runTaskAsynchronously(Stargate.getInstance(), UpdateChecker::queryAPI); - } - - /** - * Queries the spigot API to check for a newer version, and informs the user - */ - private static void queryAPI() { - try { - InputStream inputStream = new URL(APIResourceURL).openStream(); - BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream); - //There should only be one line of output - String newVersion = reader.readLine(); - reader.close(); - - String oldVersion = Stargate.getPluginVersion(); - //If there is a newer version, notify the user - if (isVersionHigher(oldVersion, newVersion)) { - Stargate.getConsoleLogger().log(Level.INFO, Stargate.getBackupString("prefix") + - getUpdateAvailableString(newVersion, oldVersion)); - Stargate.setUpdateAvailable(newVersion); - } - } catch (IOException e) { - Stargate.debug("UpdateChecker", "Unable to get newest version."); - } - } - - /** - * Gets the string to display to a user to alert about a new update - * - * @param newVersion

The new available plugin version

- * @param oldVersion

The old (current) plugin version

- * @return

The string to display

- */ - public static String getUpdateAvailableString(String newVersion, String oldVersion) { - return String.format(updateNotice, newVersion, oldVersion); - } - - /** - * Decides whether one version number is higher than another - * - * @param oldVersion

The old version to check

- * @param newVersion

The new version to check

- * @return

True if the new version is higher than the old one

- */ - public static boolean isVersionHigher(String oldVersion, String newVersion) { - String[] oldVersionParts = oldVersion.split("\\."); - String[] newVersionParts = newVersion.split("\\."); - int versionLength = Math.max(oldVersionParts.length, newVersionParts.length); - for (int i = 0; i < versionLength; i++) { - int oldVersionNumber = oldVersionParts.length > i ? Integer.parseInt(oldVersionParts[i]) : 0; - int newVersionNumber = newVersionParts.length > i ? Integer.parseInt(newVersionParts[i]) : 0; - if (newVersionNumber != oldVersionNumber) { - return newVersionNumber > oldVersionNumber; - } - } - return false; - } - -} From 4fda4c39056433a170d27fff2672d9fa1d803463 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 7 Nov 2022 10:01:34 +0100 Subject: [PATCH 368/378] Makes sure to initialize KnarLib properly --- .../java/net/knarcraft/stargate/Stargate.java | 21 +++---------------- .../stargate/utility/EconomyHelper.java | 13 ++++++------ 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2daf831..e4ce24d 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate; +import net.knarcraft.knarlib.KnarLib; import net.knarcraft.knarlib.util.UpdateChecker; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; @@ -299,24 +300,6 @@ public class Stargate extends JavaPlugin { return stargateConfig.getLanguageLoader().getBackupString(name); } - /** - * Replaces a list of variables in a string in the order they are given - * - * @param input

The input containing the variables

- * @param search

The variables to replace

- * @param values

The replacement values

- * @return

The input string with the search values replaced with the given values

- */ - public static String replaceVars(String input, String[] search, String[] values) { - if (search.length != values.length) { - throw new IllegalArgumentException("The number of search values and replace values do not match."); - } - for (int i = 0; i < search.length; i++) { - input = replaceVars(input, search[i], values[i]); - } - return input; - } - /** * Replaces a variable in a string * @@ -357,6 +340,8 @@ public class Stargate extends JavaPlugin { @Override public void onEnable() { + KnarLib.setPlugin(this); + PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); FileConfiguration newConfig = this.getConfig(); diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index e3ab32c..6c58e52 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -1,5 +1,6 @@ package net.knarcraft.stargate.utility; +import net.knarcraft.knarlib.formatting.StringFormatter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.EconomyConfig; import net.knarcraft.stargate.portal.Portal; @@ -78,7 +79,7 @@ public final class EconomyHelper { */ public static void sendObtainMessage(String portalName, Player portalOwner, int earnings) { String obtainedMsg = Stargate.getString("ecoObtain"); - obtainedMsg = replaceVars(obtainedMsg, portalName, earnings); + obtainedMsg = replacePlaceholders(obtainedMsg, portalName, earnings); Stargate.getMessageSender().sendSuccessMessage(portalOwner, obtainedMsg); } @@ -91,7 +92,7 @@ public final class EconomyHelper { */ public static void sendDeductMessage(String portalName, Player player, int cost) { String deductMsg = Stargate.getString("ecoDeduct"); - deductMsg = replaceVars(deductMsg, portalName, cost); + deductMsg = replacePlaceholders(deductMsg, portalName, cost); Stargate.getMessageSender().sendSuccessMessage(player, deductMsg); } @@ -104,7 +105,7 @@ public final class EconomyHelper { */ public static void sendInsufficientFundsMessage(String portalName, Player player, int cost) { String inFundMsg = Stargate.getString("ecoInFunds"); - inFundMsg = replaceVars(inFundMsg, portalName, cost); + inFundMsg = replacePlaceholders(inFundMsg, portalName, cost); Stargate.getMessageSender().sendErrorMessage(player, inFundMsg); } @@ -117,7 +118,7 @@ public final class EconomyHelper { */ public static void sendRefundMessage(String portalName, Player player, int cost) { String refundMsg = Stargate.getString("ecoRefund"); - refundMsg = replaceVars(refundMsg, portalName, -cost); + refundMsg = replacePlaceholders(refundMsg, portalName, -cost); Stargate.getMessageSender().sendSuccessMessage(player, refundMsg); } @@ -239,8 +240,8 @@ public final class EconomyHelper { * @param cost

The cost for a given interaction

* @return

The same string with cost and portal variables replaced

*/ - private static String replaceVars(String message, String portalName, int cost) { - return Stargate.replaceVars(message, new String[]{"%cost%", "%portal%"}, + private static String replacePlaceholders(String message, String portalName, int cost) { + return StringFormatter.replacePlaceholders(message, new String[]{"%cost%", "%portal%"}, new String[]{Stargate.getEconomyConfig().format(cost), portalName}); } From a26cc3009231c1687d3a44e28e454df9f2281acf Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 7 Nov 2022 10:07:16 +0100 Subject: [PATCH 369/378] Uses placeholder for plugin version --- src/main/resources/plugin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ebd6bf9..283fe85 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Stargate main: net.knarcraft.stargate.Stargate -version: 0.9.4.2 +version: '${project.version}' description: Stargate mod for Bukkit Revived author: EpicKnarvik97 authors: [ Drakia, PseudoKnight, EpicKnarvik97 ] From ef97da9177daaa0f9138f0047caa95c72b889c06 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 7 Nov 2022 22:27:53 +0100 Subject: [PATCH 370/378] Removes KnarLib.setPlugin call --- src/main/java/net/knarcraft/stargate/Stargate.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index e4ce24d..2cb40b1 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -1,6 +1,5 @@ package net.knarcraft.stargate; -import net.knarcraft.knarlib.KnarLib; import net.knarcraft.knarlib.util.UpdateChecker; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; @@ -340,8 +339,6 @@ public class Stargate extends JavaPlugin { @Override public void onEnable() { - KnarLib.setPlugin(this); - PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); FileConfiguration newConfig = this.getConfig(); From 5aed252181765f9af32dcfe71d60e339964ed60d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 14 Nov 2022 00:45:31 +0000 Subject: [PATCH 371/378] Updates dependencies --- pom.xml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 3f187d2..40bdfcb 100644 --- a/pom.xml +++ b/pom.xml @@ -25,12 +25,16 @@ vault-repo - http://nexus.hc.to/content/repositories/pub_releases + https://nexus.hc.to/content/repositories/pub_releases dynmap https://repo.mikeprimm.com/ + + papermc + https://repo.papermc.io/repository/maven-public/ + @@ -49,19 +53,19 @@ org.junit.jupiter junit-jupiter-api - 5.8.2 + 5.9.0 test com.github.seeseemelk MockBukkit-v1.18 - 1.15.5 + 2.85.2 test org.jetbrains annotations - 22.0.0 + 23.0.0 provided @@ -85,12 +89,11 @@ - src/main/java org.apache.maven.plugins maven-compiler-plugin - 3.6.1 + 3.8.1 ${java.version} ${java.version} @@ -127,5 +130,11 @@ + + + src/main/resources + true + + \ No newline at end of file From a35c07dc9c8c89781d5c4fe5d75e900c18fc17bb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 22 Nov 2022 16:41:55 +0100 Subject: [PATCH 372/378] Updates the JDK used for Jenkins --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b17f9a7..5a47c8f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ pipeline { agent any tools { - jdk 'JDK16' + jdk 'JDK17' } stages { stage('Build') { From 31b342324666bd980c47fe714cfbacf61595930c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 26 Nov 2022 04:05:03 +0100 Subject: [PATCH 373/378] Adds the knarcraft git repository --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 40bdfcb..7c4e29b 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,10 @@ + + gitea + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + spigot-repo https://hub.spigotmc.org/nexus/content/groups/public/ From 13cdccfc1db341d250290b9916b0ea049cc01b7b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 26 Nov 2022 15:15:45 +0100 Subject: [PATCH 374/378] Improves Jenkinsfile --- Jenkinsfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5a47c8f..2e16cba 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -16,10 +16,16 @@ pipeline { sh 'mvn test' } } + stage('Verify') { + steps { + echo 'Verifying...' + sh 'mvn verify -Dmaven.test.skip=true' + } + } stage('Deploy') { steps { echo 'Deploying...' - sh 'mvn verify -Dmaven.test.skip=true' + sh 'mvn deploy -Dmaven.install.skip=true -Dmaven.test.skip=true' archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true } } From 9ac3c1134548635fbca90c48dfc9b05b3a92bd9a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 26 Nov 2022 15:34:34 +0100 Subject: [PATCH 375/378] Adds missing distribution management --- pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7c4e29b..d5c035c 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - gitea + knarcraft-repo https://git.knarcraft.net/api/packages/EpicKnarvik97/maven @@ -40,6 +40,16 @@ https://repo.papermc.io/repository/maven-public/ + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + From e4539c3623f7b9d5c78516fefbc4af2382c5e33d Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 26 Nov 2022 17:00:04 +0100 Subject: [PATCH 376/378] Changes version to 0.9.4.3-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d5c035c..a24c65e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.knarcraft Stargate - 0.9.4.2 + 0.9.4.3-SNAPSHOT From 116e816a1862ed24eadd4d1e405aeac58925a687 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 10 Dec 2022 22:40:03 +0100 Subject: [PATCH 377/378] Bumps Spigot version to 1.19.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a24c65e..2e1bead 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ org.spigotmc spigot-api - 1.19.2-R0.1-SNAPSHOT + 1.19.3-R0.1-SNAPSHOT provided From af9142bb0561ec66a4e582179552b9e0ee36a61e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 24 Mar 2023 20:02:05 +0100 Subject: [PATCH 378/378] Adds missing known legacy config migrations --- src/main/resources/config-migrations.txt | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/resources/config-migrations.txt b/src/main/resources/config-migrations.txt index b38533f..cb2628f 100644 --- a/src/main/resources/config-migrations.txt +++ b/src/main/resources/config-migrations.txt @@ -1,4 +1,8 @@ lang=language +defaultNetwork=defaultGateNetwork +use-mysql= +ignoreEntrance= +portal-save-location=folders.portalFolder portal-folder=folders.portalFolder gate-folder=folders.gateFolder default-gate-network=gates.defaultGateNetwork @@ -18,11 +22,28 @@ debug=debugging.debug permdebug=debugging.permissionDebug useiconomy=economy.useEconomy useeconomy=economy.useEconomy +cost-to-use=economy.useCost +cost-to-create=economy.createCost createcost=economy.createCost destroycost=economy.destroyCost usecost=economy.useCost toowner=economy.toOwner +cost-destination=economy.chargeFreeDestination chargefreedestination=economy.chargeFreeDestination freegatesgreen=economy.freeGatesGreen CheckUpdates= -economy.freeGatesGreen=economy.freeGatesColored \ No newline at end of file +economy.freeGatesGreen=economy.freeGatesColored +teleportMessage= +registerMessage= +destroyzMessage= +noownersMessage= +unselectMessage= +collisinMessage= +cantAffordToUse= +cantAffordToNew= +portal-open= +portal-closed= +cost-type= +cost-to-activate= +taxaccount=taxAccount +usevault= \ No newline at end of file