diff --git a/src/main/java/com/onarandombox/multiverseinventories/InventoriesListener.java b/src/main/java/com/onarandombox/multiverseinventories/InventoriesListener.java index 8e1d8e4d..b8cf01db 100644 --- a/src/main/java/com/onarandombox/multiverseinventories/InventoriesListener.java +++ b/src/main/java/com/onarandombox/multiverseinventories/InventoriesListener.java @@ -3,6 +3,7 @@ import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.event.MVConfigReloadEvent; +import com.onarandombox.MultiverseCore.event.MVTeleportEvent; import com.onarandombox.MultiverseCore.event.MVVersionEvent; import com.onarandombox.multiverseinventories.profile.GlobalProfile; import com.onarandombox.multiverseinventories.profile.PlayerProfile; @@ -228,6 +229,22 @@ public void playerChangedWorld(PlayerChangedWorldEvent event) { inventories.getData().updateLastWorld(player.getName(), toWorld.getName()); } + /** + * Called when a player teleports using Multiverse. + * + * @param event The Multiverse teleport event. + */ + @EventHandler(priority = EventPriority.MONITOR) + public void playerMVTeleport(MVTeleportEvent event) { + if (event.isCancelled() + || event.getFrom().getWorld().equals(event.getDestination().getLocation(event.getTeleportee()).getWorld()) + || !this.inventories.getMVIConfig().getOptionalShares().contains(Sharables.LAST_LOCATION)) { + return; + } + + TeleportDetails.addTeleportDestination(event.getTeleportee(), event.getDestination()); + } + /** * Called when a player teleports. * @@ -250,6 +267,10 @@ public void playerTeleport(PlayerTeleportEvent event) { PlayerProfile playerProfile = fromWorldProfileContainer.getPlayerData(player); playerProfile.set(Sharables.LAST_LOCATION, event.getFrom()); + if (TeleportDetails.getTeleportDestination(player) == null) { + TeleportDetails.addTeleportDestination(player, event.getTo()); + } + List fromGroups = this.inventories.getGroupManager().getGroupsForWorld(fromWorldName); for (WorldGroup fromGroup : fromGroups) { playerProfile = fromGroup.getGroupProfileContainer().getPlayerData(event.getPlayer()); diff --git a/src/main/java/com/onarandombox/multiverseinventories/ShareHandler.java b/src/main/java/com/onarandombox/multiverseinventories/ShareHandler.java index 25008ab6..710336f8 100644 --- a/src/main/java/com/onarandombox/multiverseinventories/ShareHandler.java +++ b/src/main/java/com/onarandombox/multiverseinventories/ShareHandler.java @@ -33,6 +33,7 @@ public abstract class ShareHandler { * inventories/stats for a player and persisting the changes. */ final void handleSharing() { + TeleportDetails.removeTeleportDestination(this.player); ShareHandlingEvent event = this.createEvent(); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/com/onarandombox/multiverseinventories/TeleportDetails.java b/src/main/java/com/onarandombox/multiverseinventories/TeleportDetails.java new file mode 100644 index 00000000..b6ff6718 --- /dev/null +++ b/src/main/java/com/onarandombox/multiverseinventories/TeleportDetails.java @@ -0,0 +1,55 @@ +package com.onarandombox.multiverseinventories; + +import com.onarandombox.MultiverseCore.api.MVDestination; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +/** + * A utility class to keep track of currently happening teleportations. + * Keeps track of teleport destinations as well the type of destination. + */ +public class TeleportDetails { + public enum TeleportType { + MVTP, + OTHER + } + + static class TeleportDestination { + private final TeleportType type; + private final T destination; + + TeleportDestination(TeleportType type, T destination) { + this.type = type; + this.destination = destination; + } + + public TeleportType getType() { + return this.type; + } + + public T getDestination() { + return this.destination; + } + } + + private final static Map> teleportDestinationMap = new HashMap<>(); + + public static void addTeleportDestination(Player player, MVDestination mvDestination) { + teleportDestinationMap.put(player, new TeleportDestination<>(TeleportType.MVTP, mvDestination)); + } + + public static void addTeleportDestination(Player player, Location location) { + teleportDestinationMap.put(player, new TeleportDestination<>(TeleportType.OTHER, location)); + } + + public static TeleportDestination getTeleportDestination(Player player) { + return teleportDestinationMap.get(player); + } + + public static void removeTeleportDestination(Player player) { + teleportDestinationMap.remove(player); + } +} diff --git a/src/main/java/com/onarandombox/multiverseinventories/WorldChangeShareHandler.java b/src/main/java/com/onarandombox/multiverseinventories/WorldChangeShareHandler.java index 33662872..e71ec5b0 100644 --- a/src/main/java/com/onarandombox/multiverseinventories/WorldChangeShareHandler.java +++ b/src/main/java/com/onarandombox/multiverseinventories/WorldChangeShareHandler.java @@ -1,6 +1,7 @@ package com.onarandombox.multiverseinventories; import com.dumptruckman.minecraft.util.Logging; +import com.onarandombox.MultiverseCore.api.MVDestination; import com.onarandombox.multiverseinventories.event.ShareHandlingEvent; import com.onarandombox.multiverseinventories.event.WorldChangeShareHandlingEvent; import com.onarandombox.multiverseinventories.profile.PlayerProfile; @@ -21,6 +22,7 @@ final class WorldChangeShareHandler extends ShareHandler { private final String toWorld; private final List fromWorldGroups; private final List toWorldGroups; + private final boolean readLastLocation; WorldChangeShareHandler(MultiverseInventories inventories, Player player, String fromWorld, String toWorld) { super(inventories, player); @@ -32,6 +34,18 @@ final class WorldChangeShareHandler extends ShareHandler { // Get any groups we may need to load stuff from. this.toWorldGroups = getAffectedWorldGroups(toWorld); + // don't read last_location if there is an exact teleportation happening + boolean readLastLocation = true; + TeleportDetails.TeleportDestination teleportDestination = TeleportDetails.getTeleportDestination(player); + if (teleportDestination != null && teleportDestination.getType() == TeleportDetails.TeleportType.MVTP) { + MVDestination mvDestination = (MVDestination) teleportDestination.getDestination(); + if (mvDestination.getIdentifier().equals("e")) { + readLastLocation = false; + } + } + + this.readLastLocation = readLastLocation; + prepareProfiles(); } @@ -82,7 +96,7 @@ private boolean isPlayerBypassingChange() { private void addProfiles() { addWriteProfiles(); - new ReadProfilesAggregator().addReadProfiles(); + new ReadProfilesAggregator(this.readLastLocation).addReadProfiles(); } private void addWriteProfiles() { @@ -100,6 +114,11 @@ private boolean hasFromWorldGroups() { private class ReadProfilesAggregator { private Shares sharesToRead; + private final boolean readLastLocation; + + ReadProfilesAggregator(boolean readLastLocation) { + this.readLastLocation = readLastLocation; + } private void addReadProfiles() { sharesToRead = Sharables.noneOf(); @@ -149,6 +168,10 @@ private void addReadProfileForWorldGroup(WorldGroup worldGroup) { PlayerProfile playerProfile = getWorldGroupPlayerData(worldGroup); Shares sharesToAdd = getWorldGroupShares(worldGroup); + if (!this.readLastLocation) { + sharesToAdd.remove(Sharables.LAST_LOCATION); + } + addReadProfile(playerProfile, sharesToAdd); sharesToRead.addAll(sharesToAdd); } @@ -179,6 +202,10 @@ private boolean hasUnhandledShares() { private void addUnhandledSharesFromToWorld() { Shares unhandledShares = Sharables.complimentOf(sharesToRead); + if (!this.readLastLocation) { + unhandledShares.remove(Sharables.LAST_LOCATION); + } + Logging.finer("%s are left unhandled, defaulting to toWorld", unhandledShares); addReadProfile(getToWorldPlayerData(), unhandledShares);