diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 4816eb2..f428ac2 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.portal.VehicleTeleporter; import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; +import net.knarcraft.stargate.utility.UUIDMigrationHelper; import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.block.data.type.WallSign; @@ -42,6 +43,9 @@ public class PlayerEventListener implements Listener { */ @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { + //Migrate player name to UUID if necessary + UUIDMigrationHelper.migrateUUID(event.getPlayer()); + if (!Stargate.getGateConfig().enableBungee()) { return; } @@ -154,7 +158,7 @@ public class PlayerEventListener implements Listener { //Decide if the user should be teleported to another bungee server if (entrancePortal.getOptions().isBungee()) { - if (bungeeTeleport(player, entrancePortal, event)) { + if (BungeeHelper.bungeeTeleport(player, entrancePortal, event)) { Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); } return false; @@ -306,39 +310,4 @@ public class PlayerEventListener implements Listener { return false; } - /** - * Teleports a player to a bungee gate - * - * @param player

The player to teleport

- * @param entrancePortal

The gate the player is entering from

- * @param event

The event causing the teleportation

- * @return

True if the teleportation was successful

- */ - private boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { - //Check if bungee is actually enabled - if (!Stargate.getGateConfig().enableBungee()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); - entrancePortal.getPortalOpener().closePortal(false); - return false; - } - - //Teleport the player back to this gate, for sanity's sake - new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); - - //Send the SGBungee packet first, it will be queued by BC if required - if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { - Stargate.debug("bungeeTeleport", "Unable to send teleportation message"); - return false; - } - - //Send the connect-message to make the player change server - if (!BungeeHelper.changeServer(player, entrancePortal)) { - Stargate.debug("bungeeTeleport", "Unable to change server"); - return false; - } - - Stargate.debug("bungeeTeleport", "Teleported player to another server"); - return true; - } - } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java b/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java index 019f57d..eb92fe8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOwner.java @@ -43,6 +43,22 @@ public class PortalOwner { return ownerUUID; } + /** + * Sets the unique id for a portal owner without one + * + *

This method is only meant to be used to set the unique id for an owner without one. If the owner already has + * an unique id, an exception will be thrown.

+ * + * @param uniqueId

The new unique id for the portal owner

+ */ + public void setUUID(UUID uniqueId) { + if (ownerUUID == null) { + ownerUUID = uniqueId; + } else { + throw new IllegalArgumentException("An existing UUID cannot be overwritten."); + } + } + /** * Gets the name of this owner * diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 81f608e..35229c2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerMoveEvent; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -169,4 +170,39 @@ public final class BungeeHelper { } } + /** + * Teleports a player to a bungee gate + * + * @param player

The player to teleport

+ * @param entrancePortal

The gate the player is entering from

+ * @param event

The event causing the teleportation

+ * @return

True if the teleportation was successful

+ */ + public static boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { + //Check if bungee is actually enabled + if (!Stargate.getGateConfig().enableBungee()) { + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + entrancePortal.getPortalOpener().closePortal(false); + return false; + } + + //Teleport the player back to this gate, for sanity's sake + new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); + + //Send the SGBungee packet first, it will be queued by BC if required + if (!BungeeHelper.sendTeleportationMessage(player, entrancePortal)) { + Stargate.debug("bungeeTeleport", "Unable to send teleportation message"); + return false; + } + + //Send the connect-message to make the player change server + if (!BungeeHelper.changeServer(player, entrancePortal)) { + Stargate.debug("bungeeTeleport", "Unable to change server"); + return false; + } + + Stargate.debug("bungeeTeleport", "Teleported player to another server"); + return true; + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java new file mode 100644 index 0000000..e58141c --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -0,0 +1,111 @@ +package net.knarcraft.stargate.utility; + +import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.portal.Portal; +import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalOwner; +import net.knarcraft.stargate.portal.PortalRegistry; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +/** + * Helps migrate player names to UUID where necessary + */ +public class UUIDMigrationHelper { + + private static Map> playerNamesToMigrate; + + /** + * Migrates the player's name to a UUID + * + *

If any portals are missing a UUID for their owner, and the given player is the owner of those portals, the + * given player's UUID will be used as UUID for the portals' owner.

+ * + * @param player

The player to migrate

+ */ + public static void migrateUUID(OfflinePlayer player) { + Map> playersToMigrate = getPlayersToMigrate(); + String playerName = player.getName(); + + //Nothing to do + if (!playersToMigrate.containsKey(playerName)) { + return; + } + + Stargate.debug("PlayerEventListener::migrateUUID", String.format("Migrating name to UUID for player %s", + playerName)); + List portalsOwned = playersToMigrate.get(playerName); + if (portalsOwned == null) { + return; + } + + migratePortalsToUUID(portalsOwned, player.getUniqueId()); + + //Remove the player to prevent the migration to happen every time the player joins + playersToMigrate.remove(playerName); + } + + /** + * Migrates a list of portals to use UUID instead of only player name + * + * @param portals

The portals to migrate

+ * @param uniqueId

The unique ID of the portals' owner

+ */ + private static void migratePortalsToUUID(List portals, UUID uniqueId) { + Set worldsToSave = new HashSet<>(); + + //Get the real portal from the copy and set UUID + for (Portal portalCopy : portals) { + Portal portal = PortalHandler.getByName(portalCopy.getName(), portalCopy.getNetwork()); + if (portal != null) { + portal.getOwner().setUUID(uniqueId); + worldsToSave.add(portal.getWorld()); + } + } + + //Need to make sure the changes are saved + for (World world : worldsToSave) { + PortalFileHelper.saveAllPortals(world); + } + } + + /** + * Gets all player names which need to be migrated to UUIDs + * + * @return

The player names to migrate

+ */ + private static Map> getPlayersToMigrate() { + //Make sure to only go through portals once + if (playerNamesToMigrate != null) { + return playerNamesToMigrate; + } + + playerNamesToMigrate = new HashMap<>(); + for (Portal portal : PortalRegistry.getAllPortals()) { + PortalOwner owner = portal.getOwner(); + String ownerName = owner.getName(); + + //If a UUID is missing, add the portal to the list owned by the player + if (owner.getUUID() == null) { + List portalList = playerNamesToMigrate.get(ownerName); + if (portalList == null) { + List newList = new ArrayList<>(); + newList.add(portal); + playerNamesToMigrate.put(ownerName, newList); + } else { + portalList.add(portal); + } + } + } + return playerNamesToMigrate; + } + +}