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
This commit is contained in:
Kristian Knarvik 2021-02-20 13:57:04 +01:00
parent 2ae4fc9645
commit 1721750aa1
29 changed files with 1499 additions and 1206 deletions

View File

@ -22,6 +22,7 @@ public class BlockLocation extends Location {
/** /**
* Creates a new block location * Creates a new block location
*
* @param world <p>The world the block exists in</p> * @param world <p>The world the block exists in</p>
* @param x <p>The x coordinate of the block</p> * @param x <p>The x coordinate of the block</p>
* @param y <p>The y coordinate of the block</p> * @param y <p>The y coordinate of the block</p>
@ -33,6 +34,7 @@ public class BlockLocation extends Location {
/** /**
* Copies a craftbukkit block * Copies a craftbukkit block
*
* @param block <p>The block to </p> * @param block <p>The block to </p>
*/ */
public BlockLocation(Block block) { public BlockLocation(Block block) {
@ -41,6 +43,7 @@ public class BlockLocation extends Location {
/** /**
* Gets a block from a string * Gets a block from a string
*
* @param world <p>The world the block exists in</p> * @param world <p>The world the block exists in</p>
* @param string <p>A comma separated list of z, y and z coordinates as integers</p> * @param string <p>A comma separated list of z, y and z coordinates as integers</p>
*/ */
@ -51,6 +54,7 @@ public class BlockLocation extends Location {
/** /**
* Makes a new block in a relative position to this block * Makes a new block in a relative position to this block
*
* @param x <p>The x position relative to this block's position</p> * @param x <p>The x position relative to this block's position</p>
* @param y <p>The y position relative to this block's position</p> * @param y <p>The y position relative to this block's position</p>
* @param z <p>The z position relative to this block's position</p> * @param z <p>The z position relative to this block's position</p>
@ -62,6 +66,7 @@ public class BlockLocation extends Location {
/** /**
* Makes a location relative to the block location * Makes a location relative to the block location
*
* @param x <p>The x position relative to this block's position</p> * @param x <p>The x position relative to this block's position</p>
* @param y <p>The y position relative to this block's position</p> * @param y <p>The y position relative to this block's position</p>
* @param z <p>The z position relative to this block's position</p> * @param z <p>The z position relative to this block's position</p>
@ -96,6 +101,7 @@ public class BlockLocation extends Location {
/** /**
* Makes a location relative to the current location according to given parameters * Makes a location relative to the current location according to given parameters
*
* @param right <p></p> * @param right <p></p>
* @param depth <p>The y position relative to the current position</p> * @param depth <p>The y position relative to the current position</p>
* @param distance <p>The distance away from the previous location to the new location</p> * @param distance <p>The distance away from the previous location to the new location</p>
@ -110,24 +116,27 @@ public class BlockLocation extends Location {
return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); 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 <p>The new block material type</p>
*/
public void setType(Material type) {
this.getBlock().setType(type);
}
/** /**
* Gets the type for the block at this location * Gets the type for the block at this location
*
* @return <p>The block material type</p> * @return <p>The block material type</p>
*/ */
public Material getType() { public Material getType() {
return this.getBlock().getType(); return this.getBlock().getType();
} }
/**
* Sets the type for the block at this location
*
* @param type <p>The new block material type</p>
*/
public void setType(Material type) {
this.getBlock().setType(type);
}
/** /**
* Gets the location representing this block location * Gets the location representing this block location
*
* @return <p>The location representing this block location</p> * @return <p>The location representing this block location</p>
*/ */
public Location getLocation() { public Location getLocation() {
@ -136,6 +145,7 @@ public class BlockLocation extends Location {
/** /**
* Gets this block location's parent block * Gets this block location's parent block
*
* @return <p>This block location's parent block</p> * @return <p>This block location's parent block</p>
*/ */
public Block getParent() { public Block getParent() {

View File

@ -14,6 +14,7 @@ public class BloxPopulator {
/** /**
* Instantiates a new block populator * Instantiates a new block populator
*
* @param blockLocation <p>The location to start from</p> * @param blockLocation <p>The location to start from</p>
* @param material <p>The material to populate</p> * @param material <p>The material to populate</p>
*/ */
@ -25,6 +26,7 @@ public class BloxPopulator {
/** /**
* Instantiates a new block populator * Instantiates a new block populator
*
* @param blockLocation <p>The location to start from</p> * @param blockLocation <p>The location to start from</p>
* @param material <p>The material to populate</p> * @param material <p>The material to populate</p>
* @param axis <p>The axis to populate along</p> * @param axis <p>The axis to populate along</p>
@ -35,52 +37,58 @@ public class BloxPopulator {
nextAxis = axis; nextAxis = axis;
} }
/**
* Sets the location to start from
* @param blockLocation <p>The new start location</p>
*/
public void setBlockLocation(BlockLocation blockLocation) {
this.blockLocation = blockLocation;
}
/**
* Sets the polulator material
* @param material <p>The new populator material</p>
*/
public void setMat(Material material) {
nextMat = material;
}
/**
* Sets the populator axis
* @param axis <p>The new populator axis</p>
*/
public void setAxis(Axis axis) {
nextAxis = axis;
}
/** /**
* Gets the location to start from * Gets the location to start from
*
* @return <p>The location to start from</p> * @return <p>The location to start from</p>
*/ */
public BlockLocation getBlockLocation() { public BlockLocation getBlockLocation() {
return blockLocation; return blockLocation;
} }
/**
* Sets the location to start from
*
* @param blockLocation <p>The new start location</p>
*/
public void setBlockLocation(BlockLocation blockLocation) {
this.blockLocation = blockLocation;
}
/** /**
* Gets the material used for population * Gets the material used for population
*
* @return <p>The material used for population</p> * @return <p>The material used for population</p>
*/ */
public Material getMat() { public Material getMat() {
return nextMat; return nextMat;
} }
/**
* Sets the polulator material
*
* @param material <p>The new populator material</p>
*/
public void setMat(Material material) {
nextMat = material;
}
/** /**
* Gets the current population axis * Gets the current population axis
*
* @return <p>The current population axis</p> * @return <p>The current population axis</p>
*/ */
public Axis getAxis() { public Axis getAxis() {
return nextAxis; return nextAxis;
} }
/**
* Sets the populator axis
*
* @param axis <p>The new populator axis</p>
*/
public void setAxis(Axis axis) {
nextAxis = axis;
}
} }

View File

@ -26,6 +26,7 @@ public class EconomyHandler {
/** /**
* Gets the balance (money) of the given player * Gets the balance (money) of the given player
*
* @param player <p>The player to get balance for</p> * @param player <p>The player to get balance for</p>
* @return <p>The current balance of the player. Returns 0 if economy is disabled</p> * @return <p>The current balance of the player. Returns 0 if economy is disabled</p>
*/ */
@ -39,6 +40,7 @@ public class EconomyHandler {
/** /**
* Charges a player, giving the charge to a target * Charges a player, giving the charge to a target
*
* @param player <p>The player to charge</p> * @param player <p>The player to charge</p>
* @param target <p>The UUID of the player to pay</p> * @param target <p>The UUID of the player to pay</p>
* @param amount <p>The amount to charge</p> * @param amount <p>The amount to charge</p>
@ -57,6 +59,7 @@ public class EconomyHandler {
/** /**
* Charges a player * Charges a player
*
* @param player <p>The player to charge</p> * @param player <p>The player to charge</p>
* @param amount <p>The amount to charge</p> * @param amount <p>The amount to charge</p>
* @return <p>True if the payment succeeded, or if no payment was necessary</p> * @return <p>True if the payment succeeded, or if no payment was necessary</p>
@ -73,6 +76,7 @@ public class EconomyHandler {
/** /**
* Gets a formatted string for an amount, adding the name of the currency * Gets a formatted string for an amount, adding the name of the currency
*
* @param amount <p>The amount to display</p> * @param amount <p>The amount to display</p>
* @return <p>A formatted text string describing the amount</p> * @return <p>A formatted text string describing the amount</p>
*/ */
@ -86,6 +90,7 @@ public class EconomyHandler {
/** /**
* Sets up economy by initializing vault and the vault economy provider * Sets up economy by initializing vault and the vault economy provider
*
* @param pluginManager <p>The plugin manager to get plugins from</p> * @param pluginManager <p>The plugin manager to get plugins from</p>
* @return <p>True if economy was enabled</p> * @return <p>True if economy was enabled</p>
*/ */
@ -113,6 +118,7 @@ public class EconomyHandler {
/** /**
* Gets whether to use economy * Gets whether to use economy
*
* @return <p>True if the user has turned on economy and economy is available</p> * @return <p>True if the user has turned on economy and economy is available</p>
*/ */
public static boolean useEconomy() { public static boolean useEconomy() {

View File

@ -11,6 +11,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.logging.Level; import java.util.logging.Level;
@ -21,17 +22,17 @@ public class Gate {
private static final Character ENTRANCE = '.'; private static final Character ENTRANCE = '.';
private static final Character EXIT = '*'; private static final Character EXIT = '*';
private static final HashMap<String, Gate> gates = new HashMap<>(); private static final HashMap<String, Gate> gates = new HashMap<>();
private static final HashMap<Material, ArrayList<Gate>> controlBlocks = new HashMap<>(); private static final HashMap<Material, List<Gate>> controlBlocks = new HashMap<>();
private static final HashSet<Material> frameBlocks = new HashSet<>(); private static final HashSet<Material> frameBlocks = new HashSet<>();
private final String filename; private final String filename;
private final Character[][] layout; private final Character[][] layout;
private final HashMap<Character, Material> types; private final HashMap<Character, Material> types;
private final HashMap<RelativeBlockVector, Integer> exits = new HashMap<>();
private RelativeBlockVector[] entrances = new RelativeBlockVector[0]; private RelativeBlockVector[] entrances = new RelativeBlockVector[0];
private RelativeBlockVector[] border = new RelativeBlockVector[0]; private RelativeBlockVector[] border = new RelativeBlockVector[0];
private RelativeBlockVector[] controls = new RelativeBlockVector[0]; private RelativeBlockVector[] controls = new RelativeBlockVector[0];
private RelativeBlockVector exitBlock = null; private RelativeBlockVector exitBlock = null;
private final HashMap<RelativeBlockVector, Integer> exits = new HashMap<>();
private Material portalBlockOpen = Material.NETHER_PORTAL; private Material portalBlockOpen = Material.NETHER_PORTAL;
private Material portalBlockClosed = Material.AIR; private Material portalBlockClosed = Material.AIR;
private Material button = Material.STONE_BUTTON; private Material button = Material.STONE_BUTTON;
@ -50,10 +51,300 @@ public class Gate {
populateCoordinates(); 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<List<Character>> design = new ArrayList<>();
HashMap<Character, Material> types = new HashMap<>();
HashMap<String, String> config = new HashMap<>();
HashSet<Material> 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<Character> 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<Character> 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<String, String> 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 <p>The config to read</p>
* @param fileName <p>The config file the config belongs to</p>
* @param key <p>The config key to read</p>
* @param defaultMaterial <p>The default material to use, in case the config is invalid</p>
* @return <p>The material to use</p>
*/
private static Material readConfig(HashMap<String, String> 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 <p>The folder containing the gates</p>
*/
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 <p>The folder containing gate config files</p>
*/
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 <p>The name of the gate file</p>
* @param gateFolder <p>The folder containing gates</p>
*/
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
*
* <p>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.</p>
*
* @param block <p>The control block to check</p>
* @return <p>A list of gates using the given control block</p>
*/
public static Gate[] getGatesByControlBlock(Block block) {
return getGatesByControlBlock(block.getType());
}
/**
* Gets the gates with the given control block
*
* @param type <p>The type of the control block to check</p>
* @return <p>A list of gates using the given material for control block</p>
*/
public static Gate[] getGatesByControlBlock(Material type) {
Gate[] result = new Gate[0];
List<Gate> lookup = controlBlocks.get(type);
if (lookup != null) {
result = lookup.toArray(result);
}
return result;
}
/**
* Gets a portal by its name (filename before .gate)
*
* @param name <p>The name of the gate to get</p>
* @return <p>The gate with the given name</p>
*/
public static Gate getGateByName(String name) {
return gates.get(name);
}
/**
* Gets the number of loaded gate configurations
*
* @return <p>The number of loaded gate configurations</p>
*/
public static int getGateCount() {
return gates.size();
}
/**
* Checks whether the given material is used for the frame of any portals
*
* @param type <p>The material type to check</p>
* @return <p>True if the material is used for the frame of at least one portal</p>
*/
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() { private void populateCoordinates() {
ArrayList<RelativeBlockVector> entranceList = new ArrayList<>(); List<RelativeBlockVector> entranceList = new ArrayList<>();
ArrayList<RelativeBlockVector> borderList = new ArrayList<>(); List<RelativeBlockVector> borderList = new ArrayList<>();
ArrayList<RelativeBlockVector> controlList = new ArrayList<>(); List<RelativeBlockVector> controlList = new ArrayList<>();
RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length]; RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length];
int[] exitDepths = new int[layout[0].length]; int[] exitDepths = new int[layout[0].length];
RelativeBlockVector lastExit = null; RelativeBlockVector lastExit = null;
@ -273,294 +564,4 @@ public class Gate {
return true; 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<ArrayList<Character>> design = new ArrayList<>();
HashMap<Character, Material> types = new HashMap<>();
HashMap<String, String> config = new HashMap<>();
HashSet<Material> 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<Character> 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<Character> 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<String, String> 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 <p>The config to read</p>
* @param fileName <p>The config file the config belongs to</p>
* @param key <p>The config key to read</p>
* @param defaultMaterial <p>The default material to use, in case the config is invalid</p>
* @return <p>The material to use</p>
*/
private static Material readConfig(HashMap<String, String> 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 <p>The folder containing the gates</p>
*/
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 <p>The folder containing gate config files</p>
*/
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 <p>The name of the gate file</p>
* @param gateFolder <p>The folder containing gates</p>
*/
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
*
* <p>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.</p>
*
* @param block <p>The control block to check</p>
* @return <p>A list of gates using the given control block</p>
*/
public static Gate[] getGatesByControlBlock(Block block) {
return getGatesByControlBlock(block.getType());
}
/**
* Gets the gates with the given control block
*
* @param type <p>The type of the control block to check</p>
* @return <p>A list of gates using the given material for control block</p>
*/
public static Gate[] getGatesByControlBlock(Material type) {
Gate[] result = new Gate[0];
ArrayList<Gate> lookup = controlBlocks.get(type);
if (lookup != null) {
result = lookup.toArray(result);
}
return result;
}
/**
* Gets a portal by its name (filename before .gate)
*
* @param name <p>The name of the gate to get</p>
* @return <p>The gate with the given name</p>
*/
public static Gate getGateByName(String name) {
return gates.get(name);
}
/**
* Gets the number of loaded gate configurations
*
* @return <p>The number of loaded gate configurations</p>
*/
public static int getGateCount() {
return gates.size();
}
/**
* Checks whether the given material is used for the frame of any portals
*
* @param type <p>The material type to check</p>
* @return <p>True if the material is used for the frame of at least one portal</p>
*/
public static boolean isGateBlock(Material type) {
return frameBlocks.contains(type);
}
/**
* Clears all loaded gates
*/
public static void clearGates() {
gates.clear();
controlBlocks.clear();
frameBlocks.clear();
}
} }

View File

@ -25,12 +25,13 @@ public class LanguageLoader {
// Variables // Variables
private final String languageFolder; private final String languageFolder;
private final Map<String, String> loadedBackupStrings;
private String chosenLanguage; private String chosenLanguage;
private Map<String, String> loadedStringTranslations; private Map<String, String> loadedStringTranslations;
private final Map<String, String> loadedBackupStrings;
/** /**
* Instantiates a new language loader * Instantiates a new language loader
*
* @param languageFolder <p>The folder containing the language files</p> * @param languageFolder <p>The folder containing the language files</p>
* @param chosenLanguage <p>The chosen plugin language</p> * @param chosenLanguage <p>The chosen plugin language</p>
*/ */
@ -68,6 +69,7 @@ public class LanguageLoader {
/** /**
* Gets the string to display given its name/key * Gets the string to display given its name/key
*
* @param name <p>The name/key of the string to display</p> * @param name <p>The name/key of the string to display</p>
* @return <p>The string in the user's preferred language</p> * @return <p>The string in the user's preferred language</p>
*/ */
@ -87,6 +89,7 @@ public class LanguageLoader {
/** /**
* Sets the chosen plugin language * Sets the chosen plugin language
*
* @param chosenLanguage <p>The new plugin language</p> * @param chosenLanguage <p>The new plugin language</p>
*/ */
public void setChosenLanguage(String chosenLanguage) { public void setChosenLanguage(String chosenLanguage) {
@ -95,12 +98,13 @@ public class LanguageLoader {
/** /**
* Updates files in the plugin directory with contents from the compiled .jar * Updates files in the plugin directory with contents from the compiled .jar
*
* @param language <p>The language to update</p> * @param language <p>The language to update</p>
*/ */
private void updateLanguage(String language) { private void updateLanguage(String language) {
// Load the current language file // Load the current language file
ArrayList<String> keyList = new ArrayList<>(); List<String> keyList = new ArrayList<>();
ArrayList<String> valueList = new ArrayList<>(); List<String> valueList = new ArrayList<>();
Map<String, String> currentLanguageValues = load(language); Map<String, String> currentLanguageValues = load(language);
@ -159,6 +163,7 @@ public class LanguageLoader {
/** /**
* Reads language strings * Reads language strings
*
* @param inputStream <p>The input stream to read from</p> * @param inputStream <p>The input stream to read from</p>
* @param keyList <p>The key list to add keys to</p> * @param keyList <p>The key list to add keys to</p>
* @param valueList <p>The value list to add values to</p> * @param valueList <p>The value list to add values to</p>
@ -209,6 +214,7 @@ public class LanguageLoader {
/** /**
* Loads the given language * Loads the given language
*
* @param lang <p>The language to load</p> * @param lang <p>The language to load</p>
* @return <p>A mapping between loaded string indexes and the strings to display</p> * @return <p>A mapping between loaded string indexes and the strings to display</p>
*/ */
@ -218,6 +224,7 @@ public class LanguageLoader {
/** /**
* Loads the given language * Loads the given language
*
* @param lang <p>The language to load</p> * @param lang <p>The language to load</p>
* @param inputStream <p>An optional input stream to use. Defaults to using a file input stream</p> * @param inputStream <p>An optional input stream to use. Defaults to using a file input stream</p>
* @return <p>A mapping between loaded string indexes and the strings to display</p> * @return <p>A mapping between loaded string indexes and the strings to display</p>
@ -253,6 +260,7 @@ public class LanguageLoader {
/** /**
* Reads a language file given its input stream * Reads a language file given its input stream
*
* @param inputStreamReader <p>The input stream reader to read from</p> * @param inputStreamReader <p>The input stream reader to read from</p>
* @param strings <p>The loaded string pairs</p> * @param strings <p>The loaded string pairs</p>
* @throws IOException <p>If unable to read the file</p> * @throws IOException <p>If unable to read the file</p>
@ -297,6 +305,7 @@ public class LanguageLoader {
/** /**
* Removes the UTF-8 Byte Order Mark if present * Removes the UTF-8 Byte Order Mark if present
*
* @param string <p>The string to remove the BOM from</p> * @param string <p>The string to remove the BOM from</p>
* @return <p>A string guaranteed without a BOM</p> * @return <p>A string guaranteed without a BOM</p>
*/ */

View File

@ -26,6 +26,7 @@ import org.bukkit.util.Vector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@ -41,49 +42,57 @@ public class Portal {
// Block references // Block references
private final BlockLocation id; private final BlockLocation id;
private final Gate gate;
private final World world;
private BlockLocation button; private BlockLocation button;
private BlockLocation[] frame; private BlockLocation[] frame;
private BlockLocation[] entrances; private BlockLocation[] entrances;
// Gate information // Gate information
private String name; private String name;
private String destination; private String destination;
private String lastDestination = ""; private String lastDestination = "";
private String network; private String network;
private final Gate gate;
private String ownerName; private String ownerName;
private UUID ownerUUID; private UUID ownerUUID;
private final World world;
private boolean verified; private boolean verified;
private boolean fixed; private boolean fixed;
private Map<PortalOption, Boolean> options;
// 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;
// In-use information // In-use information
private Player player; private Player player;
private Player activePlayer; private Player activePlayer;
private ArrayList<String> destinations = new ArrayList<>(); private List<String> destinations = new ArrayList<>();
private boolean isOpen = false; private boolean isOpen = false;
private long openTime; private long openTime;
/**
* Instantiates a new portal
*
* @param topLeft <p>The top-left block of the portal. This is used to decide the positions of the rest of the portal</p>
* @param modX <p></p>
* @param modZ <p></p>
* @param rotX <p></p>
* @param id <p>The location of the portal's id block, which is the sign which activated the portal</p>
* @param button <p>The location of the portal's open button</p>
* @param destination <p>The destination defined on the sign's destination line</p>
* @param name <p>The name of the portal defined on the sign's first line</p>
* @param verified <p>Whether the portal's gate has been verified to match its template</p>
* @param network <p>The network the portal belongs to, defined on the sign's network line</p>
* @param gate <p>The gate template this portal uses</p>
* @param ownerUUID <p>The UUID of the gate's owner</p>
* @param ownerName <p>The name of the gate's owner</p>
* @param options <p>A map containing all possible portal options</p>
*/
Portal(BlockLocation topLeft, int modX, int modZ, float rotX, BlockLocation id, BlockLocation button, 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<PortalOption, Boolean> options) {
this.topLeft = topLeft; this.topLeft = topLeft;
this.modX = modX; this.modX = modX;
this.modZ = modZ; this.modZ = modZ;
this.rotX = rotX; this.rotX = rotX;
this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z; this.rot = rotX == 0.0F || rotX == 180.0F ? Axis.X : Axis.Z;
this.id = id; this.id = id;
this.destination = dest; this.destination = destination;
this.button = button; this.button = button;
this.verified = verified; this.verified = verified;
this.network = network; this.network = network;
@ -91,62 +100,17 @@ public class Portal {
this.gate = gate; this.gate = gate;
this.ownerUUID = ownerUUID; this.ownerUUID = ownerUUID;
this.ownerName = ownerName; this.ownerName = ownerName;
this.options = options;
this.world = topLeft.getWorld(); 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()) { 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"); Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false");
} }
if (this.random && !this.isAlwaysOn()) { if (this.isRandom() && !this.isAlwaysOn()) {
this.alwaysOn = true; this.options.put(PortalOption.ALWAYS_ON, 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;
Stargate.debug("Portal", "Gate marked as random, set to always-on"); 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 <p>The name to filter</p>
* @return <p>The filtered name</p>
*/
public static String filterName(String input) {
if (input == null) {
return "";
}
return input.replaceAll("[|:#]", "").trim();
}
/**
* Gets whether this portal is currently open
*
* @return <p>Whether this portal is open</p>
*/ */
public boolean isOpen() { public boolean isOpen() {
return isOpen || isAlwaysOn(); return isOpen || isAlwaysOn();
} }
/**
* Gets whether this portal is always on
*
* @return <p>Whether this portal is always on</p>
*/
public boolean isAlwaysOn() { public boolean isAlwaysOn() {
return alwaysOn; return this.options.get(PortalOption.ALWAYS_ON);
}
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;
} }
/** /**
* Getters and Setters * Gets whether this portal is hidden
*
* @return <p>Whether this portal is hidden</p>
*/ */
public boolean isHidden() {
return this.options.get(PortalOption.HIDDEN);
}
/**
* Gets whether this portal is private
*
* @return <p>Whether this portal is private</p>
*/
public boolean isPrivate() {
return this.options.get(PortalOption.PRIVATE);
}
/**
* Gets whether this portal is free
*
* @return <p>Whether this portal is free</p>
*/
public boolean isFree() {
return this.options.get(PortalOption.FREE);
}
/**
* Gets whether this portal is backwards
*
* <p>A backwards portal is one where players exit through the back.</p>
*
* @return <p>Whether this portal is backwards</p>
*/
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 <p>Whether portal gate is shown</p>
*/
public boolean isShown() {
return this.options.get(PortalOption.SHOW);
}
/**
* Gets whether this portal shows no network
*
* @return <p>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 <p>Whether this portal goes to a random location</p>
*/
public boolean isRandom() {
return this.options.get(PortalOption.RANDOM);
}
/**
* Gets whether this portal is a bungee portal
*
* @return <p>Whether this portal is a bungee portal</p>
*/
public boolean isBungee() {
return this.options.get(PortalOption.BUNGEE);
}
/**
* Gets the rotation of the portal in degrees
*
* @return <p>The rotation of the portal</p>
*/
public float getRotation() { public float getRotation() {
return rotX; return rotX;
} }
@ -411,7 +388,7 @@ public class Portal {
Portal end = getDestination(); Portal end = getDestination();
// Only open dest if it's not-fixed or points at this gate // 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.open(openFor, false);
end.setDestination(this); end.setDestination(this);
if (end.isVerified()) end.drawSign(); if (end.isVerified()) end.drawSign();
@ -466,12 +443,17 @@ public class Portal {
/** /**
* Gets whether this portal points to a fixed exit portal * Gets whether this portal points to a fixed exit portal
*
* @return <p>True if this portal points to a fixed exit portal</p> * @return <p>True if this portal points to a fixed exit portal</p>
*/ */
public boolean isFixed() { public boolean isFixed() {
return fixed; return fixed;
} }
public void setFixed(boolean fixed) {
this.fixed = fixed;
}
public boolean isPowered() { public boolean isPowered() {
RelativeBlockVector[] controls = gate.getControls(); RelativeBlockVector[] controls = gate.getControls();
@ -488,6 +470,7 @@ public class Portal {
/** /**
* Teleports a player to this portal * Teleports a player to this portal
*
* @param player <p>The player to teleport</p> * @param player <p>The player to teleport</p>
* @param origin <p>The portal the player teleports from</p> * @param origin <p>The portal the player teleports from</p>
* @param event <p>The player move event triggering the event</p> * @param event <p>The player move event triggering the event</p>
@ -528,6 +511,7 @@ public class Portal {
/** /**
* Teleports a vehicle to this portal * Teleports a vehicle to this portal
*
* @param vehicle <p>The vehicle to teleport</p> * @param vehicle <p>The vehicle to teleport</p>
*/ */
public void teleport(final Vehicle vehicle) { public void teleport(final Vehicle vehicle) {
@ -591,6 +575,7 @@ public class Portal {
/** /**
* Gets the exit location for a given entity and current location * Gets the exit location for a given entity and current location
*
* @param entity <p>The entity to teleport (used to determine distance from portal to avoid suffocation)</p> * @param entity <p>The entity to teleport (used to determine distance from portal to avoid suffocation)</p>
* @param traveller <p>The location of the entity travelling</p> * @param traveller <p>The location of the entity travelling</p>
* @return <p>The location the entity should be teleported to.</p> * @return <p>The location the entity should be teleported to.</p>
@ -624,6 +609,7 @@ public class Portal {
/** /**
* Checks whether the chunk the portal is located at is loaded * Checks whether the chunk the portal is located at is loaded
*
* @return <p>True if the chunk containing the portal is loaded</p> * @return <p>True if the chunk containing the portal is loaded</p>
*/ */
public boolean isChunkLoaded() { public boolean isChunkLoaded() {
@ -633,13 +619,13 @@ public class Portal {
/** /**
* Gets the identity (sign) location of the portal * Gets the identity (sign) location of the portal
*
* @return <p>The identity location of the portal</p> * @return <p>The identity location of the portal</p>
*/ */
public BlockLocation getId() { public BlockLocation getId() {
return this.id; return this.id;
} }
public int getModX() { public int getModX() {
return this.modX; return this.modX;
} }
@ -654,6 +640,7 @@ public class Portal {
/** /**
* Gets the location of the top-left block of the portal * Gets the location of the top-left block of the portal
*
* @return <p>The location of the top-left portal block</p> * @return <p>The location of the top-left portal block</p>
*/ */
public BlockLocation getTopLeft() { public BlockLocation getTopLeft() {
@ -662,6 +649,7 @@ public class Portal {
/** /**
* Verifies that all control blocks in this portal follows its gate template * Verifies that all control blocks in this portal follows its gate template
*
* @return <p>True if all control blocks were verified</p> * @return <p>True if all control blocks were verified</p>
*/ */
public boolean isVerified() { public boolean isVerified() {
@ -677,6 +665,7 @@ public class Portal {
/** /**
* Gets the result of the last portal verification * Gets the result of the last portal verification
*
* @return <p>True if this portal was verified</p> * @return <p>True if this portal was verified</p>
*/ */
public boolean wasVerified() { public boolean wasVerified() {
@ -688,6 +677,7 @@ public class Portal {
/** /**
* Checks if all blocks in a gate matches the gate template * Checks if all blocks in a gate matches the gate template
*
* @return <p>True if all blocks match the gate template</p> * @return <p>True if all blocks match the gate template</p>
*/ */
public boolean checkIntegrity() { public boolean checkIntegrity() {
@ -699,6 +689,7 @@ public class Portal {
/** /**
* Activates this portal for the given player * Activates this portal for the given player
*
* @param player <p>The player to activate the portal for</p> * @param player <p>The player to activate the portal for</p>
* @return <p>True if the portal was activated</p> * @return <p>True if the portal was activated</p>
*/ */
@ -802,7 +793,7 @@ public class Portal {
if (!isActive()) { if (!isActive()) {
Stargate.setLine(sign, ++done, Stargate.getString("signRightClick")); Stargate.setLine(sign, ++done, Stargate.getString("signRightClick"));
Stargate.setLine(sign, ++done, Stargate.getString("signToUse")); Stargate.setLine(sign, ++done, Stargate.getString("signToUse"));
if (!noNetwork) { if (!isNoNetwork()) {
Stargate.setLine(sign, ++done, "(" + network + ")"); Stargate.setLine(sign, ++done, "(" + network + ")");
} }
} else { } else {
@ -817,7 +808,7 @@ public class Portal {
} else { } else {
Stargate.setLine(sign, ++done, ">" + destination + "<"); Stargate.setLine(sign, ++done, ">" + destination + "<");
} }
if (noNetwork) { if (isNoNetwork()) {
Stargate.setLine(sign, ++done, ""); Stargate.setLine(sign, ++done, "");
} else { } else {
Stargate.setLine(sign, ++done, "(" + network + ")"); Stargate.setLine(sign, ++done, "(" + network + ")");
@ -887,6 +878,7 @@ public class Portal {
/** /**
* Gets the block at a relative block vector location * Gets the block at a relative block vector location
*
* @param vector <p>The relative block vector</p> * @param vector <p>The relative block vector</p>
* @return <p>The block at the given relative position</p> * @return <p>The block at the given relative position</p>
*/ */
@ -894,18 +886,6 @@ public class Portal {
return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ); return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ);
} }
/**
* Removes the special characters |, : and # from a portal name
* @param input <p>The name to filter</p>
* @return <p>The filtered name</p>
*/
public static String filterName(String input) {
if (input == null) {
return "";
}
return input.replaceAll("[|:#]", "").trim();
}
@Override @Override
public String toString() { 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]", id, network, name, gate.getFilename());

View File

@ -44,13 +44,14 @@ public class PortalHandler {
/** /**
* Gets all destinations in the network viewable by the given player * Gets all destinations in the network viewable by the given player
*
* @param entrancePortal <p>The portal the user is entering from</p> * @param entrancePortal <p>The portal the user is entering from</p>
* @param player <p>The player who wants to see destinations</p> * @param player <p>The player who wants to see destinations</p>
* @param network <p>The network to get destinations from</p> * @param network <p>The network to get destinations from</p>
* @return <p>All destinations the player can go to</p> * @return <p>All destinations the player can go to</p>
*/ */
public static ArrayList<String> getDestinations(Portal entrancePortal, Player player, String network) { public static List<String> getDestinations(Portal entrancePortal, Player player, String network) {
ArrayList<String> destinations = new ArrayList<>(); List<String> destinations = new ArrayList<>();
for (String destination : allPortalsNet.get(network.toLowerCase())) { for (String destination : allPortalsNet.get(network.toLowerCase())) {
Portal portal = getByName(destination, network); Portal portal = getByName(destination, network);
if (portal == null) { if (portal == null) {
@ -92,6 +93,7 @@ public class PortalHandler {
/** /**
* Un-registers the given portal * Un-registers the given portal
*
* @param portal <p>The portal to un-register</p> * @param portal <p>The portal to un-register</p>
* @param removeAll <p>Whether to remove the portal from the list of all portals</p> * @param removeAll <p>Whether to remove the portal from the list of all portals</p>
*/ */
@ -148,6 +150,7 @@ public class PortalHandler {
/** /**
* Registers a portal * Registers a portal
*
* @param portal <p>The portal to register</p> * @param portal <p>The portal to register</p>
*/ */
private static void registerPortal(Portal portal) { private static void registerPortal(Portal portal) {
@ -193,6 +196,7 @@ public class PortalHandler {
/** /**
* Creates a new portal * Creates a new portal
*
* @param event <p>The sign change event which initialized the creation</p> * @param event <p>The sign change event which initialized the creation</p>
* @param player <p>The player who's creating the portal</p> * @param player <p>The player who's creating the portal</p>
* @return <p>The created portal</p> * @return <p>The created portal</p>
@ -220,63 +224,7 @@ public class PortalHandler {
String network = filterName(event.getLine(2)); String network = filterName(event.getLine(2));
String options = filterName(event.getLine(3)).toLowerCase(); String options = filterName(event.getLine(3)).toLowerCase();
boolean hidden = (options.indexOf('h') != -1); Map<PortalOption, Boolean> portalOptions = getPortalOptions(player, destinationName, options);
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;
}
// Moved the layout check so as to avoid invalid messages when not making a gate // Moved the layout check so as to avoid invalid messages when not making a gate
int modX = 0; 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 // 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 // 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) { if (!Stargate.enableBungee) {
Stargate.sendMessage(player, Stargate.getString("bungeeDisabled")); Stargate.sendMessage(player, Stargate.getString("bungeeDisabled"));
return null; return null;
} else if (!Stargate.hasPerm(player, "stargate.admin.bungee")) {
Stargate.sendMessage(player, Stargate.getString("bungeeDeny"));
return null;
} else if (destinationName.isEmpty() || network.isEmpty()) { } else if (destinationName.isEmpty() || network.isEmpty()) {
Stargate.sendMessage(player, Stargate.getString("bungeeEmpty")); Stargate.sendMessage(player, Stargate.getString("bungeeEmpty"));
return null; return null;
@ -354,9 +305,13 @@ public class PortalHandler {
} }
// Debug // 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(); network = Stargate.getDefaultNetwork();
} }
@ -364,7 +319,7 @@ public class PortalHandler {
String denyMsg = ""; String denyMsg = "";
// Check if the player can create gates on this network // 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"); Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal");
if (Stargate.canCreatePersonal(player)) { if (Stargate.canCreatePersonal(player)) {
network = player.getName(); network = player.getName();
@ -389,7 +344,7 @@ public class PortalHandler {
} }
// Check if the user can create gates to this world. // 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); Portal p = getByName(destinationName, network);
if (p != null) { if (p != null) {
String world = p.getWorld().getName(); String world = p.getWorld().getName();
@ -413,7 +368,8 @@ public class PortalHandler {
BlockLocation button = null; BlockLocation button = null;
Portal portal; 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); int cost = Stargate.getCreateCost(player, gate);
@ -469,11 +425,11 @@ public class PortalHandler {
} }
// No button on an always-open gate. // 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); 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.getButton());
buttondata.setFacing(buttonFacing); buttonData.setFacing(buttonFacing);
button.getBlock().setBlockData(buttondata); button.getBlock().setBlockData(buttonData);
portal.setButton(button); portal.setButton(button);
} }
@ -513,8 +469,48 @@ public class PortalHandler {
return portal; return portal;
} }
/**
* Gets all portal options to be applied to a new gate
*
* @param player <p>The player creating the portal</p>
* @param destinationName <p>The destination of the portal</p>
* @param options <p>The string on the option line of the sign</p>
* @return <p>A map containing all portal options and their values</p>
*/
private static Map<PortalOption, Boolean> getPortalOptions(Player player, String destinationName, String options) {
Map<PortalOption, Boolean> 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 * Gets a portal given its name
*
* @param name <p>The name of the portal</p> * @param name <p>The name of the portal</p>
* @param network <p>The network the portal is connected to</p> * @param network <p>The network the portal is connected to</p>
* @return <p>The portal with the given name or null</p> * @return <p>The portal with the given name or null</p>
@ -529,6 +525,7 @@ public class PortalHandler {
/** /**
* Gets a portal given its entrance * Gets a portal given its entrance
*
* @param location <p>The location of the portal's entrance</p> * @param location <p>The location of the portal's entrance</p>
* @return <p>The portal at the given location</p> * @return <p>The portal at the given location</p>
*/ */
@ -539,6 +536,7 @@ public class PortalHandler {
/** /**
* Gets a portal given its entrance * Gets a portal given its entrance
*
* @param block <p>The block at the portal's entrance</p> * @param block <p>The block at the portal's entrance</p>
* @return <p>The portal at the given block's location</p> * @return <p>The portal at the given block's location</p>
*/ */
@ -548,6 +546,7 @@ public class PortalHandler {
/** /**
* Gets a portal given a location adjacent to its entrance * Gets a portal given a location adjacent to its entrance
*
* @param loc <p>A location adjacent to the portal's entrance</p> * @param loc <p>A location adjacent to the portal's entrance</p>
* @return <p>The portal adjacent to the given location</p> * @return <p>The portal adjacent to the given location</p>
*/ */
@ -581,6 +580,7 @@ public class PortalHandler {
/** /**
* Gets a portal given its control block (the block type used for the sign and button) * Gets a portal given its control block (the block type used for the sign and button)
*
* @param block <p>The portal's control block</p> * @param block <p>The portal's control block</p>
* @return <p>The gate with the given control block</p> * @return <p>The gate with the given control block</p>
*/ */
@ -590,6 +590,7 @@ public class PortalHandler {
/** /**
* Gets a portal given a block * Gets a portal given a block
*
* @param block <p>One of the loaded lookup blocks</p> * @param block <p>One of the loaded lookup blocks</p>
* @return <p>The portal corresponding to the block</p> * @return <p>The portal corresponding to the block</p>
*/ */
@ -599,6 +600,7 @@ public class PortalHandler {
/** /**
* Gets a bungee gate given its name * Gets a bungee gate given its name
*
* @param name <p>The name of the bungee gate to get</p> * @param name <p>The name of the bungee gate to get</p>
* @return <p>A bungee gate</p> * @return <p>A bungee gate</p>
*/ */
@ -608,6 +610,7 @@ public class PortalHandler {
/** /**
* Saves all gates for the given world * Saves all gates for the given world
*
* @param world <p>The world to save gates for</p> * @param world <p>The world to save gates for</p>
*/ */
public static void saveAllGates(World world) { public static void saveAllGates(World world) {
@ -694,6 +697,7 @@ public class PortalHandler {
/** /**
* Loads all gates for the given world * Loads all gates for the given world
*
* @param world <p>The world to load gates for</p> * @param world <p>The world to load gates for</p>
* @return <p>True if gates could be loaded</p> * @return <p>True if gates could be loaded</p>
*/ */
@ -712,25 +716,58 @@ public class PortalHandler {
/** /**
* Loads all the given gates * Loads all the given gates
*
* @param world <p>The world to load gates for</p> * @param world <p>The world to load gates for</p>
* @param database <p>The database file containing the gates</p> * @param database <p>The database file containing the gates</p>
* @return <p>True if the gates were loaded successfully</p> * @return <p>True if the gates were loaded successfully</p>
*/ */
private static boolean loadGates(World world, File database) { private static boolean loadGates(World world, File database) {
int l = 0; int lineIndex = 0;
try { try {
Scanner scanner = new Scanner(database); Scanner scanner = new Scanner(database);
while (scanner.hasNextLine()) { while (scanner.hasNextLine()) {
l++; lineIndex++;
String line = scanner.nextLine().trim(); String line = scanner.nextLine().trim();
//Ignore empty and comment lines
if (line.startsWith("#") || line.isEmpty()) { if (line.startsWith("#") || line.isEmpty()) {
continue; continue;
} }
//Check if the min. required portal data is present
String[] portalData = line.split(":"); String[] portalData = line.split(":");
if (portalData.length < 8) { if (portalData.length < 8) {
Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + l); Stargate.log.info(Stargate.getString("prefix") + "Invalid line - " + lineIndex);
continue; continue;
} }
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<Integer, Integer> portalCounts = openAlwaysOpenGates();
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() + ": " + lineIndex);
e.printStackTrace();
}
return false;
}
/**
* Loads one gate from a data array
*
* @param portalData <p>The array describing the portal</p>
* @param world <p>The world to create the portal in</p>
* @param lineIndex <p>The line index to report in case the user needs to fix an error</p>
*/
private static void loadGate(String[] portalData, World world, int lineIndex) {
//Load min. required portal data
String name = portalData[0]; String name = portalData[0];
BlockLocation sign = new BlockLocation(world, portalData[1]); BlockLocation sign = new BlockLocation(world, portalData[1]);
BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null;
@ -740,13 +777,17 @@ public class PortalHandler {
BlockLocation topLeft = new BlockLocation(world, portalData[6]); BlockLocation topLeft = new BlockLocation(world, portalData[6]);
Gate gate = Gate.getGateByName(portalData[7]); Gate gate = Gate.getGateByName(portalData[7]);
if (gate == null) { 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") + "Gate layout on line " + lineIndex +
continue; " does not exist [" + portalData[7] + "]");
return;
} }
//Load extra portal data
String destination = (portalData.length > 8) ? portalData[8] : ""; String destination = (portalData.length > 8) ? portalData[8] : "";
String network = (portalData.length > 9) ? portalData[9] : Stargate.getDefaultNetwork(); String network = (portalData.length > 9) ? portalData[9] : Stargate.getDefaultNetwork();
if (network.isEmpty()) network = Stargate.getDefaultNetwork(); if (network.isEmpty()) {
network = Stargate.getDefaultNetwork();
}
String ownerString = (portalData.length > 10) ? portalData[10] : ""; String ownerString = (portalData.length > 10) ? portalData[10] : "";
// Attempt to get owner as UUID // Attempt to get owner as UUID
@ -767,48 +808,31 @@ public class PortalHandler {
} }
//Creates the new portal //Creates the new portal
Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, destination, name, false, network, Portal portal = new Portal(topLeft, modX, modZ, rotX, sign, button, destination, name, false,
gate, ownerUUID, ownerName); network, gate, ownerUUID, ownerName, getPortalOptions(portalData));
loadPortalOptions(portal, portalData);
registerPortal(portal); registerPortal(portal);
portal.close(true); portal.close(true);
} }
scanner.close();
// Open any always-on gates. Do this here as it should be more efficient than in the loop.
TwoTuple<Integer, Integer> 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 * Gets all portal options stored in the portal data
* @param portal <p>The portal to apply the options to</p> *
* @param portalData <p>The string list containing all information about a portal</p> * @param portalData <p>The string list containing all information about a portal</p>
* @return <p>A map between portal options and booleans</p>
*/ */
private static void loadPortalOptions(Portal portal, String[] portalData) { private static Map<PortalOption, Boolean> getPortalOptions(String[] portalData) {
boolean hidden = (portalData.length > 11) && portalData[11].equalsIgnoreCase("true"); Map<PortalOption, Boolean> portalOptions = new HashMap<>();
boolean alwaysOn = (portalData.length > 12) && portalData[12].equalsIgnoreCase("true"); for (PortalOption option : PortalOption.values()) {
boolean isPrivate = (portalData.length > 13) && portalData[13].equalsIgnoreCase("true"); int saveIndex = option.getSaveIndex();
boolean free = (portalData.length > 15) && portalData[15].equalsIgnoreCase("true"); portalOptions.put(option, portalData.length > saveIndex && Boolean.parseBoolean(portalData[saveIndex]));
boolean backwards = (portalData.length > 16) && portalData[16].equalsIgnoreCase("true"); }
boolean show = (portalData.length > 17) && portalData[17].equalsIgnoreCase("true"); return portalOptions;
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 * Opens all always open gates
*
* @return <p>A TwoTuple where the first value is the number of always open gates and the second value is the total number of gates</p> * @return <p>A TwoTuple where the first value is the number of always open gates and the second value is the total number of gates</p>
*/ */
private static TwoTuple<Integer, Integer> openAlwaysOpenGates() { private static TwoTuple<Integer, Integer> openAlwaysOpenGates() {
@ -840,6 +864,7 @@ public class PortalHandler {
/** /**
* Destroys a star gate which has failed its integrity test * Destroys a star gate which has failed its integrity test
*
* @param portal <p>The portal of the star gate</p> * @param portal <p>The portal of the star gate</p>
*/ */
private static void destroyInvalidStarGate(Portal portal) { private static void destroyInvalidStarGate(Portal portal) {
@ -867,6 +892,7 @@ public class PortalHandler {
/** /**
* Removes the special characters |, : and # from a portal name * Removes the special characters |, : and # from a portal name
*
* @param input <p>The name to filter</p> * @param input <p>The name to filter</p>
* @return <p>The filtered name</p> * @return <p>The filtered name</p>
*/ */

View File

@ -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 <p>The character representation used on the sign to allow this option</p>
* @param permissionString <p>The permission necessary to use this option</p>
*/
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 <p>The character representation of this option</p>
*/
public char getCharacterRepresentation() {
return this.characterRepresentation;
}
/**
* Gets the permission necessary to use this option
*
* @return <p>The permission necessary for this option</p>
*/
public String getPermissionString() {
return this.permissionString;
}
/**
* Gets the index of the save file this option is stored at
*
* @return <p>This option's save index</p>
*/
public int getSaveIndex() {
return this.saveIndex;
}
}

View File

@ -16,6 +16,7 @@ public class RelativeBlockVector {
/** /**
* Instantiates a new relative block vector * Instantiates a new relative block vector
*
* @param right <p>The distance to the right relative to the origin</p> * @param right <p>The distance to the right relative to the origin</p>
* @param depth <p>The distance downward relative to the origin</p> * @param depth <p>The distance downward relative to the origin</p>
* @param distance <p>The distance outward relative to the origin</p> * @param distance <p>The distance outward relative to the origin</p>
@ -28,6 +29,7 @@ public class RelativeBlockVector {
/** /**
* Gets the distance to the right relative to the origin * 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() { public int getRight() {
@ -36,6 +38,7 @@ public class RelativeBlockVector {
/** /**
* Gets the distance downward relative to the origin * 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() { public int getDepth() {
@ -44,6 +47,7 @@ public class RelativeBlockVector {
/** /**
* Gets the distance outward relative to the origin * 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() { public int getDistance() {

View File

@ -41,25 +41,14 @@ import java.util.logging.Logger;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class Stargate extends JavaPlugin { public class Stargate extends JavaPlugin {
public static final ConcurrentLinkedQueue<Portal> openList = new ConcurrentLinkedQueue<>();
private static final int activeTime = 10;
private static final int openTime = 10;
public static Logger log; public static Logger log;
private FileConfiguration newConfig;
private PluginManager pm;
public static Server server; public static Server server;
public static Stargate stargate; public static Stargate stargate;
public static LanguageLoader languageLoader; 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; 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 destMemory = false;
public static boolean handleVehicles = true; public static boolean handleVehicles = true;
public static boolean sortLists = false; public static boolean sortLists = false;
@ -67,32 +56,36 @@ public class Stargate extends JavaPlugin {
public static boolean enableBungee = true; public static boolean enableBungee = true;
public static boolean verifyPortals = true; public static boolean verifyPortals = true;
public static ChatColor signColor; public static ChatColor signColor;
// Temp workaround for snowmen, don't check gate entrance // Temp workaround for snowmen, don't check gate entrance
public static boolean ignoreEntrance = false; public static boolean ignoreEntrance = false;
// Used for debug // Used for debug
public static boolean debug = false; public static boolean debug = false;
public static boolean permDebug = false; public static boolean permDebug = false;
public static final ConcurrentLinkedQueue<Portal> openList = new ConcurrentLinkedQueue<>();
public static ConcurrentLinkedQueue<Portal> activeList = new ConcurrentLinkedQueue<>(); public static ConcurrentLinkedQueue<Portal> activeList = new ConcurrentLinkedQueue<>();
// Used for populating gate open/closed material. // Used for populating gate open/closed material.
public static Queue<BloxPopulator> blockPopulatorQueue = new LinkedList<>(); public static Queue<BloxPopulator> blockPopulatorQueue = new LinkedList<>();
// HashMap of player names for Bungee support // HashMap of player names for Bungee support
public static Map<String, String> bungeeQueue = new HashMap<>(); public static Map<String, String> bungeeQueue = new HashMap<>();
// World names that contain stargates // World names that contain stargates
public static HashSet<String> managedWorlds = new HashSet<>(); public static HashSet<String> 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() { public Stargate() {
super(); super();
} }
/** /**
* Special constructor used for MockBukkit * Special constructor used for MockBukkit
*
* @param loader <p>The plugin loader to be used.</p> * @param loader <p>The plugin loader to be used.</p>
* @param descriptionFile <p>The description file to be used.</p> * @param descriptionFile <p>The description file to be used.</p>
* @param dataFolder <p>The data folder to be used.</p> * @param dataFolder <p>The data folder to be used.</p>
@ -102,80 +95,6 @@ public class Stargate extends JavaPlugin {
super(loader, descriptionFile, dataFolder, 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() { public static String getPluginVersion() {
return pluginVersion; return pluginVersion;
} }
@ -192,86 +111,6 @@ public class Stargate extends JavaPlugin {
return activeTime; 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) { public static void debug(String rout, String msg) {
if (Stargate.debug) { if (Stargate.debug) {
log.info("[stargate::" + rout + "] " + msg); log.info("[stargate::" + rout + "] " + msg);
@ -442,6 +281,7 @@ public class Stargate extends JavaPlugin {
/** /**
* Checks whether a given user can travel between two portals * Checks whether a given user can travel between two portals
*
* @param player <p>The player to check</p> * @param player <p>The player to check</p>
* @param entrancePortal <p>The portal the user wants to enter</p> * @param entrancePortal <p>The portal the user wants to enter</p>
* @param destination <p>The portal the user wants to exit</p> * @param destination <p>The portal the user wants to exit</p>
@ -497,11 +337,13 @@ public class Stargate extends JavaPlugin {
/* /*
* Check if the player has access to {option} * 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 // 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 // Check if they can use this specific option
return hasPerm(player, "stargate.option." + option); return hasPerm(player, option.getPermissionString());
} }
/* /*
@ -629,24 +471,9 @@ public class Stargate extends JavaPlugin {
return gate.getDestroyCost(); 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.getString("prefix") + "Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")");
return plugin;
}
return null;
}
/** /**
* Replaces a list of variables in a string in the order they are given * Replaces a list of variables in a string in the order they are given
*
* @param input <p>The input containing the variables</p> * @param input <p>The input containing the variables</p>
* @param search <p>The variables to replace</p> * @param search <p>The variables to replace</p>
* @param values <p>The replacement values</p> * @param values <p>The replacement values</p>
@ -664,6 +491,7 @@ public class Stargate extends JavaPlugin {
/** /**
* Replaces a variable in a string * Replaces a variable in a string
*
* @param input <p>The input containing the variables</p> * @param input <p>The input containing the variables</p>
* @param search <p>The variable to replace</p> * @param search <p>The variable to replace</p>
* @param value <p>The replacement value</p> * @param value <p>The replacement value</p>
@ -673,8 +501,179 @@ public class Stargate extends JavaPlugin {
return input.replace(search, 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
*/
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.getString("prefix") + "Found " + plugin.getDescription().getName() + " (v" + plugin.getDescription().getVersion() + ")");
return plugin;
}
return null;
}
/** /**
* Reloads all portals and files * Reloads all portals and files
*
* @param sender <p>The sender of the reload request</p> * @param sender <p>The sender of the reload request</p>
*/ */
public void reload(CommandSender sender) { public void reload(CommandSender sender) {

View File

@ -2,6 +2,7 @@ package net.knarcraft.stargate;
/** /**
* This class allows storing two values of any type * This class allows storing two values of any type
*
* @param <K> <p>The first type</p> * @param <K> <p>The first type</p>
* @param <L> <p>The second type</p> * @param <L> <p>The second type</p>
*/ */
@ -12,6 +13,7 @@ public class TwoTuple<K,L> {
/** /**
* Instantiate a new TwoTuple * Instantiate a new TwoTuple
*
* @param firstValue <p>The first value</p> * @param firstValue <p>The first value</p>
* @param secondValue <p>The second value</p> * @param secondValue <p>The second value</p>
*/ */
@ -22,6 +24,7 @@ public class TwoTuple<K,L> {
/** /**
* Gets the first value * Gets the first value
*
* @return <p>The first value</p> * @return <p>The first value</p>
*/ */
public K getFirstValue() { public K getFirstValue() {
@ -30,6 +33,7 @@ public class TwoTuple<K,L> {
/** /**
* Gets the second value * Gets the second value
*
* @return <p>The second value</p> * @return <p>The second value</p>
*/ */
public L getSecondValue() { public L getSecondValue() {

View File

@ -16,6 +16,7 @@ public class CommandReload implements CommandExecutor {
/** /**
* Instantiates the reload command * Instantiates the reload command
*
* @param plugin <p>A reference to the calling plugin object</p> * @param plugin <p>A reference to the calling plugin object</p>
*/ */
public CommandReload(Stargate plugin) { public CommandReload(Stargate plugin) {

View File

@ -19,6 +19,7 @@ public class CommandStarGate implements CommandExecutor {
/** /**
* Instantiates the stargate command * Instantiates the stargate command
*
* @param plugin <p>A reference to the calling plugin object</p> * @param plugin <p>A reference to the calling plugin object</p>
*/ */
public CommandStarGate(Stargate plugin) { public CommandStarGate(Stargate plugin) {

View File

@ -11,12 +11,12 @@ import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class StargateAccessEvent extends StargatePlayerEvent { 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 * Instantiates a new stargate access event
*
* @param player <p>The player involved in the vent</p> * @param player <p>The player involved in the vent</p>
* @param portal <p>The portal involved in the event</p> * @param portal <p>The portal involved in the event</p>
* @param deny <p>Whether the event should be denied</p> * @param deny <p>Whether the event should be denied</p>
@ -27,8 +27,18 @@ public class StargateAccessEvent extends StargatePlayerEvent {
this.deny = deny; this.deny = deny;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Gets whether the player should be denied access * Gets whether the player should be denied access
*
* @return <p>Whether the player should be denied access</p> * @return <p>Whether the player should be denied access</p>
*/ */
public boolean getDeny() { public boolean getDeny() {
@ -37,20 +47,13 @@ public class StargateAccessEvent extends StargatePlayerEvent {
/** /**
* Sets whether to deny the player * Sets whether to deny the player
*
* @param deny <p>Whether to deny the player</p> * @param deny <p>Whether to deny the player</p>
*/ */
public void setDeny(boolean deny) { public void setDeny(boolean deny) {
this.deny = deny; this.deny = deny;
} }
/**
* Gets a handler-list containing all event handlers
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@Override @Override
@NotNull @NotNull
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -14,11 +14,10 @@ import java.util.List;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class StargateActivateEvent extends StargatePlayerEvent { public class StargateActivateEvent extends StargatePlayerEvent {
private static final HandlerList handlers = new HandlerList();
private List<String> destinations; private List<String> destinations;
private String destination; private String destination;
private static final HandlerList handlers = new HandlerList();
/** /**
* Instantiates a new stargate activate event * Instantiates a new stargate activate event
* *
@ -34,6 +33,15 @@ public class StargateActivateEvent extends StargatePlayerEvent {
this.destination = destination; this.destination = destination;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Gets the destinations available for the portal * Gets the destinations available for the portal
* *
@ -70,15 +78,6 @@ public class StargateActivateEvent extends StargatePlayerEvent {
this.destination = destination; this.destination = destination;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@Override @Override
@NotNull @NotNull
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -10,9 +10,8 @@ import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class StargateCloseEvent extends StargateEvent { public class StargateCloseEvent extends StargateEvent {
private boolean force;
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private boolean force;
/** /**
* Instantiates a new stargate closing event * Instantiates a new stargate closing event
@ -26,6 +25,15 @@ public class StargateCloseEvent extends StargateEvent {
this.force = force; this.force = force;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Gets whether to force the stargate to close * Gets whether to force the stargate to close
* *
@ -44,15 +52,6 @@ public class StargateCloseEvent extends StargateEvent {
this.force = force; this.force = force;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull @NotNull
@Override @Override
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -11,13 +11,12 @@ import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class StargateCreateEvent extends StargatePlayerEvent { public class StargateCreateEvent extends StargatePlayerEvent {
private static final HandlerList handlers = new HandlerList();
private final String[] lines;
private boolean deny; private boolean deny;
private String denyReason; private String denyReason;
private final String[] lines;
private int cost; private int cost;
private static final HandlerList handlers = new HandlerList();
/** /**
* Instantiates a new stargate creation event * Instantiates a new stargate creation event
* *
@ -36,6 +35,15 @@ public class StargateCreateEvent extends StargatePlayerEvent {
this.cost = cost; this.cost = cost;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Gets a given line from the sign creating the star gate * Gets a given line from the sign creating the star gate
* *
@ -101,15 +109,6 @@ public class StargateCreateEvent extends StargatePlayerEvent {
this.cost = cost; this.cost = cost;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull @NotNull
@Override @Override
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -11,14 +11,14 @@ import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class StargateDestroyEvent extends StargatePlayerEvent { public class StargateDestroyEvent extends StargatePlayerEvent {
private static final HandlerList handlers = new HandlerList();
private boolean deny; private boolean deny;
private String denyReason; private String denyReason;
private int cost; private int cost;
private static final HandlerList handlers = new HandlerList();
/** /**
* Instantiates a new Stargate Destroy Event * Instantiates a new Stargate Destroy Event
*
* @param portal <p>The portal destroyed</p> * @param portal <p>The portal destroyed</p>
* @param player <p>The player destroying the portal</p> * @param player <p>The player destroying the portal</p>
* @param deny <p>Whether the event should be denied (cancelled)</p> * @param deny <p>Whether the event should be denied (cancelled)</p>
@ -32,8 +32,18 @@ public class StargateDestroyEvent extends StargatePlayerEvent {
this.cost = cost; this.cost = cost;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Gets whether this event should be denied * Gets whether this event should be denied
*
* @return <p>Whether this event should be denied</p> * @return <p>Whether this event should be denied</p>
*/ */
public boolean getDeny() { public boolean getDeny() {
@ -42,6 +52,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent {
/** /**
* Sets whether this event should be denied * Sets whether this event should be denied
*
* @param deny <p>Whether this event should be denied</p> * @param deny <p>Whether this event should be denied</p>
*/ */
public void setDeny(boolean deny) { public void setDeny(boolean deny) {
@ -50,6 +61,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent {
/** /**
* Gets the reason the event was denied * Gets the reason the event was denied
*
* @return <p>The reason the event was denied</p> * @return <p>The reason the event was denied</p>
*/ */
public String getDenyReason() { public String getDenyReason() {
@ -58,6 +70,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent {
/** /**
* Sets the reason the event was denied * Sets the reason the event was denied
*
* @param denyReason <p>The reason the event was denied</p> * @param denyReason <p>The reason the event was denied</p>
*/ */
public void setDenyReason(String denyReason) { public void setDenyReason(String denyReason) {
@ -66,6 +79,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent {
/** /**
* Gets the cost of destroying the portal * Gets the cost of destroying the portal
*
* @return <p>The cost of destroying the portal</p> * @return <p>The cost of destroying the portal</p>
*/ */
public int getCost() { public int getCost() {
@ -74,21 +88,13 @@ public class StargateDestroyEvent extends StargatePlayerEvent {
/** /**
* Sets the cost of destroying the portal * Sets the cost of destroying the portal
*
* @param cost <p>The cost of destroying the portal</p> * @param cost <p>The cost of destroying the portal</p>
*/ */
public void setCost(int cost) { public void setCost(int cost) {
this.cost = cost; this.cost = cost;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull @NotNull
@Override @Override
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -15,6 +15,7 @@ public abstract class StargateEvent extends Event implements Cancellable {
/** /**
* Instantiates a new stargate event * Instantiates a new stargate event
*
* @param event <p>UNUSED</p> * @param event <p>UNUSED</p>
* @param portal <p>The portal involved in this stargate event</p> * @param portal <p>The portal involved in this stargate event</p>
*/ */
@ -25,6 +26,7 @@ public abstract class StargateEvent extends Event implements Cancellable {
/** /**
* Gets the portal involved in this stargate event * Gets the portal involved in this stargate event
*
* @return <p>The portal involved in this stargate event</p> * @return <p>The portal involved in this stargate event</p>
*/ */
public Portal getPortal() { public Portal getPortal() {

View File

@ -10,12 +10,12 @@ import org.jetbrains.annotations.NotNull;
*/ */
public class StargateOpenEvent extends StargatePlayerEvent { public class StargateOpenEvent extends StargatePlayerEvent {
private boolean force;
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private boolean force;
/** /**
* Instantiates a new stargate open event * Instantiates a new stargate open event
*
* @param player <p>The player opening the stargate</p> * @param player <p>The player opening the stargate</p>
* @param portal <p>The portal opened</p> * @param portal <p>The portal opened</p>
* @param force <p>Whether to force the portal open</p> * @param force <p>Whether to force the portal open</p>
@ -26,8 +26,18 @@ public class StargateOpenEvent extends StargatePlayerEvent {
this.force = force; this.force = force;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Gets whether the portal should be forced open * Gets whether the portal should be forced open
*
* @return <p>Whether the portal should be forced open</p> * @return <p>Whether the portal should be forced open</p>
*/ */
public boolean getForce() { public boolean getForce() {
@ -36,20 +46,13 @@ public class StargateOpenEvent extends StargatePlayerEvent {
/** /**
* Sets whether the portal should be forced open * Sets whether the portal should be forced open
*
* @param force <p>Whether the portal should be forced open</p> * @param force <p>Whether the portal should be forced open</p>
*/ */
public void setForce(boolean force) { public void setForce(boolean force) {
this.force = force; this.force = force;
} }
/**
* Gets a handler-list containing all event handlers
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@Override @Override
@NotNull @NotNull
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -12,13 +12,13 @@ import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class StargatePortalEvent extends StargatePlayerEvent { public class StargatePortalEvent extends StargatePlayerEvent {
private static final HandlerList handlers = new HandlerList();
private final Portal destination; private final Portal destination;
private Location exit; private Location exit;
private static final HandlerList handlers = new HandlerList();
/** /**
* Instantiates a new stargate portal event * Instantiates a new stargate portal event
*
* @param player <p>The player teleporting</p> * @param player <p>The player teleporting</p>
* @param portal <p>The portal the player entered from</p> * @param portal <p>The portal the player entered from</p>
* @param destination <p>The destination the player should exit from</p> * @param destination <p>The destination the player should exit from</p>
@ -31,6 +31,15 @@ public class StargatePortalEvent extends StargatePlayerEvent {
this.exit = exit; this.exit = exit;
} }
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
/** /**
* Return the destination gate * Return the destination gate
* *
@ -56,14 +65,6 @@ public class StargatePortalEvent extends StargatePlayerEvent {
this.exit = loc; this.exit = loc;
} }
/**
* Gets a handler-list containing all event handlers
* @return <p>A handler-list with all event handlers</p>
*/
public static HandlerList getHandlerList() {
return handlers;
}
@Override @Override
@NotNull @NotNull
public HandlerList getHandlers() { public HandlerList getHandlers() {

View File

@ -57,7 +57,11 @@ public class BlockEventListener implements Listener {
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) /**
* Detects block breaking to detect if the user is destroying a gate
*
* @param event <p>The triggered event</p>
*/
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
@ -113,6 +117,7 @@ public class BlockEventListener implements Listener {
/** /**
* Handles economy payment for breaking the portal * Handles economy payment for breaking the portal
*
* @param destroyEvent <p>The destroy event</p> * @param destroyEvent <p>The destroy event</p>
* @param player <p>The player which triggered the event</p> * @param player <p>The player which triggered the event</p>
* @param portal <p>The broken portal</p> * @param portal <p>The broken portal</p>
@ -140,6 +145,7 @@ public class BlockEventListener implements Listener {
/** /**
* Prevents any block physics events which may damage parts of the portal * Prevents any block physics events which may damage parts of the portal
*
* @param event <p>The event to check and possibly cancel</p> * @param event <p>The event to check and possibly cancel</p>
*/ */
@EventHandler @EventHandler

View File

@ -1,16 +1,11 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.Portal;
import net.knarcraft.stargate.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.utility.BungeeHelper;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener; import org.bukkit.plugin.messaging.PluginMessageListener;
import org.jetbrains.annotations.NotNull; 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 * 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 { public class BungeeCordListener implements PluginMessageListener {
/**
* Receive a plugin message
*
* @param channel <p>The channel the message was received on</p>
* @param unused <p>Unused.</p>
* @param message <p>The message received from the plugin</p>
*/
@Override @Override
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player unused, @NotNull byte[] message) { 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")) { if (!Stargate.enableBungee || !channel.equals("BungeeCord")) {
return; return;
} }
String receivedMessage = readPluginMessage(message); String receivedMessage = BungeeHelper.readPluginMessage(message);
if (receivedMessage == null) { if (receivedMessage == null) {
return; return;
} }
String[] messageParts = receivedMessage.split("#@#"); BungeeHelper.handleTeleportMessage(receivedMessage);
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);
}
} }
/**
* Reads a plugin message byte array to a string
* @param message <p>The byte array to read</p>
* @return <p>The message contained in the byte array</p>
*/
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);
}
} }

View File

@ -18,6 +18,7 @@ public class EntityEventListener implements Listener {
/** /**
* This event handler prevents sending entities to the normal nether instead of the stargate target * This event handler prevents sending entities to the normal nether instead of the stargate target
*
* @param event <p>The event to check and possibly cancel</p> * @param event <p>The event to check and possibly cancel</p>
*/ */
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)

View File

@ -1,10 +1,12 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.Portal;
import net.knarcraft.stargate.PortalHandler; 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.EconomyHelper;
import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.MaterialHelper;
import net.knarcraft.stargate.Portal;
import net.knarcraft.stargate.Stargate;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; 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.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Objects; import java.util.Objects;
public class PlayerEventsListener implements Listener { public class PlayerEventsListener implements Listener {
@ -31,6 +30,11 @@ public class PlayerEventsListener implements Listener {
private static long eventTime; private static long eventTime;
private static PlayerInteractEvent previousEvent; private static PlayerInteractEvent previousEvent;
/**
* This event handler handles detection of any player teleporting through a bungee gate
*
* @param event <p>The event to check for a teleporting player</p>
*/
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
if (!Stargate.enableBungee) { if (!Stargate.enableBungee) {
@ -51,6 +55,15 @@ public class PlayerEventsListener implements Listener {
portal.teleport(player, portal, null); portal.teleport(player, portal, null);
} }
/**
* This event handler handles some special teleportation events
*
* <p>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.</p>
*
* @param event <p>The event to check and possibly cancel</p>
*/
@EventHandler @EventHandler
public void onPlayerTeleport(PlayerTeleportEvent event) { public void onPlayerTeleport(PlayerTeleportEvent event) {
// cancel portal and end gateway teleportation if it's from a stargate entrance // cancel portal and end gateway teleportation if it's from a stargate entrance
@ -76,101 +89,39 @@ public class PlayerEventsListener implements Listener {
} }
} }
/**
* This event handler detects if a player moves into a portal
*
* @param event <p>Player move event which was triggered</p>
*/
@EventHandler @EventHandler
public void onPlayerMove(PlayerMoveEvent event) { public void onPlayerMove(PlayerMoveEvent event) {
if (event.isCancelled()) return; if (event.isCancelled()) {
return;
}
// Check to see if the player actually moved //Check to see if the player moved to another block
if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == BlockLocation fromLocation = (BlockLocation) event.getFrom();
event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { BlockLocation toLocation = (BlockLocation) event.getTo();
if (toLocation == null || fromLocation.equals(toLocation)) {
return; return;
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
Portal entrancePortal = PortalHandler.getByEntrance(event.getTo()); Portal entrancePortal = PortalHandler.getByEntrance(toLocation);
// 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 destination = entrancePortal.getDestination(player); Portal destination = entrancePortal.getDestination(player);
if (!entrancePortal.isBungee() && destination == null) {
return;
}
if (!Stargate.canAccessPortal(player, entrancePortal, destination)) { //Decide if the anything stops the player from teleport
Stargate.sendMessage(player, Stargate.getString("denyMsg")); if (!playerCanTeleport(entrancePortal, destination, player, event)) {
entrancePortal.teleport(player, entrancePortal, event);
entrancePortal.close(false);
return; 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); Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false);
// BungeeCord Support //Decide if the user should be teleported to another bungee server
if (entrancePortal.isBungee()) { if (entrancePortal.isBungee() && bungeeTeleport(player, entrancePortal, event)) {
if (!Stargate.enableBungee) {
player.sendMessage(Stargate.getString("bungeeDisabled"));
entrancePortal.close(false);
return; 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 <player>#@#<destination>
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);
return;
}
destination.teleport(player, entrancePortal, event); destination.teleport(player, entrancePortal, event);
entrancePortal.close(false); entrancePortal.close(false);
} }
@ -284,4 +235,83 @@ public class PlayerEventsListener implements Listener {
} }
} }
/**
* Teleports a player to a bungee gate
*
* @param player <p>The player to teleport</p>
* @param entrancePortal <p>The gate the player is entering from</p>
* @param event <p>The event causing the teleportation</p>
* @return <p>True if the teleportation was successful</p>
*/
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 <p>The portal the player is entering from</p>
* @param destination <p>The destination of the portal the player is inside</p>
* @param player <p>The player wanting to teleport</p>
* @param event <p>The move event causing the teleportation</p>
* @return <p>True if the player can teleport. False otherwise</p>
*/
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;
}
} }

View File

@ -16,30 +16,6 @@ import java.util.List;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class VehicleEventListener implements Listener { public class VehicleEventListener implements Listener {
/**
* Check for a vehicle moving through a portal
* @param event <p>The triggered move event</p>
*/
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
if (!Stargate.handleVehicles) {
return;
}
List<Entity> 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) { public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player) {
destinationPortal.teleport(vehicle); destinationPortal.teleport(vehicle);
Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6);
@ -47,6 +23,7 @@ public class VehicleEventListener implements Listener {
/** /**
* Teleports a vehicle through a stargate * Teleports a vehicle through a stargate
*
* @param passengers <p>The passengers inside the vehicle</p> * @param passengers <p>The passengers inside the vehicle</p>
* @param entrancePortal <p>The portal the vehicle is entering</p> * @param entrancePortal <p>The portal the vehicle is entering</p>
* @param vehicle <p>The vehicle passing through</p> * @param vehicle <p>The vehicle passing through</p>
@ -57,6 +34,7 @@ public class VehicleEventListener implements Listener {
/** /**
* Teleports a vehicle through a stargate * Teleports a vehicle through a stargate
*
* @param passengers <p>The passengers inside the vehicle</p> * @param passengers <p>The passengers inside the vehicle</p>
* @param entrancePortal <p>The portal the vehicle is entering</p> * @param entrancePortal <p>The portal the vehicle is entering</p>
* @param vehicle <p>The vehicle passing through</p> * @param vehicle <p>The vehicle passing through</p>
@ -79,6 +57,7 @@ public class VehicleEventListener implements Listener {
/** /**
* Teleports a player and the vehicle the player sits in * Teleports a player and the vehicle the player sits in
*
* @param entrancePortal <p>The portal the minecart entered</p> * @param entrancePortal <p>The portal the minecart entered</p>
* @param vehicle <p>The vehicle to teleport</p> * @param vehicle <p>The vehicle to teleport</p>
* @param passengers <p>Any entities sitting in the minecart</p> * @param passengers <p>Any entities sitting in the minecart</p>
@ -116,4 +95,29 @@ public class VehicleEventListener implements Listener {
entrancePortal.close(false); entrancePortal.close(false);
} }
/**
* Check for a vehicle moving through a portal
*
* @param event <p>The triggered move event</p>
*/
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
if (!Stargate.handleVehicles) {
return;
}
List<Entity> 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);
}
} }

View File

@ -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 <p>The player teleporting</p>
* @param entrancePortal <p>The portal the player is teleporting from</p>
* @return <p>True if the message was successfully sent</p>
*/
public static boolean sendTeleportationMessage(Player player, Portal entrancePortal) {
try {
// Build the message, format is <player>#@#<destination>
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 <p>The player to teleport</p>
* @param entrancePortal <p>The bungee portal the player teleports from</p>
* @return <p>True if able to send the plugin message</p>
*/
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 <p>The byte array to read</p>
* @return <p>The message contained in the byte array or null on failure</p>
*/
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 <p>The received message</p>
*/
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);
}
}
}

View File

@ -9,6 +9,7 @@ public class EconomyHelper {
/** /**
* Tries to make the given user pay the teleport fee * Tries to make the given user pay the teleport fee
*
* @param entrancePortal <p>The portal the player is entering</p> * @param entrancePortal <p>The portal the player is entering</p>
* @param player <p>The player wishing to teleport</p> * @param player <p>The player wishing to teleport</p>
* @param cost <p>The cost of teleportation</p> * @param cost <p>The cost of teleportation</p>
@ -52,6 +53,7 @@ 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 * Sends a message to the gate owner telling him/her how much he/she earned from a player using his/her gate
*
* @param portalName <p>The name of the used portal</p> * @param portalName <p>The name of the used portal</p>
* @param portalOwner <p>The owner of the portal</p> * @param portalOwner <p>The owner of the portal</p>
* @param earnings <p>The amount the owner earned</p> * @param earnings <p>The amount the owner earned</p>
@ -64,6 +66,7 @@ public class EconomyHelper {
/** /**
* Sends a message telling the user how much they paid for interacting with a portal * Sends a message telling the user how much they paid for interacting with a portal
*
* @param portalName <p>The name of the portal interacted with</p> * @param portalName <p>The name of the portal interacted with</p>
* @param player <p>The interacting player</p> * @param player <p>The interacting player</p>
* @param cost <p>The cost of the interaction</p> * @param cost <p>The cost of the interaction</p>
@ -76,6 +79,7 @@ public class EconomyHelper {
/** /**
* Sends a message telling the user they don't have enough funds to do a portal interaction * Sends a message telling the user they don't have enough funds to do a portal interaction
*
* @param portalName <p>The name of the portal interacted with</p> * @param portalName <p>The name of the portal interacted with</p>
* @param player <p>The interacting player</p> * @param player <p>The interacting player</p>
* @param cost <p>The cost of the interaction</p> * @param cost <p>The cost of the interaction</p>
@ -88,6 +92,7 @@ public class EconomyHelper {
/** /**
* Sends a message telling the user how much they are refunded for breaking their portal * Sends a message telling the user how much they are refunded for breaking their portal
*
* @param portalName <p>The name of the broken portal</p> * @param portalName <p>The name of the broken portal</p>
* @param player <p>The player breaking the portal</p> * @param player <p>The player breaking the portal</p>
* @param cost <p>The amount the user has to pay for destroying the portal. (expects a negative value)</p> * @param cost <p>The amount the user has to pay for destroying the portal. (expects a negative value)</p>
@ -100,6 +105,7 @@ public class EconomyHelper {
/** /**
* Replaces the cost and portal variables in a string * Replaces the cost and portal variables in a string
*
* @param message <p>The message to replace variables in</p> * @param message <p>The message to replace variables in</p>
* @param portalName <p>The name of the relevant portal</p> * @param portalName <p>The name of the relevant portal</p>
* @param cost <p>The cost for a given interaction</p> * @param cost <p>The cost for a given interaction</p>

View File

@ -10,6 +10,7 @@ public final class MaterialHelper {
/** /**
* Checks whether the given material is a dead or alive wall coral * Checks whether the given material is a dead or alive wall coral
*
* @param material <p>The material to check</p> * @param material <p>The material to check</p>
* @return <p>True if the material is a wall coral</p> * @return <p>True if the material is a wall coral</p>
*/ */
@ -24,6 +25,7 @@ public final class MaterialHelper {
/** /**
* Checks whether the given material can be used as a button * Checks whether the given material can be used as a button
*
* @param material <p>The material to check</p> * @param material <p>The material to check</p>
* @return <p>True if the material can be used as a button</p> * @return <p>True if the material can be used as a button</p>
*/ */