Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
88bb02dfbd | |||
4db6274dc3 | |||
9c963c9e8c | |||
fc744b04dc | |||
1565707809 | |||
527562bc60 | |||
42e208402e | |||
7f91808baf | |||
0540498818 | |||
57ec7071cf | |||
5f2d7988e2 | |||
ac25f2747f | |||
aa3bb58b33 | |||
ee0e66e9be | |||
f90a09143f | |||
8c4cf16375 | |||
4566c15350 | |||
0297d62d6d | |||
80ff241d4b | |||
f3292cff99 | |||
8c37b11484 | |||
e0ac9b41e7 | |||
e5c1ad1f3a | |||
cab99e11b0 | |||
3c4d10ae3f | |||
aff0082906 | |||
20c3c93c06 | |||
dab9378a67 | |||
62661f65f4 | |||
b8d98c26d4 | |||
8bb9c464d6 | |||
2b5d791581 | |||
2a61480684 | |||
91a0316e6e |
58
README.md
58
README.md
@ -10,6 +10,7 @@ can share a network or be split into clusters; they can be hidden on a network o
|
||||
- Multiple built-in languages (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru)
|
||||
- Teleport across worlds or servers (BungeeCord supported)
|
||||
- Vehicle teleportation -- teleport minecarts, boats, horses, pigs and striders
|
||||
- Leashed teleportation -- teleport any creature in a leash with the player
|
||||
- Underwater portals -- portals can be placed underwater as long as a waterproof button is used
|
||||
- API available -- using the API, a lot of behavior can be changed
|
||||
- Button customization -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests)
|
||||
@ -58,7 +59,9 @@ stargate.option -- Allow use of all options
|
||||
stargate.option.backwards -- Allow use of 'B'ackwards
|
||||
stargate.option.show -- Allow use of 'S'how
|
||||
stargate.option.nonetwork -- Allow use of 'N'oNetwork
|
||||
stargate.option.random -- Allow use of 'Random' stargates
|
||||
stargate.option.random -- Allow use of 'R'andom stargates
|
||||
stargate.option.silent -- Allow use of S'i'lent stargates
|
||||
stargate.option.nosign -- Allow use of 'E' (No sign)
|
||||
|
||||
stargate.create -- Allow creating Stargates on any network (Override all create permissions)
|
||||
stargate.create.personal -- Allow creating Stargates on network {playername}
|
||||
@ -126,8 +129,10 @@ section). See the Custom Gate Layout section to learn how to add custom gates.
|
||||
- 'S' is for showing an always-on gate in the network list
|
||||
- 'N' is for hiding the network name
|
||||
- 'R' is for random gates. These follow standard permissions of gates, but have a random exit location every time a
|
||||
player enters.
|
||||
- 'U' is for a gate connecting to another through bungee
|
||||
player enters. (Implicitly always on)
|
||||
- 'U' is for a gate connecting to another through bungee (Implicitly always on)
|
||||
- 'I' is for a silent gate, which does not output anything to the chat while teleporting. Increases immersion
|
||||
- 'E' is for gate without a sign. Only for fixed stargates
|
||||
|
||||
The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'.
|
||||
|
||||
@ -199,7 +204,11 @@ The key `button` is used to define the type of button that is generated for this
|
||||
a type of wall coral (dead or alive), a type of shulker box or a chest.
|
||||
|
||||
`X` and `-` are used to define block types for the layout (Any single-character can be used, such as `#`).
|
||||
In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are.
|
||||
In the gate format, you can see we use `X` to show where obsidian must be, `-` where the controls (Button/sign) are.
|
||||
|
||||
For more complex gate designs, it is possible to add more materials. If you add something like a=GLOWSTONE, `a` can then
|
||||
be used in the gate layout, just as `X` is used. See the `squarenetherglowstonegate.gate` file for an example.
|
||||
|
||||
You will also notice a `*` in the gate layout, this is the "exit point" of the gate, the block at which the player will
|
||||
teleport in front of.
|
||||
|
||||
@ -301,6 +310,10 @@ gates:
|
||||
functionality:
|
||||
enableBungee - Enable this for BungeeCord support. This allows portals across Bungee servers.
|
||||
handleVehicles - Whether or not to handle vehicles going through gates. Set to false to disallow vehicles (Manned or not) going through gates.
|
||||
handleEmptyVehicles - Whether or not to handle empty vehicles going through gates (chest/hopper/tnt/furnace minecarts included).
|
||||
handleCreatureTransportation - Whether or not to handle players that transport creatures by sending vehicles (minecarts, boats) through gates.
|
||||
handleNonPlayerVehicles - Whether or not to handle vehicles with a passenger which is not a player going through gates (pigs, horses, villagers, creepers, etc.). handleCreatureTransportation must be enabled.
|
||||
handleLeashedCreatures - Whether or not to handle creatures leashed by a player going through gates. Set to false to disallow leashed creatures going through gates.
|
||||
economy:
|
||||
useEconomy - Whether or not to enable Economy using Vault (must have the Vault plugin)
|
||||
createCost - The cost to create a stargate
|
||||
@ -363,10 +376,47 @@ bungeeDisabled=BungeeCord support is disabled.
|
||||
bungeeDeny=You do not have permission to create BungeeCord gates.
|
||||
bungeeEmpty=BungeeCord gates require both a destination and network.
|
||||
bungeeSign=Teleport to
|
||||
|
||||
portalInfoTitle=[STARGATE INFO]
|
||||
portalInfoName=Name: %name%
|
||||
portalInfoDestination=Destination: %destination%
|
||||
portalInfoNetwork=Network: %network%
|
||||
portalInfoServer=Server: %server%
|
||||
```
|
||||
|
||||
# Changes
|
||||
|
||||
#### \[Version 0.9.0.6] EpicKnarvik97 fork
|
||||
|
||||
- Makes containers no longer open when used as buttons
|
||||
- Validates and updates stargate buttons when the plugin is loaded or reloaded
|
||||
- Adds an option to make a stargate silent (no text in chat when teleporting) for better immersion on RP servers
|
||||
- Makes buttons update and/or remove themselves when their location or material changes
|
||||
- Adds another default gate to show that it's possible to use any number of materials for a stargate's border
|
||||
- Adds an option for stargates without a sign. Right-clicking such a stargate will display gate information
|
||||
- Fixes a bug causing signs to be re-drawn after they're broken
|
||||
- Makes buttons and signs be replaced by water instead of air when underwater
|
||||
- Makes portal info shown when right-clicking a stargate fully customizable
|
||||
|
||||
#### \[Version 0.9.0.5] EpicKnarvik97 fork
|
||||
|
||||
- Adds an option to stargate functionality to disable all teleportation of creatures
|
||||
- Adds an option to stargate functionality to disable all teleportation of empty minecarts
|
||||
- Adds an option to stargate functionality to disable teleportation of creatures if no player is present in the vehicle
|
||||
- Prevents a player in a vehicle from teleporting without the vehicle if vehicle teleportation is disabled
|
||||
- Prevents an infinite number of teleportation messages if vehicle teleportation is detected but denied
|
||||
|
||||
#### \[Version 0.9.0.4] EpicKnarvik97 fork
|
||||
|
||||
- Adds teleportation of leashed creatures. By default, any creature connected to a player by a lead will be teleported
|
||||
with the player through stargates, even if the player is in a vehicle. This behavior can be disabled in the config
|
||||
file.
|
||||
|
||||
#### \[Version 0.9.0.3] EpicKnarvik97 fork
|
||||
|
||||
- Adds a missing error message when a player in a vehicle cannot pay the teleportation fee
|
||||
- Adds UUID migration to automatically update player names to UUID when possible
|
||||
|
||||
#### \[Version 0.9.0.2] EpicKnarvik97 fork
|
||||
|
||||
- Fixes a bug causing Stargates using NETHER_PORTAL blocks to generate nether portals in the nether.
|
||||
|
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>Stargate</artifactId>
|
||||
<version>0.9.0.2</version>
|
||||
<version>0.9.0.6</version>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.knarcraft.stargate.config;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.portal.Gate;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -3,10 +3,10 @@ package net.knarcraft.stargate.config;
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockChangeRequest;
|
||||
import net.knarcraft.stargate.listener.BungeeCordListener;
|
||||
import net.knarcraft.stargate.portal.GateHandler;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.PortalRegistry;
|
||||
import net.knarcraft.stargate.portal.property.gate.GateHandler;
|
||||
import net.knarcraft.stargate.thread.BlockChangeThread;
|
||||
import net.knarcraft.stargate.utility.FileHelper;
|
||||
import net.knarcraft.stargate.utility.PortalFileHelper;
|
||||
|
@ -13,6 +13,10 @@ public final class StargateGateConfig {
|
||||
private int maxGatesEachNetwork = 0;
|
||||
private boolean rememberDestination = false;
|
||||
private boolean handleVehicles = true;
|
||||
private boolean handleEmptyVehicles = true;
|
||||
private boolean handleCreatureTransportation = true;
|
||||
private boolean handleNonPlayerVehicles = true;
|
||||
private boolean handleLeashedCreatures = true;
|
||||
private boolean sortNetworkDestinations = false;
|
||||
private boolean protectEntrance = false;
|
||||
private boolean enableBungee = true;
|
||||
@ -76,6 +80,56 @@ public final class StargateGateConfig {
|
||||
return handleVehicles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether vehicles with no passengers should be handled
|
||||
*
|
||||
* <p>The handle vehicles option overrides this option if disabled. This option allows empty passenger
|
||||
* minecarts/boats, but also chest/tnt/hopper/furnace minecarts to teleport through stargates.</p>
|
||||
*
|
||||
* @return <p>Whether vehicles without passengers should be handled</p>
|
||||
*/
|
||||
public boolean handleEmptyVehicles() {
|
||||
return handleEmptyVehicles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether vehicles containing creatures should be handled
|
||||
*
|
||||
* <p>The handle vehicles option overrides this option if disabled. This option allows creatures (pigs, pandas,
|
||||
* zombies, etc.) to teleport through stargates if in a vehicle.</p>
|
||||
*
|
||||
* @return <p>Whether vehicles with creatures should be handled</p>
|
||||
*/
|
||||
public boolean handleCreatureTransportation() {
|
||||
return handleCreatureTransportation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether vehicles containing a creature, but not a player should be handled
|
||||
*
|
||||
* <p>The handle vehicles option, and the handle creature transportation option, override this option if disabled.
|
||||
* This option allows creatures (pigs, pandas, zombies, etc.) to teleport through stargates if in a vehicle, even
|
||||
* if no player is in the vehicle.
|
||||
* As it is not possible to check if a creature is allowed through a stargate, they will be able to go through
|
||||
* regardless of whether the initiating player is allowed to enter the stargate. Enabling this is necessary to
|
||||
* teleport creatures using minecarts, but only handleCreatureTransportation is required to teleport creatures
|
||||
* using a boat manned by a player.</p>
|
||||
*
|
||||
* @return <p>Whether non-empty vehicles without a player should be handled</p>
|
||||
*/
|
||||
public boolean handleNonPlayerVehicles() {
|
||||
return handleNonPlayerVehicles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether leashed creatures should be teleported with a teleporting player
|
||||
*
|
||||
* @return <p>Whether leashed creatures should be handled</p>
|
||||
*/
|
||||
public boolean handleLeashedCreatures() {
|
||||
return handleLeashedCreatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the list of destinations within a network should be sorted
|
||||
*
|
||||
@ -142,6 +196,10 @@ public final class StargateGateConfig {
|
||||
|
||||
//Functionality
|
||||
handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles");
|
||||
handleEmptyVehicles = newConfig.getBoolean("gates.functionality.handleEmptyVehicles");
|
||||
handleCreatureTransportation = newConfig.getBoolean("gates.functionality.handleCreatureTransportation");
|
||||
handleNonPlayerVehicles = newConfig.getBoolean("gates.functionality.handleNonPlayerVehicles");
|
||||
handleLeashedCreatures = newConfig.getBoolean("gates.functionality.handleLeashedCreatures");
|
||||
enableBungee = newConfig.getBoolean("gates.functionality.enableBungee");
|
||||
|
||||
//Integrity
|
||||
@ -173,5 +231,4 @@ public final class StargateGateConfig {
|
||||
Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE");
|
||||
PortalSignDrawer.setColors(ChatColor.BLACK, ChatColor.WHITE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.stargate.listener;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockChangeRequest;
|
||||
import net.knarcraft.stargate.event.StargateDestroyEvent;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalCreator;
|
||||
@ -9,6 +10,7 @@ import net.knarcraft.stargate.portal.PortalRegistry;
|
||||
import net.knarcraft.stargate.utility.EconomyHelper;
|
||||
import net.knarcraft.stargate.utility.MaterialHelper;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import net.knarcraft.stargate.utility.PortalFileHelper;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
@ -81,6 +83,13 @@ public class BlockEventListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove the sign if the no sign option is enabled
|
||||
if (portal.getOptions().hasNoSign()) {
|
||||
Material replaceMaterial = PortalFileHelper.decideRemovalMaterial(portal.getSignLocation(), portal);
|
||||
BlockChangeRequest request = new BlockChangeRequest(portal.getSignLocation(), replaceMaterial, null);
|
||||
Stargate.addBlockChangeRequest(request);
|
||||
}
|
||||
|
||||
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("createMsg"));
|
||||
Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName());
|
||||
Stargate.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(),
|
||||
|
@ -1,15 +1,18 @@
|
||||
package net.knarcraft.stargate.listener;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.config.MessageSender;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.portal.PlayerTeleporter;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalActivator;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.VehicleTeleporter;
|
||||
import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter;
|
||||
import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter;
|
||||
import net.knarcraft.stargate.utility.BungeeHelper;
|
||||
import net.knarcraft.stargate.utility.MaterialHelper;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import net.knarcraft.stargate.utility.UUIDMigrationHelper;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
@ -42,6 +45,9 @@ public class PlayerEventListener implements Listener {
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
//Migrate player name to UUID if necessary
|
||||
UUIDMigrationHelper.migrateUUID(event.getPlayer());
|
||||
|
||||
if (!Stargate.getGateConfig().enableBungee()) {
|
||||
return;
|
||||
}
|
||||
@ -86,7 +92,8 @@ public class PlayerEventListener implements Listener {
|
||||
|
||||
Entity playerVehicle = player.getVehicle();
|
||||
//If the player is in a vehicle, but vehicle handling is disabled, just ignore the player
|
||||
if (playerVehicle == null || Stargate.getGateConfig().handleVehicles()) {
|
||||
if (playerVehicle == null || (playerVehicle instanceof LivingEntity &&
|
||||
Stargate.getGateConfig().handleVehicles())) {
|
||||
teleportPlayer(playerVehicle, player, entrancePortal, destination, event);
|
||||
}
|
||||
}
|
||||
@ -114,7 +121,9 @@ public class PlayerEventListener implements Listener {
|
||||
//Just teleport the player like normal
|
||||
new PlayerTeleporter(destination, player).teleport(entrancePortal, event);
|
||||
}
|
||||
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
|
||||
}
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
}
|
||||
|
||||
@ -154,7 +163,7 @@ public class PlayerEventListener implements Listener {
|
||||
|
||||
//Decide if the user should be teleported to another bungee server
|
||||
if (entrancePortal.getOptions().isBungee()) {
|
||||
if (bungeeTeleport(player, entrancePortal, event)) {
|
||||
if (BungeeHelper.bungeeTeleport(player, entrancePortal, event) && !entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
|
||||
}
|
||||
return false;
|
||||
@ -236,7 +245,9 @@ public class PlayerEventListener implements Listener {
|
||||
boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getNetwork());
|
||||
|
||||
if (PermissionHelper.portalAccessDenied(player, portal, deny)) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!portal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -255,11 +266,12 @@ public class PlayerEventListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Prevent a double click caused by a Spigot bug
|
||||
if (clickIsBug(event, block)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MaterialHelper.isButtonCompatible(block.getType())) {
|
||||
//Prevent a double click caused by a Spigot bug
|
||||
if (clickIsBug(event, block)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Portal portal = PortalHandler.getByBlock(block);
|
||||
if (portal == null) {
|
||||
@ -276,69 +288,68 @@ public class PlayerEventListener implements Listener {
|
||||
}
|
||||
|
||||
PermissionHelper.openPortal(player, portal);
|
||||
if (portal.getPortalOpener().isOpenFor(player)) {
|
||||
if (portal.getPortalOpener().isOpenFor(player) && !MaterialHelper.isContainer(block.getType())) {
|
||||
event.setUseInteractedBlock(Event.Result.ALLOW);
|
||||
}
|
||||
} else {
|
||||
//Display information about the portal if it has no sign
|
||||
displayPortalInfo(block, player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays information about a clicked portal
|
||||
*
|
||||
* <p>This will only display portal info if the portal has no sign and is not silent.</p>
|
||||
*
|
||||
* @param block <p>The clicked block</p>
|
||||
* @param player <p>The player that clicked the block</p>
|
||||
*/
|
||||
private void displayPortalInfo(Block block, Player player) {
|
||||
Portal portal = PortalHandler.getByBlock(block);
|
||||
if (portal == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Display portal information as a portal without a sign does not display any
|
||||
if (portal.getOptions().hasNoSign() && !portal.getOptions().isSilent()) {
|
||||
MessageSender sender = Stargate.getMessageSender();
|
||||
sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString("portalInfoTitle"));
|
||||
sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoName"),
|
||||
"%name%", portal.getName()));
|
||||
sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoDestination"),
|
||||
"%destination%", portal.getDestinationName()));
|
||||
if (portal.getOptions().isBungee()) {
|
||||
sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoServer"),
|
||||
"%server%", portal.getNetwork()));
|
||||
} else {
|
||||
sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoNetwork"),
|
||||
"%network%", portal.getNetwork()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function decides if a right click of a coral is caused by a Spigot bug
|
||||
* This function decides if a right click of a block is caused by a Spigot bug
|
||||
*
|
||||
* <p>The Spigot bug currently makes every right click of a coral trigger twice, causing the portal to close
|
||||
* immediately. This fix should detect the bug without breaking wall coral buttons once the bug is fixed.</p>
|
||||
* <p>The Spigot bug currently makes every right click of some blocks trigger twice, causing the portal to close
|
||||
* immediately, or causing portal information printing twice. This fix should detect the bug without breaking
|
||||
* clicking once the bug is fixed.</p>
|
||||
*
|
||||
* @param event <p>The event causing the right click</p>
|
||||
* @param block <p>The block to check</p>
|
||||
* @return <p>True if the click is a bug and should be cancelled</p>
|
||||
*/
|
||||
private boolean clickIsBug(PlayerInteractEvent event, Block block) {
|
||||
if (MaterialHelper.isWallCoral(block.getType())) {
|
||||
if (previousEvent != null &&
|
||||
event.getPlayer() == previousEvent.getPlayer() && eventTime + 15 > System.currentTimeMillis()) {
|
||||
previousEvent = null;
|
||||
eventTime = 0;
|
||||
return true;
|
||||
}
|
||||
previousEvent = event;
|
||||
eventTime = System.currentTimeMillis();
|
||||
if (previousEvent != null &&
|
||||
event.getPlayer() == previousEvent.getPlayer() && eventTime + 15 > System.currentTimeMillis()) {
|
||||
previousEvent = null;
|
||||
eventTime = 0;
|
||||
return true;
|
||||
}
|
||||
previousEvent = event;
|
||||
eventTime = System.currentTimeMillis();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.getGateConfig().enableBungee()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled"));
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Teleport the player back to this gate, for sanity's sake
|
||||
new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event);
|
||||
|
||||
//Send the SGBungee packet first, it will be queued by BC if required
|
||||
if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) {
|
||||
Stargate.debug("bungeeTeleport", "Unable to send teleportation message");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Send the connect-message to make the player change server
|
||||
if (!BungeeHelper.changeServer(player, entrancePortal)) {
|
||||
Stargate.debug("bungeeTeleport", "Unable to change server");
|
||||
return false;
|
||||
}
|
||||
|
||||
Stargate.debug("bungeeTeleport", "Teleported player to another server");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package net.knarcraft.stargate.listener;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.FromTheEndTeleportation;
|
||||
import net.knarcraft.stargate.portal.PlayerTeleporter;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -3,7 +3,7 @@ package net.knarcraft.stargate.listener;
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.VehicleTeleporter;
|
||||
import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter;
|
||||
import net.knarcraft.stargate.utility.EconomyHelper;
|
||||
import net.knarcraft.stargate.utility.EntityHelper;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
@ -89,7 +89,9 @@ public class VehicleEventListener implements Listener {
|
||||
//On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open
|
||||
// to one player at a time, we only need to check if the portal is open to the driver.
|
||||
if (!entrancePortal.getPortalOpener().isOpenFor(player)) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -115,9 +117,14 @@ public class VehicleEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
|
||||
new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal);
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
//Teleport the vehicle and inform the user if the vehicle was teleported
|
||||
boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal);
|
||||
if (teleported) {
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
|
||||
}
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,14 +156,20 @@ public class VehicleEventListener implements Listener {
|
||||
private static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) {
|
||||
//Make sure the user can access the portal
|
||||
if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Transfer payment if necessary
|
||||
//Check if the player is able to afford the teleport fee
|
||||
int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal);
|
||||
return cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost);
|
||||
boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost);
|
||||
if (!canAffordFee && !entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds"));
|
||||
}
|
||||
return canAffordFee;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,12 @@ package net.knarcraft.stargate.portal;
|
||||
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.portal.property.PortalLocation;
|
||||
import net.knarcraft.stargate.portal.property.PortalOption;
|
||||
import net.knarcraft.stargate.portal.property.PortalOptions;
|
||||
import net.knarcraft.stargate.portal.property.PortalOwner;
|
||||
import net.knarcraft.stargate.portal.property.PortalStructure;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -15,6 +21,7 @@ public class Portal {
|
||||
private final String name;
|
||||
private final String network;
|
||||
private final PortalOwner portalOwner;
|
||||
private boolean isRegistered;
|
||||
|
||||
private final PortalOptions options;
|
||||
private final PortalOpener portalOpener;
|
||||
@ -48,6 +55,24 @@ public class Portal {
|
||||
this.portalActivator = portalOpener.getPortalActivator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this portal is registered
|
||||
*
|
||||
* @return <p>True if this portal is registered</p>
|
||||
*/
|
||||
public boolean isRegistered() {
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this portal is registered
|
||||
*
|
||||
* @param isRegistered <p>True if this portal is registered</p>
|
||||
*/
|
||||
public void setRegistered(boolean isRegistered) {
|
||||
this.isRegistered = isRegistered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location data for this portal
|
||||
*
|
||||
|
@ -248,7 +248,9 @@ public class PortalActivator {
|
||||
|
||||
//If no destinations are available, just tell the player and quit
|
||||
if (destinations.size() == 0) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("destEmpty"));
|
||||
if (!portal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("destEmpty"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4,14 +4,18 @@ import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.event.StargateCreateEvent;
|
||||
import net.knarcraft.stargate.portal.property.PortalLocation;
|
||||
import net.knarcraft.stargate.portal.property.PortalOption;
|
||||
import net.knarcraft.stargate.portal.property.PortalOptions;
|
||||
import net.knarcraft.stargate.portal.property.PortalOwner;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
import net.knarcraft.stargate.portal.property.gate.GateHandler;
|
||||
import net.knarcraft.stargate.utility.DirectionHelper;
|
||||
import net.knarcraft.stargate.utility.EconomyHelper;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import net.knarcraft.stargate.utility.PortalFileHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
|
||||
@ -45,16 +49,16 @@ public class PortalCreator {
|
||||
*/
|
||||
public Portal createPortal() {
|
||||
BlockLocation signLocation = new BlockLocation(event.getBlock());
|
||||
Block idParent = signLocation.getParent();
|
||||
Block signControlBlock = signLocation.getParent();
|
||||
|
||||
//Return early if the sign is not placed on a block, or the block is not a control block
|
||||
if (idParent == null || GateHandler.getGatesByControlBlock(idParent).length == 0) {
|
||||
if (signControlBlock == null || GateHandler.getGatesByControlBlock(signControlBlock).length == 0) {
|
||||
Stargate.debug("createPortal", "Control block not registered");
|
||||
return null;
|
||||
}
|
||||
|
||||
//The control block is already part of another portal
|
||||
if (PortalHandler.getByBlock(idParent) != null) {
|
||||
if (PortalHandler.getByBlock(signControlBlock) != null) {
|
||||
Stargate.debug("createPortal", "idParent belongs to existing stargate");
|
||||
return null;
|
||||
}
|
||||
@ -69,7 +73,8 @@ public class PortalCreator {
|
||||
Map<PortalOption, Boolean> portalOptions = PortalHandler.getPortalOptions(player, destinationName, options);
|
||||
|
||||
//Get the yaw
|
||||
float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), signLocation.getLocation());
|
||||
float yaw = DirectionHelper.getYawFromLocationDifference(signControlBlock.getLocation(),
|
||||
signLocation.getLocation());
|
||||
|
||||
//Get the direction the button should be facing
|
||||
BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw);
|
||||
@ -80,7 +85,7 @@ public class PortalCreator {
|
||||
Stargate.debug("createPortal", "Finished getting all portal info");
|
||||
|
||||
//Try and find a gate matching the new portal
|
||||
Gate gate = PortalHandler.findMatchingGate(portalLocation, player);
|
||||
Gate gate = PortalHandler.findMatchingGate(portalLocation, player.getWorld());
|
||||
if ((gate == null) || (portalLocation.getButtonVector() == null)) {
|
||||
Stargate.debug("createPortal", "Could not find matching gate layout");
|
||||
return null;
|
||||
@ -196,9 +201,8 @@ public class PortalCreator {
|
||||
}
|
||||
|
||||
//Add button if the portal is not always on
|
||||
if (!portalOptions.isAlwaysOn() && !portalOptions.isBungee()) {
|
||||
generatePortalButton(portalLocation.getTopLeft(), portalLocation.getButtonVector(),
|
||||
portalLocation.getButtonFacing());
|
||||
if (!portalOptions.isAlwaysOn()) {
|
||||
PortalFileHelper.generatePortalButton(portal, portalLocation.getButtonFacing());
|
||||
}
|
||||
|
||||
//Register the new portal
|
||||
@ -267,25 +271,6 @@ public class PortalCreator {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a button for a portal
|
||||
*
|
||||
* @param topLeft <p>The top-left block of the portal</p>
|
||||
* @param buttonVector <p>A relative vector pointing at the button</p>
|
||||
* @param buttonFacing <p>The direction the button should be facing</p>
|
||||
*/
|
||||
private void generatePortalButton(BlockLocation topLeft, RelativeBlockVector buttonVector,
|
||||
BlockFace buttonFacing) {
|
||||
//Go one block outwards to find the button's location rather than the control block's location
|
||||
BlockLocation button = topLeft.getRelativeLocation(buttonVector.addToVector(
|
||||
RelativeBlockVector.Property.OUT, 1), portal.getYaw());
|
||||
|
||||
Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton());
|
||||
buttonData.setFacing(buttonFacing);
|
||||
button.getBlock().setBlockData(buttonData);
|
||||
portal.getStructure().setButton(button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the open state of the newly created portal
|
||||
*
|
||||
|
@ -3,8 +3,14 @@ package net.knarcraft.stargate.portal;
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.portal.property.PortalLocation;
|
||||
import net.knarcraft.stargate.portal.property.PortalOption;
|
||||
import net.knarcraft.stargate.portal.property.PortalStructure;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
import net.knarcraft.stargate.portal.property.gate.GateHandler;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -137,12 +143,12 @@ public class PortalHandler {
|
||||
* Tries to find a gate matching the portal the user is trying to create
|
||||
*
|
||||
* @param portalLocation <p>The location data for the new portal</p>
|
||||
* @param player <p>The player trying to create the new portal</p>
|
||||
* @param world <p>The world the player is located in</p>
|
||||
* @return <p>The matching gate type, or null if no such gate could be found</p>
|
||||
*/
|
||||
static Gate findMatchingGate(PortalLocation portalLocation, Player player) {
|
||||
static Gate findMatchingGate(PortalLocation portalLocation, World world) {
|
||||
Block signParent = portalLocation.getSignLocation().getParent();
|
||||
BlockLocation parent = new BlockLocation(player.getWorld(), signParent.getX(), signParent.getY(),
|
||||
BlockLocation parent = new BlockLocation(world, signParent.getX(), signParent.getY(),
|
||||
signParent.getZ());
|
||||
|
||||
//Get all gates with the used type of control blocks
|
||||
|
@ -5,6 +5,7 @@ import net.knarcraft.stargate.container.BlockChangeRequest;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.event.StargateCloseEvent;
|
||||
import net.knarcraft.stargate.event.StargateOpenEvent;
|
||||
import net.knarcraft.stargate.portal.property.PortalOptions;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.Orientable;
|
||||
|
@ -4,8 +4,6 @@ import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.utility.PortalFileHelper;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -37,6 +35,7 @@ public class PortalRegistry {
|
||||
lookupControls.clear();
|
||||
allPortals.clear();
|
||||
allPortalNetworks.clear();
|
||||
bungeePortals.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,6 +162,7 @@ public class PortalRegistry {
|
||||
*/
|
||||
public static void unregisterPortal(Portal portal, boolean removeAll) {
|
||||
Stargate.debug("Unregister", "Unregistering gate " + portal.getName());
|
||||
portal.getPortalActivator().deactivate();
|
||||
portal.getPortalOpener().closePortal(true);
|
||||
|
||||
String portalName = portal.getName().toLowerCase();
|
||||
@ -219,17 +219,11 @@ public class PortalRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
//Clear sign data
|
||||
if (portal.getSignLocation().getBlock().getBlockData() instanceof WallSign) {
|
||||
Sign sign = (Sign) portal.getSignLocation().getBlock().getState();
|
||||
sign.setLine(0, portal.getName());
|
||||
sign.setLine(1, "");
|
||||
sign.setLine(2, "");
|
||||
sign.setLine(3, "");
|
||||
sign.update();
|
||||
}
|
||||
//Mark the portal's sign as unregistered
|
||||
new PortalSignDrawer(portal).drawUnregisteredSign();
|
||||
|
||||
PortalFileHelper.saveAllPortals(portal.getWorld());
|
||||
portal.setRegistered(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,14 +244,14 @@ public class PortalRegistry {
|
||||
} else {
|
||||
//Check if network exists in the lookup list. If not, register the new network
|
||||
if (!portalLookupByNetwork.containsKey(networkName)) {
|
||||
Stargate.debug("register", "Network " + portal.getNetwork() +
|
||||
" not in lookupNamesNet, adding");
|
||||
Stargate.debug("register", String.format("Network %s not in lookupNamesNet, adding",
|
||||
portal.getNetwork()));
|
||||
portalLookupByNetwork.put(networkName, new HashMap<>());
|
||||
}
|
||||
//Check if this network exists in the network list. If not, register the network
|
||||
if (!allPortalNetworks.containsKey(networkName)) {
|
||||
Stargate.debug("register", "Network " + portal.getNetwork() +
|
||||
" not in allPortalsNet, adding");
|
||||
Stargate.debug("register", String.format("Network %s not in allPortalsNet, adding",
|
||||
portal.getNetwork()));
|
||||
allPortalNetworks.put(networkName, new ArrayList<>());
|
||||
}
|
||||
|
||||
@ -292,6 +286,7 @@ public class PortalRegistry {
|
||||
}
|
||||
|
||||
allPortals.add(portal);
|
||||
portal.setRegistered(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.portal.property.PortalLocation;
|
||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.block.Block;
|
||||
@ -45,18 +46,33 @@ public class PortalSignDrawer {
|
||||
* Draws the sign of the portal this sign drawer is responsible for
|
||||
*/
|
||||
public void drawSign() {
|
||||
Block signBlock = portal.getSignLocation().getBlock();
|
||||
BlockState state = signBlock.getState();
|
||||
if (!(state instanceof Sign sign)) {
|
||||
Stargate.logWarning("Sign block is not a Sign object");
|
||||
Stargate.debug("Portal::drawSign", String.format("Block: %s @ %s", signBlock.getType(),
|
||||
signBlock.getLocation()));
|
||||
Sign sign = getSign();
|
||||
if (sign == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
drawSign(sign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sign for this sign drawer's portal
|
||||
*
|
||||
* @return <p>The sign of this sign drawer's portal</p>
|
||||
*/
|
||||
private Sign getSign() {
|
||||
Block signBlock = portal.getSignLocation().getBlock();
|
||||
BlockState state = signBlock.getState();
|
||||
if (!(state instanceof Sign sign)) {
|
||||
if (!portal.getOptions().hasNoSign()) {
|
||||
Stargate.logWarning("Sign block is not a Sign object");
|
||||
Stargate.debug("Portal::drawSign", String.format("Block: %s @ %s", signBlock.getType(),
|
||||
signBlock.getLocation()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the sign of the portal this sign drawer is responsible for
|
||||
*
|
||||
@ -64,9 +80,7 @@ public class PortalSignDrawer {
|
||||
*/
|
||||
private void drawSign(Sign sign) {
|
||||
//Clear sign
|
||||
for (int index = 0; index <= 3; index++) {
|
||||
sign.setLine(index, "");
|
||||
}
|
||||
clearSign(sign);
|
||||
setLine(sign, 0, highlightColor + "-" + mainColor +
|
||||
portal.getName() + highlightColor + "-");
|
||||
|
||||
@ -89,6 +103,30 @@ public class PortalSignDrawer {
|
||||
sign.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all lines of a sign, but does not update the sign
|
||||
*
|
||||
* @param sign <p>The sign to clear</p>
|
||||
*/
|
||||
private void clearSign(Sign sign) {
|
||||
for (int index = 0; index <= 3; index++) {
|
||||
sign.setLine(index, "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this sign drawer's portal as unregistered
|
||||
*/
|
||||
public void drawUnregisteredSign() {
|
||||
Sign sign = getSign();
|
||||
if (sign == null) {
|
||||
return;
|
||||
}
|
||||
clearSign(sign);
|
||||
sign.setLine(0, portal.getName());
|
||||
sign.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a sign with choose-able network locations
|
||||
*
|
||||
@ -174,7 +212,7 @@ public class PortalSignDrawer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a bungee sign
|
||||
* Draws the sign of a BungeeCord portal
|
||||
*
|
||||
* @param sign <p>The sign to re-draw</p>
|
||||
*/
|
||||
@ -185,7 +223,9 @@ public class PortalSignDrawer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an inactive sign
|
||||
* Draws the sign of an in-active portal
|
||||
*
|
||||
* <p>The sign for an in-active portal should display the right-click prompt and the network.</p>
|
||||
*
|
||||
* @param sign <p>The sign to re-draw</p>
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property;
|
||||
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property;
|
||||
|
||||
/**
|
||||
* Each enum value represents one option a portal can have/use
|
||||
@ -48,7 +48,17 @@ public enum PortalOption {
|
||||
/**
|
||||
* This option allows a portal to teleport to another server connected through BungeeCord
|
||||
*/
|
||||
BUNGEE('u', "stargate.admin.bungee", 20);
|
||||
BUNGEE('u', "stargate.admin.bungee", 20),
|
||||
|
||||
/**
|
||||
* This option allows a portal which does not display a teleportation message, for better immersion
|
||||
*/
|
||||
SILENT('i', "stargate.option.silent", 21),
|
||||
|
||||
/**
|
||||
* This option causes a fixed portal's sign to be removed after creation
|
||||
*/
|
||||
NO_SIGN('e', "stargate.option.nosign", 22);
|
||||
|
||||
private final char characterRepresentation;
|
||||
private final String permissionString;
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
|
||||
@ -25,12 +25,17 @@ public class PortalOptions {
|
||||
|
||||
if (this.isAlwaysOn() && !isFixed) {
|
||||
this.options.put(PortalOption.ALWAYS_ON, false);
|
||||
Stargate.debug("Portal", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false");
|
||||
Stargate.debug("PortalOptions", "Can not create a non-fixed always-on gate. Setting AlwaysOn = false");
|
||||
}
|
||||
|
||||
if (this.isRandom() && !this.isAlwaysOn()) {
|
||||
if ((this.isRandom() || this.isBungee()) && !this.isAlwaysOn()) {
|
||||
this.options.put(PortalOption.ALWAYS_ON, true);
|
||||
Stargate.debug("Portal", "Gate marked as random, set to always-on");
|
||||
Stargate.debug("PortalOptions", "Gate marked as random or bungee, set to always-on");
|
||||
}
|
||||
|
||||
if (this.hasNoSign() && !this.isFixed) {
|
||||
this.options.put(PortalOption.NO_SIGN, false);
|
||||
Stargate.debug("PortalOptions", "Gate marked with no sign, but not fixed. Setting NoSign = false");
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,4 +170,27 @@ public class PortalOptions {
|
||||
return this.options.get(PortalOption.BUNGEE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this portal is silent
|
||||
*
|
||||
* <p>A silent portal does not output anything to the chat when teleporting. This option is mainly useful to keep
|
||||
* the immersion during teleportation (for role-playing servers or similar).</p>
|
||||
*
|
||||
* @return <p>Whether this portal is silent</p>
|
||||
*/
|
||||
public boolean isSilent() {
|
||||
return this.options.get(PortalOption.SILENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this portal has no sign
|
||||
*
|
||||
* <p>An always-on portal is allowed to not have a sign as it will never be interacted with anyway.</p>
|
||||
*
|
||||
* @return <p>Whether this portal has no sign</p>
|
||||
*/
|
||||
public boolean hasNoSign() {
|
||||
return this.options.get(PortalOption.NO_SIGN);
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -43,6 +43,22 @@ public class PortalOwner {
|
||||
return ownerUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unique id for a portal owner without one
|
||||
*
|
||||
* <p>This method is only meant to be used to set the unique id for an owner without one. If the owner already has
|
||||
* an unique id, an exception will be thrown.</p>
|
||||
*
|
||||
* @param uniqueId <p>The new unique id for the portal owner</p>
|
||||
*/
|
||||
public void setUUID(UUID uniqueId) {
|
||||
if (ownerUUID == null) {
|
||||
ownerUUID = uniqueId;
|
||||
} else {
|
||||
throw new IllegalArgumentException("An existing UUID cannot be overwritten.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this owner
|
||||
*
|
@ -1,8 +1,10 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
|
||||
/**
|
||||
* The portal structure is responsible for the physical properties of a portal
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property.gate;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property.gate;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.utility.GateReader;
|
||||
@ -243,6 +243,7 @@ public class GateHandler {
|
||||
loadGateFromJar("nethergate.gate", gateFolder);
|
||||
loadGateFromJar("watergate.gate", gateFolder);
|
||||
loadGateFromJar("endgate.gate", gateFolder);
|
||||
loadGateFromJar("squarenetherglowstonegate.gate", gateFolder);
|
||||
}
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.property.gate;
|
||||
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
|
@ -0,0 +1,72 @@
|
||||
package net.knarcraft.stargate.portal.teleporter;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.event.StargateEntityPortalEvent;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
/**
|
||||
* The portal teleporter takes care of the actual portal teleportation for any entities
|
||||
*/
|
||||
public class EntityTeleporter extends Teleporter {
|
||||
|
||||
private final Entity teleportingEntity;
|
||||
|
||||
/**
|
||||
* Instantiates a new portal teleporter
|
||||
*
|
||||
* @param portal <p>The portal which is the target of the teleportation</p>
|
||||
*/
|
||||
public EntityTeleporter(Portal portal, Entity teleportingEntity) {
|
||||
super(portal);
|
||||
this.teleportingEntity = teleportingEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports an entity to this teleporter's portal
|
||||
*
|
||||
* @param origin <p>The portal the entity is teleporting from</p>
|
||||
* @return <p>True if the entity was teleported. False otherwise</p>
|
||||
*/
|
||||
public boolean teleport(Portal origin) {
|
||||
Location traveller = teleportingEntity.getLocation();
|
||||
Location exit = getExit(teleportingEntity, traveller);
|
||||
|
||||
//Rotate the entity to face out from the portal
|
||||
adjustRotation(exit);
|
||||
|
||||
//Call the StargateEntityPortalEvent to allow plugins to change destination
|
||||
if (!origin.equals(portal)) {
|
||||
exit = triggerEntityPortalEvent(origin, exit);
|
||||
if (exit == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Load chunks to make sure not to teleport to the void
|
||||
loadChunks();
|
||||
|
||||
teleportingEntity.teleport(exit);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the entity portal event to allow plugins to change the exit location
|
||||
*
|
||||
* @param origin <p>The origin portal teleported from</p>
|
||||
* @param exit <p>The exit location to teleport the entity to</p>
|
||||
* @return <p>The location the entity should be teleported to, or null if the event was cancelled</p>
|
||||
*/
|
||||
protected Location triggerEntityPortalEvent(Portal origin, Location exit) {
|
||||
StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingEntity, origin,
|
||||
portal, exit);
|
||||
Stargate.getInstance().getServer().getPluginManager().callEvent(stargateEntityPortalEvent);
|
||||
//Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake
|
||||
if (stargateEntityPortalEvent.isCancelled()) {
|
||||
new EntityTeleporter(origin, teleportingEntity).teleport(origin);
|
||||
return null;
|
||||
}
|
||||
return stargateEntityPortalEvent.getExit();
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.teleporter;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.event.StargatePlayerPortalEvent;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
@ -48,6 +49,9 @@ public class PlayerTeleporter extends Teleporter {
|
||||
//Load chunks to make sure not to teleport to the void
|
||||
loadChunks();
|
||||
|
||||
//Teleport any creatures leashed by the player in a 15-block range
|
||||
teleportLeashedCreatures(player, origin);
|
||||
|
||||
//If no event is passed in, assume it's a teleport, and act as such
|
||||
if (event == null) {
|
||||
player.teleport(exit);
|
@ -1,9 +1,10 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.teleporter;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.ChunkUnloadRequest;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.utility.DirectionHelper;
|
||||
import net.knarcraft.stargate.utility.EntityHelper;
|
||||
import org.bukkit.Chunk;
|
||||
@ -13,7 +14,9 @@ import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Slab;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -247,4 +250,47 @@ public abstract class Teleporter {
|
||||
return chunksToLoad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports any creatures leashed by the player
|
||||
*
|
||||
* @param player <p>The player which is teleported</p>
|
||||
* @param origin <p>The portal the player is teleporting from</p>
|
||||
*/
|
||||
protected void teleportLeashedCreatures(Player player, Portal origin) {
|
||||
//If this feature is disabled, just return
|
||||
if (!Stargate.getGateConfig().handleLeashedCreatures()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Find any nearby leashed entities to teleport with the player
|
||||
List<Creature> nearbyEntities = getLeashedCreatures(player);
|
||||
//Teleport all creatures leashed by the player to the portal the player is to exit from
|
||||
for (Creature creature : nearbyEntities) {
|
||||
creature.setLeashHolder(null);
|
||||
scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> {
|
||||
new EntityTeleporter(portal, creature).teleport(origin);
|
||||
scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> creature.setLeashHolder(player), 6);
|
||||
}, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all creatures leashed by a player within the given range
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @return <p>A list of all creatures the player is holding in a leash (lead)</p>
|
||||
*/
|
||||
protected List<Creature> getLeashedCreatures(Player player) {
|
||||
List<Creature> leashedCreatures = new ArrayList<>();
|
||||
//Find any nearby leashed entities to teleport with the player
|
||||
List<Entity> nearbyEntities = player.getNearbyEntities(15, 15, 15);
|
||||
//Teleport all creatures leashed by the player to the portal the player is to exit from
|
||||
for (Entity entity : nearbyEntities) {
|
||||
if (entity instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder() == player) {
|
||||
leashedCreatures.add(creature);
|
||||
}
|
||||
}
|
||||
return leashedCreatures;
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
package net.knarcraft.stargate.portal.teleporter;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.event.StargateEntityPortalEvent;
|
||||
import net.knarcraft.stargate.config.StargateGateConfig;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.utility.DirectionHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@ -15,7 +17,7 @@ import java.util.List;
|
||||
/**
|
||||
* The portal teleporter takes care of the actual portal teleportation for any vehicles
|
||||
*/
|
||||
public class VehicleTeleporter extends Teleporter {
|
||||
public class VehicleTeleporter extends EntityTeleporter {
|
||||
|
||||
private final Vehicle teleportingVehicle;
|
||||
|
||||
@ -26,7 +28,7 @@ public class VehicleTeleporter extends Teleporter {
|
||||
* @param teleportingVehicle <p>The teleporting vehicle</p>
|
||||
*/
|
||||
public VehicleTeleporter(Portal portal, Vehicle teleportingVehicle) {
|
||||
super(portal);
|
||||
super(portal, teleportingVehicle);
|
||||
this.teleportingVehicle = teleportingVehicle;
|
||||
}
|
||||
|
||||
@ -36,9 +38,11 @@ public class VehicleTeleporter extends Teleporter {
|
||||
* <p>It is assumed that if a vehicle contains any players, their permissions have already been validated before
|
||||
* calling this method.</p>
|
||||
*
|
||||
* @param origin <p>The portal the vehicle teleports from</p>
|
||||
* @param origin <p>The portal the vehicle is teleporting from</p>
|
||||
* @return <p>True if the vehicle was teleported. False otherwise</p>
|
||||
*/
|
||||
public void teleport(Portal origin) {
|
||||
@Override
|
||||
public boolean teleport(Portal origin) {
|
||||
Location traveller = teleportingVehicle.getLocation();
|
||||
Location exit = getExit(teleportingVehicle, traveller);
|
||||
|
||||
@ -58,12 +62,12 @@ public class VehicleTeleporter extends Teleporter {
|
||||
if (!origin.equals(portal)) {
|
||||
exit = triggerEntityPortalEvent(origin, exit);
|
||||
if (exit == null) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Teleport the vehicle
|
||||
teleportVehicle(exit, newVelocity);
|
||||
return teleportVehicle(exit, newVelocity, origin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,45 +75,84 @@ public class VehicleTeleporter extends Teleporter {
|
||||
*
|
||||
* @param exit <p>The location the vehicle should be teleported to</p>
|
||||
* @param newVelocity <p>The velocity to give the vehicle right after teleportation</p>
|
||||
* @param origin <p>The portal the vehicle teleported from</p>
|
||||
* @return <p>True if the vehicle was teleported. False otherwise</p>
|
||||
*/
|
||||
private void teleportVehicle(Location exit, Vector newVelocity) {
|
||||
private boolean teleportVehicle(Location exit, Vector newVelocity, Portal origin) {
|
||||
//Load chunks to make sure not to teleport to the void
|
||||
loadChunks();
|
||||
|
||||
List<Entity> passengers = teleportingVehicle.getPassengers();
|
||||
if (!passengers.isEmpty()) {
|
||||
//Check if the passengers are allowed according to current config settings
|
||||
if (!vehiclePassengersAllowed(passengers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(teleportingVehicle instanceof LivingEntity)) {
|
||||
//Teleport a normal vehicle with passengers (minecart or boat)
|
||||
putPassengersInNewVehicle(passengers, exit, newVelocity);
|
||||
putPassengersInNewVehicle(passengers, exit, newVelocity, origin);
|
||||
} else {
|
||||
//Teleport a living vehicle with passengers (pig, horse, donkey, strider)
|
||||
teleportLivingVehicle(exit, passengers);
|
||||
teleportLivingVehicle(exit, passengers, origin);
|
||||
}
|
||||
} else {
|
||||
//Check if teleportation of empty vehicles is enabled
|
||||
if (!Stargate.getGateConfig().handleEmptyVehicles()) {
|
||||
return false;
|
||||
}
|
||||
//Teleport an empty vehicle
|
||||
teleportingVehicle.teleport(exit);
|
||||
scheduler.scheduleSyncDelayedTask(Stargate.getInstance(),
|
||||
() -> teleportingVehicle.setVelocity(newVelocity), 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the entity portal event to allow plugins to change the exit location
|
||||
* Checks whether current config values allow the teleportation of the given passengers
|
||||
*
|
||||
* @param origin <p>The origin portal teleported from</p>
|
||||
* @param exit <p>The exit location to teleport the vehicle to</p>
|
||||
* @return <p>The location the vehicle should be teleported to, or null if the event was cancelled</p>
|
||||
* @param passengers <p>The passengers to teleport</p>
|
||||
* @return <p>True if the passengers are allowed to teleport</p>
|
||||
*/
|
||||
private Location triggerEntityPortalEvent(Portal origin, Location exit) {
|
||||
StargateEntityPortalEvent stargateEntityPortalEvent = new StargateEntityPortalEvent(teleportingVehicle, origin,
|
||||
portal, exit);
|
||||
Stargate.getInstance().getServer().getPluginManager().callEvent(stargateEntityPortalEvent);
|
||||
//Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake
|
||||
if (stargateEntityPortalEvent.isCancelled()) {
|
||||
new VehicleTeleporter(origin, teleportingVehicle).teleport(origin);
|
||||
return null;
|
||||
private boolean vehiclePassengersAllowed(List<Entity> passengers) {
|
||||
StargateGateConfig config = Stargate.getGateConfig();
|
||||
//Don't teleport if the vehicle contains a creature and creature transportation is disabled
|
||||
if (containsNonPlayer(passengers) && !config.handleCreatureTransportation()) {
|
||||
return false;
|
||||
}
|
||||
return stargateEntityPortalEvent.getExit();
|
||||
//Don't teleport if the player does not contain a player and non-player vehicles is disabled
|
||||
return containsPlayer(passengers) || config.handleNonPlayerVehicles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a list of entities contains any non-players
|
||||
*
|
||||
* @param entities <p>The list of entities to check</p>
|
||||
* @return <p>True if at least one entity is not a player</p>
|
||||
*/
|
||||
private boolean containsNonPlayer(List<Entity> entities) {
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a list of entities contains at least one player
|
||||
*
|
||||
* @param entities <p>The list of entities to check</p>
|
||||
* @return <p>True if at least one player is present among the passengers</p>
|
||||
*/
|
||||
private boolean containsPlayer(List<Entity> entities) {
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof Player) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,11 +160,12 @@ public class VehicleTeleporter extends Teleporter {
|
||||
*
|
||||
* @param exit <p>The location the vehicle will exit</p>
|
||||
* @param passengers <p>The passengers of the vehicle</p>
|
||||
* @param origin <p>The portal the vehicle teleported from</p>
|
||||
*/
|
||||
private void teleportLivingVehicle(Location exit, List<Entity> passengers) {
|
||||
private void teleportLivingVehicle(Location exit, List<Entity> passengers, Portal origin) {
|
||||
teleportingVehicle.eject();
|
||||
teleportingVehicle.teleport(exit);
|
||||
handleVehiclePassengers(passengers, teleportingVehicle, 2);
|
||||
handleVehiclePassengers(passengers, teleportingVehicle, 2, origin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,9 +178,10 @@ public class VehicleTeleporter extends Teleporter {
|
||||
* @param passengers <p>A list of all passengers in the vehicle</p>
|
||||
* @param exit <p>The exit location to spawn the new vehicle on</p>
|
||||
* @param newVelocity <p>The new velocity of the new vehicle</p>
|
||||
* @param origin <p>The portal the vehicle teleported from</p>
|
||||
*/
|
||||
private void putPassengersInNewVehicle(List<Entity> passengers, Location exit,
|
||||
Vector newVelocity) {
|
||||
Vector newVelocity, Portal origin) {
|
||||
World vehicleWorld = exit.getWorld();
|
||||
if (vehicleWorld == null) {
|
||||
Stargate.logWarning("Unable to get the world to teleport the vehicle to");
|
||||
@ -149,7 +194,7 @@ public class VehicleTeleporter extends Teleporter {
|
||||
teleportingVehicle.remove();
|
||||
//Set rotation, add passengers and restore velocity
|
||||
newVehicle.setRotation(exit.getYaw(), exit.getPitch());
|
||||
handleVehiclePassengers(passengers, newVehicle, 1);
|
||||
handleVehiclePassengers(passengers, newVehicle, 1, origin);
|
||||
scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> newVehicle.setVelocity(newVelocity), 1);
|
||||
}
|
||||
|
||||
@ -159,12 +204,18 @@ public class VehicleTeleporter extends Teleporter {
|
||||
* @param passengers <p>The passengers to handle</p>
|
||||
* @param vehicle <p>The vehicle the passengers should be put into</p>
|
||||
* @param delay <p>The amount of milliseconds to wait before adding the vehicle passengers</p>
|
||||
* @param origin <p>The portal the vehicle teleported from</p>
|
||||
*/
|
||||
private void handleVehiclePassengers(List<Entity> passengers, Vehicle vehicle, long delay) {
|
||||
private void handleVehiclePassengers(List<Entity> passengers, Vehicle vehicle, long delay, Portal origin) {
|
||||
for (Entity passenger : passengers) {
|
||||
passenger.eject();
|
||||
scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> teleportAndAddPassenger(vehicle, passenger),
|
||||
delay);
|
||||
scheduler.scheduleSyncDelayedTask(Stargate.getInstance(), () -> {
|
||||
if (passenger instanceof Player player) {
|
||||
//Teleport any creatures leashed by the player in a 15-block range
|
||||
teleportLeashedCreatures(player, origin);
|
||||
}
|
||||
teleportAndAddPassenger(vehicle, passenger);
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,7 @@ public class StarGateThread implements Runnable {
|
||||
|
||||
for (Portal portal : openPortalsQueue) {
|
||||
//Skip always open and non-open gates
|
||||
if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee() ||
|
||||
!portal.isOpen()) {
|
||||
if (portal.getOptions().isAlwaysOn() || !portal.isOpen()) {
|
||||
continue;
|
||||
}
|
||||
if (time > portal.getTriggeredTime() + Stargate.getGateConfig().getOpenTime()) {
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.knarcraft.stargate.utility;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.portal.PlayerTeleporter;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -169,4 +170,41 @@ public final class BungeeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*/
|
||||
public static boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) {
|
||||
//Check if bungee is actually enabled
|
||||
if (!Stargate.getGateConfig().enableBungee()) {
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled"));
|
||||
}
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Teleport the player back to this gate, for sanity's sake
|
||||
new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event);
|
||||
|
||||
//Send the SGBungee packet first, it will be queued by BC if required
|
||||
if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) {
|
||||
Stargate.debug("bungeeTeleport", "Unable to send teleportation message");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Send the connect-message to make the player change server
|
||||
if (!BungeeHelper.changeServer(player, entrancePortal)) {
|
||||
Stargate.debug("bungeeTeleport", "Unable to change server");
|
||||
return false;
|
||||
}
|
||||
|
||||
Stargate.debug("bungeeTeleport", "Teleported player to another server");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package net.knarcraft.stargate.utility;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalOwner;
|
||||
import net.knarcraft.stargate.portal.property.PortalOwner;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -28,6 +28,17 @@ public final class MaterialHelper {
|
||||
material.equals(Material.DEAD_TUBE_CORAL_WALL_FAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given material is a container
|
||||
*
|
||||
* @param material <p>The material to check</p>
|
||||
* @return <p>True if the material is a container</p>
|
||||
*/
|
||||
public static boolean isContainer(Material material) {
|
||||
return Tag.SHULKER_BOXES.isTagged(material) || material == Material.CHEST ||
|
||||
material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given material can be used as a button
|
||||
*
|
||||
@ -35,8 +46,7 @@ public final class MaterialHelper {
|
||||
* @return <p>True if the material can be used as a button</p>
|
||||
*/
|
||||
public static boolean isButtonCompatible(Material material) {
|
||||
return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || Tag.SHULKER_BOXES.isTagged(material) ||
|
||||
material == Material.CHEST || material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST;
|
||||
return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || isContainer(material);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package net.knarcraft.stargate.utility;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.event.StargateAccessEvent;
|
||||
import net.knarcraft.stargate.portal.PlayerTeleporter;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalOption;
|
||||
import net.knarcraft.stargate.portal.property.PortalOption;
|
||||
import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
@ -27,13 +27,15 @@ public final class PermissionHelper {
|
||||
Portal destination = portal.getPortalActivator().getDestination();
|
||||
|
||||
//For an always open portal, no action is necessary
|
||||
if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee()) {
|
||||
if (portal.getOptions().isAlwaysOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Destination is invalid or the same portal. Send an error message
|
||||
if (destination == null || destination == portal) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg"));
|
||||
if (!portal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -49,19 +51,25 @@ public final class PermissionHelper {
|
||||
//Deny access if another player has activated the portal, and it's still in use
|
||||
if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() &&
|
||||
portal.getActivePlayer() != player) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!portal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Check if the player can use the private gate
|
||||
if (portal.getOptions().isPrivate() && !PermissionHelper.canUsePrivatePortal(player, portal)) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!portal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Destination is currently in use by another player, blocking teleportation
|
||||
if (destination.isOpen() && !destination.getOptions().isAlwaysOn()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg"));
|
||||
if (!portal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -374,7 +382,9 @@ public final class PermissionHelper {
|
||||
|
||||
//Not open for this player
|
||||
if (!entrancePortal.getPortalOpener().isOpenFor(player)) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event);
|
||||
return true;
|
||||
}
|
||||
@ -386,7 +396,9 @@ public final class PermissionHelper {
|
||||
|
||||
//Player cannot access portal
|
||||
if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
if (!entrancePortal.getOptions().isSilent()) {
|
||||
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||
}
|
||||
new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event);
|
||||
entrancePortal.getPortalOpener().closePortal(false);
|
||||
return true;
|
||||
|
@ -1,16 +1,25 @@
|
||||
package net.knarcraft.stargate.utility;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockChangeRequest;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.portal.Gate;
|
||||
import net.knarcraft.stargate.portal.GateHandler;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.PortalLocation;
|
||||
import net.knarcraft.stargate.portal.PortalOptions;
|
||||
import net.knarcraft.stargate.portal.PortalOwner;
|
||||
import net.knarcraft.stargate.portal.PortalRegistry;
|
||||
import net.knarcraft.stargate.portal.property.PortalLocation;
|
||||
import net.knarcraft.stargate.portal.property.PortalOptions;
|
||||
import net.knarcraft.stargate.portal.property.PortalOwner;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
import net.knarcraft.stargate.portal.property.gate.GateHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
@ -114,7 +123,9 @@ public final class PortalFileHelper {
|
||||
builder.append(options.isShown()).append(':');
|
||||
builder.append(options.isNoNetwork()).append(':');
|
||||
builder.append(options.isRandom()).append(':');
|
||||
builder.append(options.isBungee());
|
||||
builder.append(options.isBungee()).append(':');
|
||||
builder.append(options.isSilent()).append(':');
|
||||
builder.append(options.hasNoSign());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,14 +158,17 @@ public final class PortalFileHelper {
|
||||
int lineIndex = 0;
|
||||
try {
|
||||
Scanner scanner = new Scanner(database);
|
||||
boolean needsToSaveDatabase = false;
|
||||
while (scanner.hasNextLine()) {
|
||||
//Read the line and do whatever needs to be done
|
||||
readPortalLine(scanner, ++lineIndex, world);
|
||||
needsToSaveDatabase = readPortalLine(scanner, ++lineIndex, world) || needsToSaveDatabase;
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
//Do necessary tasks after all portals have loaded
|
||||
doPostLoadTasks(world);
|
||||
Stargate.debug("PortalFileHelper::loadPortals", String.format("Finished loading portals for %s. " +
|
||||
"Starting post loading tasks", world));
|
||||
doPostLoadTasks(world, needsToSaveDatabase);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Stargate.logSevere(String.format("Exception while reading stargates from %s: %d", database.getName(),
|
||||
@ -170,24 +184,25 @@ public final class PortalFileHelper {
|
||||
* @param scanner <p>The scanner to read</p>
|
||||
* @param lineIndex <p>The index of the read line</p>
|
||||
* @param world <p>The world for which portals are currently being read</p>
|
||||
* @return <p>True if the read portal has changed and the world's database needs to be saved</p>
|
||||
*/
|
||||
private static void readPortalLine(Scanner scanner, int lineIndex, World world) {
|
||||
private static boolean readPortalLine(Scanner scanner, int lineIndex, World world) {
|
||||
String line = scanner.nextLine().trim();
|
||||
|
||||
//Ignore empty and comment lines
|
||||
if (line.startsWith("#") || line.isEmpty()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check if the min. required portal data is present
|
||||
String[] portalData = line.split(":");
|
||||
if (portalData.length < 8) {
|
||||
Stargate.logInfo(String.format("Invalid line - %s", lineIndex));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Load the portal defined in the current line
|
||||
loadPortal(portalData, world, lineIndex);
|
||||
return loadPortal(portalData, world, lineIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,9 +211,10 @@ public final class PortalFileHelper {
|
||||
* <p>This will open always on portals, print info about loaded stargates and re-draw portal signs for loaded
|
||||
* portals.</p>
|
||||
*
|
||||
* @param world <p>The world portals have been loaded for</p>
|
||||
* @param world <p>The world portals have been loaded for</p>
|
||||
* @param needsToSaveDatabase <p>Whether the portal database's file needs to be updated</p>
|
||||
*/
|
||||
private static void doPostLoadTasks(World world) {
|
||||
private static void doPostLoadTasks(World world, boolean needsToSaveDatabase) {
|
||||
//Open any always-on portals. Do this here as it should be more efficient than in the loop.
|
||||
PortalHandler.verifyAllPortals();
|
||||
int portalCount = PortalRegistry.getAllPortals().size();
|
||||
@ -210,7 +226,15 @@ public final class PortalFileHelper {
|
||||
|
||||
//Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since
|
||||
for (Portal portal : PortalRegistry.getAllPortals()) {
|
||||
portal.drawSign();
|
||||
if (portal.isRegistered()) {
|
||||
portal.drawSign();
|
||||
updatePortalButton(portal);
|
||||
}
|
||||
}
|
||||
//Save the portals to disk to update with any changes
|
||||
Stargate.debug("PortalFileHelper::doPostLoadTasks", String.format("Saving database for world %s", world));
|
||||
if (needsToSaveDatabase) {
|
||||
saveAllPortals(world);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,8 +244,9 @@ public final class PortalFileHelper {
|
||||
* @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>
|
||||
* @return <p>True if the portal's data has changed and its database needs to be updated</p>
|
||||
*/
|
||||
private static void loadPortal(String[] portalData, World world, int lineIndex) {
|
||||
private static boolean loadPortal(String[] portalData, World world, int lineIndex) {
|
||||
//Load min. required portal data
|
||||
String name = portalData[0];
|
||||
BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null;
|
||||
@ -237,12 +262,13 @@ public final class PortalFileHelper {
|
||||
if (gate == null) {
|
||||
//Mark the sign as invalid to reduce some player confusion
|
||||
markPortalWithInvalidGate(portalLocation, portalData[7], lineIndex);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Load extra portal data
|
||||
String destination = (portalData.length > 8) ? portalData[8] : "";
|
||||
String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : Stargate.getDefaultNetwork();
|
||||
String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] :
|
||||
Stargate.getDefaultNetwork();
|
||||
String ownerString = (portalData.length > 10) ? portalData[10] : "";
|
||||
|
||||
//Get the owner from the owner string
|
||||
@ -253,8 +279,124 @@ public final class PortalFileHelper {
|
||||
PortalHandler.getPortalOptions(portalData));
|
||||
|
||||
//Register the portal, and close it in case it wasn't properly closed when the server stopped
|
||||
boolean buttonLocationChanged = updateButtonVector(portal);
|
||||
PortalHandler.registerPortal(portal);
|
||||
portal.getPortalOpener().closePortal(true);
|
||||
return buttonLocationChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a portal's button if it does not match the correct material
|
||||
*
|
||||
* @param portal <p>The portal update the button of</p>
|
||||
*/
|
||||
private static void updatePortalButton(Portal portal) {
|
||||
BlockLocation buttonLocation = getButtonLocation(portal);
|
||||
BlockData buttonData = buttonLocation.getBlock().getBlockData();
|
||||
if (portal.getOptions().isAlwaysOn()) {
|
||||
//Clear button if not already air or water
|
||||
if (buttonData.getMaterial() != Material.AIR && buttonData.getMaterial() != Material.WATER) {
|
||||
Material newMaterial = decideRemovalMaterial(buttonLocation, portal);
|
||||
Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, newMaterial, null));
|
||||
}
|
||||
} else {
|
||||
//Replace button if the material does not match
|
||||
if (buttonData.getMaterial() != portal.getGate().getPortalButton()) {
|
||||
generatePortalButton(portal, DirectionHelper.getBlockFaceFromYaw(portal.getYaw()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides the material to use for removing a portal's button/sign
|
||||
*
|
||||
* @param location <p>The location of the button/sign to replace</p>
|
||||
* @param portal <p>The portal the button/sign belongs to</p>
|
||||
* @return <p>The material to use for removing the button/sign</p>
|
||||
*/
|
||||
public static Material decideRemovalMaterial(BlockLocation location, Portal portal) {
|
||||
//Get the blocks to each side of the location
|
||||
Location leftLocation = location.getRelativeLocation(-1, 0, 0, portal.getYaw());
|
||||
Location rightLocation = location.getRelativeLocation(1, 0, 0, portal.getYaw());
|
||||
|
||||
//If the block is water or is waterlogged, assume the portal is underwater
|
||||
if (isUnderwater(leftLocation) || isUnderwater(rightLocation)) {
|
||||
return Material.WATER;
|
||||
} else {
|
||||
return Material.AIR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given location is underwater
|
||||
*
|
||||
* <p>If the location has a water block, or a block which is waterlogged, it will be considered underwater.</p>
|
||||
*
|
||||
* @param location <p>The location to check</p>
|
||||
* @return <p>True if the location is underwater</p>
|
||||
*/
|
||||
private static boolean isUnderwater(Location location) {
|
||||
BlockData blockData = location.getBlock().getBlockData();
|
||||
return blockData.getMaterial() == Material.WATER ||
|
||||
(blockData instanceof Waterlogged waterlogged && waterlogged.isWaterlogged());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the button vector for the given portal
|
||||
*
|
||||
* <p>As the button vector isn't saved, it is null when the portal is loaded. This method allows it to be
|
||||
* explicitly set when necessary.</p>
|
||||
*
|
||||
* @param portal <p>The portal to update the button vector for</p>
|
||||
* @return <p>True if the calculated button location is not the same as the one in the portal file</p>
|
||||
*/
|
||||
private static boolean updateButtonVector(Portal portal) {
|
||||
for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) {
|
||||
BlockLocation controlLocation = portal.getLocation().getTopLeft().getRelativeLocation(control,
|
||||
portal.getYaw());
|
||||
BlockLocation buttonLocation = controlLocation.getRelativeLocation(
|
||||
new RelativeBlockVector(0, 0, 1), portal.getYaw());
|
||||
if (!buttonLocation.equals(portal.getLocation().getSignLocation())) {
|
||||
portal.getLocation().setButtonVector(control);
|
||||
|
||||
BlockLocation oldButtonLocation = portal.getStructure().getButton();
|
||||
if (oldButtonLocation != null && !oldButtonLocation.equals(buttonLocation)) {
|
||||
Stargate.addBlockChangeRequest(new BlockChangeRequest(oldButtonLocation, Material.AIR, null));
|
||||
portal.getStructure().setButton(buttonLocation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a button for a portal
|
||||
*
|
||||
* @param portal <p>The portal to generate button for</p>
|
||||
* @param buttonFacing <p>The direction the button should be facing</p>
|
||||
*/
|
||||
public static void generatePortalButton(Portal portal, BlockFace buttonFacing) {
|
||||
//Go one block outwards to find the button's location rather than the control block's location
|
||||
BlockLocation button = getButtonLocation(portal);
|
||||
|
||||
Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton());
|
||||
buttonData.setFacing(buttonFacing);
|
||||
button.getBlock().setBlockData(buttonData);
|
||||
portal.getStructure().setButton(button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of a portal's button
|
||||
*
|
||||
* @param portal <p>The portal to find the button for</p>
|
||||
* @return <p>The location of the portal's button</p>
|
||||
*/
|
||||
private static BlockLocation getButtonLocation(Portal portal) {
|
||||
BlockLocation topLeft = portal.getTopLeft();
|
||||
RelativeBlockVector buttonVector = portal.getLocation().getButtonVector();
|
||||
return topLeft.getRelativeLocation(buttonVector.addToVector(RelativeBlockVector.Property.OUT, 1),
|
||||
portal.getYaw());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,111 @@
|
||||
package net.knarcraft.stargate.utility;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.portal.PortalRegistry;
|
||||
import net.knarcraft.stargate.portal.property.PortalOwner;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Helps migrate player names to UUID where necessary
|
||||
*/
|
||||
public class UUIDMigrationHelper {
|
||||
|
||||
private static Map<String, List<Portal>> playerNamesToMigrate;
|
||||
|
||||
/**
|
||||
* Migrates the player's name to a UUID
|
||||
*
|
||||
* <p>If any portals are missing a UUID for their owner, and the given player is the owner of those portals, the
|
||||
* given player's UUID will be used as UUID for the portals' owner.</p>
|
||||
*
|
||||
* @param player <p>The player to migrate</p>
|
||||
*/
|
||||
public static void migrateUUID(OfflinePlayer player) {
|
||||
Map<String, List<Portal>> playersToMigrate = getPlayersToMigrate();
|
||||
String playerName = player.getName();
|
||||
|
||||
//Nothing to do
|
||||
if (!playersToMigrate.containsKey(playerName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Stargate.debug("PlayerEventListener::migrateUUID", String.format("Migrating name to UUID for player %s",
|
||||
playerName));
|
||||
List<Portal> portalsOwned = playersToMigrate.get(playerName);
|
||||
if (portalsOwned == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
migratePortalsToUUID(portalsOwned, player.getUniqueId());
|
||||
|
||||
//Remove the player to prevent the migration to happen every time the player joins
|
||||
playersToMigrate.remove(playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a list of portals to use UUID instead of only player name
|
||||
*
|
||||
* @param portals <p>The portals to migrate</p>
|
||||
* @param uniqueId <p>The unique ID of the portals' owner</p>
|
||||
*/
|
||||
private static void migratePortalsToUUID(List<Portal> portals, UUID uniqueId) {
|
||||
Set<World> worldsToSave = new HashSet<>();
|
||||
|
||||
//Get the real portal from the copy and set UUID
|
||||
for (Portal portalCopy : portals) {
|
||||
Portal portal = PortalHandler.getByName(portalCopy.getName(), portalCopy.getNetwork());
|
||||
if (portal != null) {
|
||||
portal.getOwner().setUUID(uniqueId);
|
||||
worldsToSave.add(portal.getWorld());
|
||||
}
|
||||
}
|
||||
|
||||
//Need to make sure the changes are saved
|
||||
for (World world : worldsToSave) {
|
||||
PortalFileHelper.saveAllPortals(world);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all player names which need to be migrated to UUIDs
|
||||
*
|
||||
* @return <p>The player names to migrate</p>
|
||||
*/
|
||||
private static Map<String, List<Portal>> getPlayersToMigrate() {
|
||||
//Make sure to only go through portals once
|
||||
if (playerNamesToMigrate != null) {
|
||||
return playerNamesToMigrate;
|
||||
}
|
||||
|
||||
playerNamesToMigrate = new HashMap<>();
|
||||
for (Portal portal : PortalRegistry.getAllPortals()) {
|
||||
PortalOwner owner = portal.getOwner();
|
||||
String ownerName = owner.getName();
|
||||
|
||||
//If a UUID is missing, add the portal to the list owned by the player
|
||||
if (owner.getUUID() == null) {
|
||||
List<Portal> portalList = playerNamesToMigrate.get(ownerName);
|
||||
if (portalList == null) {
|
||||
List<Portal> newList = new ArrayList<>();
|
||||
newList.add(portal);
|
||||
playerNamesToMigrate.put(ownerName, newList);
|
||||
} else {
|
||||
portalList.add(portal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return playerNamesToMigrate;
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,11 @@
|
||||
# maxGatesEachNetwork - The maximum number of gates allowed on a network - 0 for unlimited
|
||||
# language - The language file to load for messages
|
||||
# rememberDestination - Whether to remember the cursor location between uses
|
||||
# handleVehicles - Whether to allow vehicles through gates
|
||||
# handleVehicles - Whether to allow vehicles through gates. This overrides other vehicle settings
|
||||
# handleEmptyVehicles - Whether to allow empty vehicles through gates (chest/hopper/tnt/furnace minecarts included)
|
||||
# handleCreatureTransportation - Whether to allow players to transport creatures by sending vehicles (minecarts, boats) through gates
|
||||
# handleNonPlayerVehicles - Whether to allow vehicles with a passenger which is not a player through gates. handleCreatureTransportation must be enabled
|
||||
# handleLeashedCreatures - Whether to allow creatures lead by a player to teleport with the player
|
||||
# sortNetworkDestinations - Whether to sort network lists alphabetically
|
||||
# protectEntrance - Whether to protect gate entrance material (More resource intensive. Only enable if using destroyable open/closed material)
|
||||
# mainSignColor - The color used for drawing signs (Default: BLACK).
|
||||
@ -49,6 +53,10 @@ gates:
|
||||
functionality:
|
||||
enableBungee: false
|
||||
handleVehicles: true
|
||||
handleEmptyVehicles: true
|
||||
handleCreatureTransportation: true
|
||||
handleNonPlayerVehicles: true
|
||||
handleLeashedCreatures: true
|
||||
economy:
|
||||
useEconomy: false
|
||||
createCost: 0
|
||||
|
13
src/main/resources/gates/squarenetherglowstonegate.gate
Normal file
13
src/main/resources/gates/squarenetherglowstonegate.gate
Normal file
@ -0,0 +1,13 @@
|
||||
portal-open=NETHER_PORTAL
|
||||
portal-closed=AIR
|
||||
button=OAK_BUTTON
|
||||
toowner=false
|
||||
X=OBSIDIAN
|
||||
-=GLOWSTONE
|
||||
A=GLOWSTONE
|
||||
|
||||
XAX
|
||||
X...X
|
||||
-...-
|
||||
X.*.X
|
||||
XAX
|
@ -35,3 +35,9 @@ bungeeDisabled=BungeeCord support is disabled.
|
||||
bungeeDeny=You do not have permission to create BungeeCord gates.
|
||||
bungeeEmpty=BungeeCord gates require both a destination and network.
|
||||
bungeeSign=Teleport to
|
||||
|
||||
portalInfoTitle=[STARGATE INFO]
|
||||
portalInfoName=Name: %name%
|
||||
portalInfoDestination=Destination: %destination%
|
||||
portalInfoNetwork=Network: %network%
|
||||
portalInfoServer=Server: %server%
|
@ -35,3 +35,9 @@ bungeeDisabled=BungeeCord støtte er slått av.
|
||||
bungeeDeny=Du har ikke tillatelse til å opprette BungeeCord porter.
|
||||
bungeeEmpty=BungeeCord porter behøver bade en destinasjon og et nettverk.
|
||||
bungeeSign=Teleporter til
|
||||
|
||||
portalInfoTitle=[STJERNEPORT INFO]
|
||||
portalInfoName=Navn: %name%
|
||||
portalInfoDestination=Destinasjon: %destination%
|
||||
portalInfoNetwork=Nettverk: %network%
|
||||
portalInfoServer=Server: %server%
|
@ -35,3 +35,9 @@ bungeeDisabled=BungeeCord støtte er slått av.
|
||||
bungeeDeny=Du har ikkje løyve til å opprette BungeeCord portar.
|
||||
bungeeEmpty=BungeeCord portar treng bade ein destinasjon og eit nettverk.
|
||||
bungeeSign=Teleporter til
|
||||
|
||||
portalInfoTitle=[STJERNEPORT INFO]
|
||||
portalInfoName=Namn: %name%
|
||||
portalInfoDestination=Destinasjon: %destination%
|
||||
portalInfoNetwork=Nettverk: %network%
|
||||
portalInfoServer=Server: %server%
|
@ -1,6 +1,6 @@
|
||||
name: Stargate
|
||||
main: net.knarcraft.stargate.Stargate
|
||||
version: 0.9.0.2
|
||||
version: 0.9.0.6
|
||||
description: Stargate mod for Bukkit Revived
|
||||
author: EpicKnarvik97
|
||||
authors: [ Drakia, PseudoKnight, EpicKnarvik97 ]
|
||||
@ -97,6 +97,8 @@ permissions:
|
||||
stargate.option.show: true
|
||||
stargate.option.nonetwork: true
|
||||
stargate.option.random: true
|
||||
stargate.option.silent: true
|
||||
stargate.option.nosign: true
|
||||
stargate.option.hidden:
|
||||
description: Allows the creation of a hidden stargate
|
||||
default: false
|
||||
@ -121,6 +123,12 @@ permissions:
|
||||
stargate.option.random:
|
||||
description: Allows the creation of a stargate with a random destination
|
||||
default: false
|
||||
stargate.option.silent:
|
||||
description: Allows the creation of a stargate which does not output anything to the chat
|
||||
default: false
|
||||
stargate.option.nosign:
|
||||
description: Allows the creation of a stargate which has no sign
|
||||
default: false
|
||||
stargate.admin.hidden:
|
||||
description: Allows this player to see all hidden stargates
|
||||
default: false
|
||||
|
@ -5,6 +5,8 @@ import be.seeseemelk.mockbukkit.ServerMock;
|
||||
import be.seeseemelk.mockbukkit.WorldMock;
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.portal.property.gate.GateHandler;
|
||||
import net.knarcraft.stargate.portal.property.gate.GateLayout;
|
||||
import org.bukkit.Material;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
Reference in New Issue
Block a user