13 Commits

Author SHA1 Message Date
e5c1ad1f3a 0.9.0.5 - Adds three new options to disable features of vehicle teleportation with more granularity #9
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-03 15:55:56 +01:00
cab99e11b0 Adds leashed teleportation as a feature to the README
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-01 19:25:52 +01:00
3c4d10ae3f Updates changelog and version to 0.9.0.4 2021-11-01 18:49:05 +01:00
aff0082906 Adds a config option to disable leashed creatures from teleporting with a player 2021-11-01 18:44:10 +01:00
20c3c93c06 Adds a few fixes which seem to make leash teleportation work as expected
Un-leashes and re-leashes teleported leashed entities
Delays leashed creature teleportation and the re-leashing to prevent odd behavior such as infinite leash or no-ai creature
2021-11-01 17:54:38 +01:00
dab9378a67 Merge branch 'master' into leashed-teleportation 2021-11-01 17:05:34 +01:00
62661f65f4 Updates info and version to 0.9.0.3
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-01 16:32:56 +01:00
b8d98c26d4 Adds triggers for teleporting leashed entities 2021-11-01 16:28:13 +01:00
8bb9c464d6 Adds some code for teleporting creatures leashed by a player 2021-11-01 16:27:29 +01:00
2b5d791581 Adds the EntityTeleporter for generic teleportation of entities 2021-11-01 16:26:46 +01:00
2a61480684 Adds UUID fetching on player join. See #12
Whenever a player joins, their names will be checked against a map containing all names which need to be migrated to UUID. All portals the player has created which still use the player name will be updated.
2021-11-01 15:13:22 +01:00
91a0316e6e Adds a missing insufficient funds message when checking if vehicle passengers can pay for the teleportation 2021-11-01 13:54:31 +01:00
b98aec4a20 0.9.0.2 Fixes a bug in the code to prevent nether portals from generating in the nether 2021-11-01 00:38:36 +01:00
15 changed files with 486 additions and 81 deletions

View File

@ -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)
@ -301,6 +302,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
@ -367,6 +372,29 @@ bungeeSign=Teleport to
# Changes
#### \[Version 0.9.0.5] EpicKnarvik97 fork
- Adds an option to stargate functionality to disable all teleportation of creatures
- Adds an option to stargate functionality to disable all teleportation of empty minecarts
- Adds an option to stargate functionality to disable teleportation of creatures if no player is present in the vehicle
- Prevents a player in a vehicle from teleporting without the vehicle if vehicle teleportation is disabled
- Prevents an infinite number of teleportation messages if vehicle teleportation is detected but denied
#### \[Version 0.9.0.4] EpicKnarvik97 fork
- Adds teleportation of leashed creatures. By default, any creature connected to a player by a lead will be teleported
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.
#### \[Version 0.9.0.1] EpicKnarvik97 fork
- Adds the highlightSignColor option and renames the signColor option to mainSignColor

View File

@ -4,7 +4,7 @@
<groupId>net.knarcraft</groupId>
<artifactId>Stargate</artifactId>
<version>0.9.0.1</version>
<version>0.9.0.5</version>
<licenses>
<license>

View File

@ -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);
}
}

View File

@ -10,6 +10,7 @@ import net.knarcraft.stargate.portal.VehicleTeleporter;
import net.knarcraft.stargate.utility.BungeeHelper;
import net.knarcraft.stargate.utility.MaterialHelper;
import net.knarcraft.stargate.utility.PermissionHelper;
import net.knarcraft.stargate.utility.UUIDMigrationHelper;
import org.bukkit.GameMode;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.WallSign;
@ -42,6 +43,9 @@ public class PlayerEventListener implements Listener {
*/
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
//Migrate player name to UUID if necessary
UUIDMigrationHelper.migrateUUID(event.getPlayer());
if (!Stargate.getGateConfig().enableBungee()) {
return;
}
@ -86,7 +90,8 @@ public class PlayerEventListener implements Listener {
Entity playerVehicle = player.getVehicle();
//If the player is in a vehicle, but vehicle handling is disabled, just ignore the player
if (playerVehicle == null || Stargate.getGateConfig().handleVehicles()) {
if (playerVehicle == null || (playerVehicle instanceof LivingEntity &&
Stargate.getGateConfig().handleVehicles())) {
teleportPlayer(playerVehicle, player, entrancePortal, destination, event);
}
}
@ -154,7 +159,7 @@ public class PlayerEventListener implements Listener {
//Decide if the user should be teleported to another bungee server
if (entrancePortal.getOptions().isBungee()) {
if (bungeeTeleport(player, entrancePortal, event)) {
if (BungeeHelper.bungeeTeleport(player, entrancePortal, event)) {
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
}
return false;
@ -306,39 +311,4 @@ public class PlayerEventListener implements Listener {
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;
}
}

View File

@ -1,5 +1,6 @@
package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.container.FromTheEndTeleportation;
import net.knarcraft.stargate.portal.PlayerTeleporter;
import net.knarcraft.stargate.portal.Portal;
@ -8,7 +9,6 @@ import net.knarcraft.stargate.utility.PermissionHelper;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -37,11 +37,14 @@ public class PortalEventListener implements Listener {
if (event.isCancelled()) {
return;
}
//Cancel nether portal creation when the portal is a StarGate portal
for (BlockState block : event.getBlocks()) {
if (PortalHandler.getByBlock(block.getBlock()) != null) {
//Unnecessary nether portal creation is only triggered by nether pairing
if (event.getReason() == PortalCreateEvent.CreateReason.NETHER_PAIR) {
//If an entity is standing in a Stargate entrance, it can be assumed that the creation is a mistake
Entity entity = event.getEntity();
if (entity != null && PortalHandler.getByAdjacentEntrance(entity.getLocation()) != null) {
Stargate.debug("PortalEventListener::onPortalCreation",
"Cancelled nether portal create event");
event.setCancelled(true);
return;
}
}
}

View File

@ -115,9 +115,12 @@ public class VehicleEventListener implements Listener {
}
}
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal);
entrancePortal.getPortalOpener().closePortal(false);
//Teleport the vehicle and inform the user if the vehicle was teleported
boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleport(entrancePortal);
if (teleported) {
Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg"));
entrancePortal.getPortalOpener().closePortal(false);
}
}
/**
@ -154,9 +157,13 @@ public class VehicleEventListener implements Listener {
return false;
}
//Transfer payment if necessary
//Check if the player is able to afford the teleport fee
int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal);
return cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost);
boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost);
if (!canAffordFee) {
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds"));
}
return canAffordFee;
}
}

View File

@ -0,0 +1,71 @@
package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.event.StargateEntityPortalEvent;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
/**
* The portal teleporter takes care of the actual portal teleportation for any entities
*/
public class EntityTeleporter extends Teleporter {
private final Entity teleportingEntity;
/**
* Instantiates a new portal teleporter
*
* @param portal <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();
}
}

View File

@ -48,6 +48,9 @@ public class PlayerTeleporter extends Teleporter {
//Load chunks to make sure not to teleport to the void
loadChunks();
//Teleport any creatures leashed by the player in a 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);

View File

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

View File

@ -13,7 +13,9 @@ import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Slab;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import java.util.ArrayList;
@ -247,4 +249,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), 3);
}, 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;
}
}

View File

@ -1,12 +1,13 @@
package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.event.StargateEntityPortalEvent;
import net.knarcraft.stargate.config.StargateGateConfig;
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 +16,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 +27,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 +37,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 +61,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 +74,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 +159,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 +177,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 +193,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 +203,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);
}
}

View File

@ -5,6 +5,7 @@ import net.knarcraft.stargate.portal.PlayerTeleporter;
import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalHandler;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerMoveEvent;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -169,4 +170,39 @@ public final class BungeeHelper {
}
}
/**
* Teleports a player to a bungee gate
*
* @param player <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()) {
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;
}
}

View File

@ -0,0 +1,111 @@
package net.knarcraft.stargate.utility;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.portal.PortalOwner;
import net.knarcraft.stargate.portal.PortalRegistry;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/**
* Helps migrate player names to UUID where necessary
*/
public class UUIDMigrationHelper {
private static Map<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;
}
}

View File

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

View File

@ -1,6 +1,6 @@
name: Stargate
main: net.knarcraft.stargate.Stargate
version: 0.9.0.1
version: 0.9.0.5
description: Stargate mod for Bukkit Revived
author: EpicKnarvik97
authors: [ Drakia, PseudoKnight, EpicKnarvik97 ]