mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-22 02:25:41 +01:00
Completely refactor player listener
This commit is contained in:
parent
454bcd36e5
commit
b4d86ac133
@ -188,11 +188,7 @@ public class MVCoreConfig implements MVConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
|
||||||
public String getJoinDestination() {
|
public String getJoinDestination() {
|
||||||
if (Objects.equals(configHandle.get(configNodes.JOIN_DESTINATION), "")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return configHandle.get(configNodes.JOIN_DESTINATION);
|
return configHandle.get(configNodes.JOIN_DESTINATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ import org.mvplugins.multiverse.core.world.WorldManager;
|
|||||||
public class MVChatListener implements InjectableListener {
|
public class MVChatListener implements InjectableListener {
|
||||||
private final MVCoreConfig config;
|
private final MVCoreConfig config;
|
||||||
private final WorldManager worldManager;
|
private final WorldManager worldManager;
|
||||||
private final MVPlayerListener playerListener;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MVChatListener(
|
MVChatListener(
|
||||||
@ -26,7 +25,6 @@ public class MVChatListener implements InjectableListener {
|
|||||||
MVPlayerListener playerListener) {
|
MVPlayerListener playerListener) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.worldManager = worldManager;
|
this.worldManager = worldManager;
|
||||||
this.playerListener = playerListener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,13 +44,7 @@ public class MVChatListener implements InjectableListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String world = playerListener.getPlayerWorld().get(event.getPlayer().getName());
|
String prefix = this.worldManager.getLoadedWorld(event.getPlayer().getWorld())
|
||||||
if (world == null) {
|
|
||||||
world = event.getPlayer().getWorld().getName();
|
|
||||||
playerListener.getPlayerWorld().put(event.getPlayer().getName(), world);
|
|
||||||
}
|
|
||||||
|
|
||||||
String prefix = this.worldManager.getLoadedWorld(world)
|
|
||||||
.map(mvworld -> mvworld.isHidden() ? "" : mvworld.getAlias())
|
.map(mvworld -> mvworld.isHidden() ? "" : mvworld.getAlias())
|
||||||
.getOrElse("");
|
.getOrElse("");
|
||||||
String chat = event.getFormat();
|
String chat = event.getFormat();
|
||||||
|
@ -7,17 +7,15 @@
|
|||||||
|
|
||||||
package org.mvplugins.multiverse.core.listeners;
|
package org.mvplugins.multiverse.core.listeners;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import com.dumptruckman.minecraft.util.Logging;
|
import com.dumptruckman.minecraft.util.Logging;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Provider;
|
import jakarta.inject.Provider;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -37,7 +35,6 @@ import org.mvplugins.multiverse.core.api.BlockSafety;
|
|||||||
import org.mvplugins.multiverse.core.commandtools.MVCommandManager;
|
import org.mvplugins.multiverse.core.commandtools.MVCommandManager;
|
||||||
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
||||||
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
||||||
import org.mvplugins.multiverse.core.destination.ParsedDestination;
|
|
||||||
import org.mvplugins.multiverse.core.economy.MVEconomist;
|
import org.mvplugins.multiverse.core.economy.MVEconomist;
|
||||||
import org.mvplugins.multiverse.core.event.MVRespawnEvent;
|
import org.mvplugins.multiverse.core.event.MVRespawnEvent;
|
||||||
import org.mvplugins.multiverse.core.inject.InjectableListener;
|
import org.mvplugins.multiverse.core.inject.InjectableListener;
|
||||||
@ -45,6 +42,7 @@ import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter;
|
|||||||
import org.mvplugins.multiverse.core.teleportation.TeleportQueue;
|
import org.mvplugins.multiverse.core.teleportation.TeleportQueue;
|
||||||
import org.mvplugins.multiverse.core.utils.result.ResultChain;
|
import org.mvplugins.multiverse.core.utils.result.ResultChain;
|
||||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||||
|
import org.mvplugins.multiverse.core.world.MultiverseWorld;
|
||||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||||
import org.mvplugins.multiverse.core.world.entrycheck.EntryFeeResult;
|
import org.mvplugins.multiverse.core.world.entrycheck.EntryFeeResult;
|
||||||
import org.mvplugins.multiverse.core.world.entrycheck.WorldEntryCheckerProvider;
|
import org.mvplugins.multiverse.core.world.entrycheck.WorldEntryCheckerProvider;
|
||||||
@ -60,7 +58,6 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
private final Provider<WorldManager> worldManagerProvider;
|
private final Provider<WorldManager> worldManagerProvider;
|
||||||
private final BlockSafety blockSafety;
|
private final BlockSafety blockSafety;
|
||||||
private final AsyncSafetyTeleporter safetyTeleporter;
|
private final AsyncSafetyTeleporter safetyTeleporter;
|
||||||
private final Server server;
|
|
||||||
private final TeleportQueue teleportQueue;
|
private final TeleportQueue teleportQueue;
|
||||||
private final MVEconomist economist;
|
private final MVEconomist economist;
|
||||||
private final WorldEntryCheckerProvider worldEntryCheckerProvider;
|
private final WorldEntryCheckerProvider worldEntryCheckerProvider;
|
||||||
@ -68,8 +65,6 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
private final DestinationsProvider destinationsProvider;
|
private final DestinationsProvider destinationsProvider;
|
||||||
private final EnforcementHandler enforcementHandler;
|
private final EnforcementHandler enforcementHandler;
|
||||||
|
|
||||||
private final Map<String, String> playerWorld = new ConcurrentHashMap<String, String>();
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MVPlayerListener(
|
MVPlayerListener(
|
||||||
MultiverseCore plugin,
|
MultiverseCore plugin,
|
||||||
@ -77,7 +72,6 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
Provider<WorldManager> worldManagerProvider,
|
Provider<WorldManager> worldManagerProvider,
|
||||||
BlockSafety blockSafety,
|
BlockSafety blockSafety,
|
||||||
AsyncSafetyTeleporter safetyTeleporter,
|
AsyncSafetyTeleporter safetyTeleporter,
|
||||||
Server server,
|
|
||||||
TeleportQueue teleportQueue,
|
TeleportQueue teleportQueue,
|
||||||
MVEconomist economist,
|
MVEconomist economist,
|
||||||
WorldEntryCheckerProvider worldEntryCheckerProvider,
|
WorldEntryCheckerProvider worldEntryCheckerProvider,
|
||||||
@ -89,7 +83,6 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
this.worldManagerProvider = worldManagerProvider;
|
this.worldManagerProvider = worldManagerProvider;
|
||||||
this.blockSafety = blockSafety;
|
this.blockSafety = blockSafety;
|
||||||
this.safetyTeleporter = safetyTeleporter;
|
this.safetyTeleporter = safetyTeleporter;
|
||||||
this.server = server;
|
|
||||||
this.teleportQueue = teleportQueue;
|
this.teleportQueue = teleportQueue;
|
||||||
this.economist = economist;
|
this.economist = economist;
|
||||||
this.worldEntryCheckerProvider = worldEntryCheckerProvider;
|
this.worldEntryCheckerProvider = worldEntryCheckerProvider;
|
||||||
@ -106,15 +99,6 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
return commandManagerProvider.get();
|
return commandManagerProvider.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the map of player and the world name they are in.
|
|
||||||
*
|
|
||||||
* @return the playerWorld-map
|
|
||||||
*/
|
|
||||||
public Map<String, String> getPlayerWorld() {
|
|
||||||
return playerWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when a player respawns.
|
* This method is called when a player respawns.
|
||||||
*
|
*
|
||||||
@ -122,159 +106,156 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
public void playerRespawn(PlayerRespawnEvent event) {
|
public void playerRespawn(PlayerRespawnEvent event) {
|
||||||
World world = event.getPlayer().getWorld();
|
getWorldManager()
|
||||||
LoadedMultiverseWorld mvWorld = getWorldManager().getLoadedWorld(world.getName()).getOrNull();
|
.getLoadedWorld(event.getPlayer().getWorld())
|
||||||
// If it's not a World MV manages we stop.
|
.filter(mvWorld -> isBedOrAnchorRespawn(event, mvWorld))
|
||||||
if (mvWorld == null) {
|
.flatMap(MultiverseWorld::getRespawnWorld)
|
||||||
return;
|
.map(this::getMostAccurateRespawnLocation)
|
||||||
|
.peek(respawnLocation -> callMVRepawnEvent(event, respawnLocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isBedOrAnchorRespawn(PlayerRespawnEvent event, LoadedMultiverseWorld mvWorld) {
|
||||||
if (mvWorld.getBedRespawn() && (event.isBedSpawn() || event.isAnchorSpawn())) {
|
if (mvWorld.getBedRespawn() && (event.isBedSpawn() || event.isAnchorSpawn())) {
|
||||||
Logging.fine("Spawning %s at their %s.", event.getPlayer().getName(), event.isBedSpawn() ? "BED" : "ANCHOR");
|
Logging.fine("Spawning %s at their %s.",
|
||||||
return;
|
event.getPlayer().getName(),
|
||||||
|
event.isBedSpawn() ? "BED" : "ANCHOR");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the instance of the World the player should respawn at.
|
private Location getMostAccurateRespawnLocation(World world) {
|
||||||
LoadedMultiverseWorld respawnWorld = null;
|
return getWorldManager().getLoadedWorld(world.getName())
|
||||||
if (getWorldManager().isLoadedWorld(mvWorld.getRespawnWorld())) {
|
.map(LoadedMultiverseWorld::getSpawnLocation)
|
||||||
respawnWorld = getWorldManager().getLoadedWorld(mvWorld.getRespawnWorld()).getOrNull();
|
.getOrElse(world.getSpawnLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's null then it either means the World doesn't exist or the value is blank, so we don't handle it.
|
private void callMVRepawnEvent(PlayerRespawnEvent event, Location respawnLocation) {
|
||||||
// NOW: We'll always handle it to get more accurate spawns
|
MVRespawnEvent respawnEvent = new MVRespawnEvent(
|
||||||
if (respawnWorld != null) {
|
respawnLocation, event.getPlayer(), "compatability");
|
||||||
world = respawnWorld.getBukkitWorld().getOrNull();
|
Bukkit.getPluginManager().callEvent(respawnEvent);
|
||||||
}
|
|
||||||
// World has been set to the appropriate world
|
|
||||||
Location respawnLocation = getMostAccurateRespawnLocation(world);
|
|
||||||
|
|
||||||
MVRespawnEvent respawnEvent = new MVRespawnEvent(respawnLocation, event.getPlayer(), "compatability");
|
|
||||||
this.server.getPluginManager().callEvent(respawnEvent);
|
|
||||||
event.setRespawnLocation(respawnEvent.getPlayersRespawnLocation());
|
event.setRespawnLocation(respawnEvent.getPlayersRespawnLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Location getMostAccurateRespawnLocation(World w) {
|
|
||||||
LoadedMultiverseWorld mvw = getWorldManager().getLoadedWorld(w.getName()).getOrNull();
|
|
||||||
if (mvw != null) {
|
|
||||||
return mvw.getSpawnLocation();
|
|
||||||
}
|
|
||||||
return w.getSpawnLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when a player joins the server.
|
* This method is called when a player joins the server.
|
||||||
|
*
|
||||||
* @param event The Event that was fired.
|
* @param event The Event that was fired.
|
||||||
*/
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void playerJoin(PlayerJoinEvent event) {
|
public void playerJoin(PlayerJoinEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
LoadedMultiverseWorld world = getWorldManager().getLoadedWorld(player.getWorld()).getOrNull();
|
if (player.hasPlayedBefore()) {
|
||||||
if (world == null) {
|
playerJoinAgain(event);
|
||||||
Logging.finer("Player joined in a world that is not managed by Multiverse.");
|
} else {
|
||||||
|
playerJoinFirstTime(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the Players GameMode setting for the new world.
|
||||||
|
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playerJoinAgain(PlayerJoinEvent event) {
|
||||||
|
Logging.finer("Player joined AGAIN!");
|
||||||
|
if (!config.getEnableJoinDestination()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Option.of(destinationsProvider.parseDestination(config.getJoinDestination()))
|
||||||
|
.peek(joinDestination -> {
|
||||||
|
Logging.fine("Moving player to: %s", joinDestination);
|
||||||
|
safetyTeleporter.teleportSafely(event.getPlayer(), joinDestination);
|
||||||
|
})
|
||||||
|
.onEmpty(() -> {
|
||||||
|
Logging.warning("JoinDestination '%s' is invalid! Not teleporting player!",
|
||||||
|
config.getJoinDestination());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playerJoinFirstTime(PlayerJoinEvent event) {
|
||||||
|
Logging.finer("Player joined for the FIRST time!");
|
||||||
|
if (!config.getFirstSpawnOverride()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Option.of(destinationsProvider.parseDestination(config.getFirstSpawnLocation()))
|
Option.of(destinationsProvider.parseDestination(config.getFirstSpawnLocation()))
|
||||||
.peek(parsedDestination -> {
|
.peek(firstSpawnDestination -> {
|
||||||
if (!player.hasPlayedBefore()) {
|
Logging.fine("Moving NEW player to(firstspawnoverride): %s", firstSpawnDestination);
|
||||||
Logging.finer("Player joined for the FIRST time!");
|
safetyTeleporter.teleportSafely(event.getPlayer(), firstSpawnDestination);
|
||||||
if (config.getFirstSpawnOverride()) {
|
})
|
||||||
Logging.fine("Moving NEW player to(firstspawnoverride): %s", config.getFirstSpawnLocation());
|
.onEmpty(() -> {
|
||||||
this.sendPlayerToDefaultWorld(player, parsedDestination);
|
Logging.warning("FirstSpawnLocation '%s' is invalid! Not teleporting player!",
|
||||||
}
|
config.getFirstSpawnLocation());
|
||||||
}
|
|
||||||
handleJoinDestination(player);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle the Players GameMode setting for the new world.
|
|
||||||
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
|
||||||
playerWorld.put(player.getName(), player.getWorld().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will teleport the player to the destination specified in config
|
|
||||||
* @param player The {@link Player} to teleport
|
|
||||||
*/
|
|
||||||
private void handleJoinDestination(@NotNull Player player) {
|
|
||||||
if (!config.getEnableJoinDestination()) {
|
|
||||||
Logging.finer("JoinDestination is disabled");
|
|
||||||
// User has disabled the feature in config
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.getJoinDestination() == null) {
|
|
||||||
Logging.warning("Joindestination is enabled but no destination has been specified in config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.finer("JoinDestination is " + config.getJoinDestination());
|
|
||||||
ParsedDestination<?> joinDestination = destinationsProvider.parseDestination(config.getJoinDestination());
|
|
||||||
|
|
||||||
if (joinDestination == null) {
|
|
||||||
Logging.warning("The destination in JoinDestination in config is invalid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, teleport the player
|
|
||||||
safetyTeleporter.teleportSafely(player, player, joinDestination);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when a player changes worlds.
|
* This method is called when a player changes worlds.
|
||||||
|
*
|
||||||
* @param event The Event that was fired.
|
* @param event The Event that was fired.
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void playerChangedWorld(PlayerChangedWorldEvent event) {
|
public void playerChangedWorld(PlayerChangedWorldEvent event) {
|
||||||
// Permissions now determine whether or not to handle a gamemode.
|
// Permissions now determine whether or not to handle a gamemode.
|
||||||
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
||||||
playerWorld.put(event.getPlayer().getName(), event.getPlayer().getWorld().getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when a player teleports anywhere.
|
* This method is called when a player teleports anywhere.
|
||||||
|
*
|
||||||
* @param event The Event that was fired.
|
* @param event The Event that was fired.
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void playerTeleport(PlayerTeleportEvent event) {
|
public void playerTeleport(PlayerTeleportEvent event) {
|
||||||
Logging.finer("Got teleport event for player '"
|
if (event.getTo() == null) {
|
||||||
+ event.getPlayer().getName() + "' with cause '" + event.getCause() + "'");
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Player teleportee = event.getPlayer();
|
|
||||||
CommandSender teleporter;
|
|
||||||
Optional<String> teleporterName = teleportQueue.popFromQueue(teleportee.getName());
|
|
||||||
if (teleporterName.isPresent()) {
|
|
||||||
if (teleporterName.equals("CONSOLE")) {
|
|
||||||
Logging.finer("We know the teleporter is the console! Magical!");
|
|
||||||
teleporter = this.server.getConsoleSender();
|
|
||||||
} else {
|
|
||||||
teleporter = this.server.getPlayerExact(teleporterName.get());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
teleporter = teleportee;
|
|
||||||
}
|
|
||||||
Logging.finer("Inferred sender '" + teleporter + "' from name '"
|
|
||||||
+ teleporterName + "', fetched from name '" + teleportee.getName() + "'");
|
|
||||||
LoadedMultiverseWorld fromWorld = getWorldManager().getLoadedWorld(event.getFrom().getWorld().getName()).getOrNull();
|
|
||||||
LoadedMultiverseWorld toWorld = getWorldManager().getLoadedWorld(event.getTo().getWorld().getName()).getOrNull();
|
|
||||||
if (toWorld == null) {
|
|
||||||
Logging.fine("Player '" + teleportee.getName() + "' is teleporting to world '"
|
|
||||||
+ event.getTo().getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
|
||||||
+ "actions will be taken by Multiverse-Core.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
|
||||||
// The player is Teleporting to the same world.
|
|
||||||
Logging.finer("Player '" + teleportee.getName() + "' is teleporting to the same world.");
|
|
||||||
this.stateSuccess(teleportee.getName(), toWorld.getAlias());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultChain entryResult = worldEntryCheckerProvider.forSender(teleporter).canEnterWorld(fromWorld, toWorld)
|
Logging.finer("Got teleport event for player '%s' with cause '%s'",
|
||||||
|
event.getPlayer().getName(), event.getCause());
|
||||||
|
|
||||||
|
Player teleportee = event.getPlayer();
|
||||||
|
CommandSender teleporter = getTeleporter(teleportee);
|
||||||
|
|
||||||
|
World fromWorld = event.getFrom().getWorld();
|
||||||
|
World toWorld = event.getTo().getWorld();
|
||||||
|
if (toWorld == null) {
|
||||||
|
Logging.warning("Player '%s' is teleporting to a world that does not exist. "
|
||||||
|
+ "No further actions will be taken by Multiverse-Core.", teleportee.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(fromWorld, toWorld)) {
|
||||||
|
// The player is Teleporting to the same world.
|
||||||
|
Logging.finer("Player '%s' is teleporting to the same world '%s'.",
|
||||||
|
teleportee.getName(), toWorld.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTeleportEntry(event, toWorld, fromWorld, teleporter, teleportee);
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull CommandSender getTeleporter(Player teleportee) {
|
||||||
|
return teleportQueue.popFromQueue(teleportee.getName())
|
||||||
|
.map(teleporterName -> {
|
||||||
|
Logging.finer("Player '%s' is being teleported by '%s'.",
|
||||||
|
teleportee.getName(), teleporterName);
|
||||||
|
return teleporterName.equals("CONSOLE")
|
||||||
|
? Bukkit.getConsoleSender()
|
||||||
|
: Bukkit.getPlayerExact(teleporterName);
|
||||||
|
})
|
||||||
|
.getOrElse(teleportee);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkTeleportEntry(
|
||||||
|
PlayerTeleportEvent event, World toWorld, World fromWorld, CommandSender teleporter, Player teleportee) {
|
||||||
|
getWorldManager().getLoadedWorld(toWorld).peek(mvToWorld -> {
|
||||||
|
LoadedMultiverseWorld mvFromWorld = getWorldManager().getLoadedWorld(fromWorld).getOrNull();
|
||||||
|
ResultChain entryResult = worldEntryCheckerProvider.forSender(teleporter)
|
||||||
|
.canEnterWorld(mvFromWorld, mvToWorld)
|
||||||
.onSuccessReason(EntryFeeResult.Success.class, reason -> {
|
.onSuccessReason(EntryFeeResult.Success.class, reason -> {
|
||||||
if (reason == EntryFeeResult.Success.ENOUGH_MONEY) {
|
if (teleporter instanceof Player player && reason == EntryFeeResult.Success.ENOUGH_MONEY) {
|
||||||
economist.payEntryFee((Player) teleporter, toWorld);
|
economist.payEntryFee(player, mvToWorld);
|
||||||
// Send payment receipt
|
// Send payment receipt
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -282,29 +263,25 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
getCommandManager().getCommandIssuer(teleporter).sendError(results.getLastResultMessage());
|
getCommandManager().getCommandIssuer(teleporter).sendError(results.getLastResultMessage());
|
||||||
});
|
});
|
||||||
|
|
||||||
Logging.fine("Teleport result: %s", entryResult);
|
Logging.fine("Teleport result: %s", entryResult);
|
||||||
}
|
}).onEmpty(() -> {
|
||||||
|
Logging.fine("Player '%s' is teleporting to world '%s' which is not managed by Multiverse-Core. "
|
||||||
private void stateSuccess(String playerName, String worldName) {
|
+ "No further actions will be taken by Multiverse-Core.",
|
||||||
Logging.fine("MV-Core is allowing Player '" + playerName
|
teleportee.getName(),
|
||||||
+ "' to go to '" + worldName + "'.");
|
toWorld.getName());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called to adjust the portal location to the actual portal location (and not
|
* This method is called to adjust the portal location to the actual portal location (and not
|
||||||
* right outside of it.
|
* right outside of it.
|
||||||
|
*
|
||||||
* @param event The Event that was fired.
|
* @param event The Event that was fired.
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void playerPortalCheck(PlayerPortalEvent event) {
|
public void playerPortalCheck(PlayerPortalEvent event) {
|
||||||
if (event.isCancelled() || event.getFrom() == null) {
|
World fromWorld = event.getFrom().getWorld();
|
||||||
return;
|
if (fromWorld != null && fromWorld.getBlockAt(event.getFrom()).getType() != Material.NETHER_PORTAL) {
|
||||||
}
|
|
||||||
|
|
||||||
// REMEMBER! getTo MAY be NULL HERE!!!
|
|
||||||
// If the player was actually outside of the portal, adjust the from location
|
|
||||||
if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.NETHER_PORTAL) {
|
|
||||||
Location newloc = blockSafety.findPortalBlockNextTo(event.getFrom());
|
Location newloc = blockSafety.findPortalBlockNextTo(event.getFrom());
|
||||||
// TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what
|
// TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what
|
||||||
// TODO: we want to do here.
|
// TODO: we want to do here.
|
||||||
@ -312,71 +289,56 @@ public class MVPlayerListener implements InjectableListener {
|
|||||||
event.setFrom(newloc);
|
event.setFrom(newloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Wait for the adjust, then return!
|
|
||||||
if (event.getTo() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when a player actually portals via a vanilla style portal.
|
* This method is called when a player actually portals via a vanilla style portal.
|
||||||
|
*
|
||||||
* @param event The Event that was fired.
|
* @param event The Event that was fired.
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public void playerPortal(PlayerPortalEvent event) {
|
public void playerPortal(PlayerPortalEvent event) {
|
||||||
if (event.isCancelled() || (event.getFrom() == null)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// The adjust should have happened much earlier.
|
|
||||||
if (event.getTo() == null) {
|
if (event.getTo() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.isUsingCustomPortalSearch()) {
|
if (config.isUsingCustomPortalSearch()) {
|
||||||
event.setSearchRadius(config.getCustomPortalSearchRadius());
|
event.setSearchRadius(config.getCustomPortalSearchRadius());
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadedMultiverseWorld fromWorld = getWorldManager().getLoadedWorld(event.getFrom().getWorld().getName()).getOrNull();
|
if (Objects.equals(event.getFrom().getWorld(), event.getTo().getWorld())) {
|
||||||
LoadedMultiverseWorld toWorld = getWorldManager().getLoadedWorld(event.getTo().getWorld().getName()).getOrNull();
|
|
||||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
|
||||||
// The player is Portaling to the same world.
|
|
||||||
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultChain entryResult = worldEntryCheckerProvider.forSender(event.getPlayer()).canEnterWorld(fromWorld, toWorld)
|
checkPortalTeleportEntry(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPortalTeleportEntry(PlayerPortalEvent event) {
|
||||||
|
getWorldManager().getLoadedWorld(event.getTo().getWorld()).peek(toWorld -> {
|
||||||
|
LoadedMultiverseWorld fromWorld = getWorldManager().getLoadedWorld(event.getFrom().getWorld()).getOrNull();
|
||||||
|
ResultChain entryResult = worldEntryCheckerProvider.forSender(event.getPlayer())
|
||||||
|
.canEnterWorld(fromWorld, toWorld)
|
||||||
.onFailure(results -> {
|
.onFailure(results -> {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
getCommandManager().getCommandIssuer(event.getPlayer()).sendError(results.getLastResultMessage());
|
getCommandManager().getCommandIssuer(event.getPlayer())
|
||||||
|
.sendError(results.getLastResultMessage());
|
||||||
});
|
});
|
||||||
|
|
||||||
Logging.fine("Teleport result: %s", entryResult);
|
Logging.fine("Teleport result: %s", entryResult);
|
||||||
}
|
});
|
||||||
|
|
||||||
private void sendPlayerToDefaultWorld(final Player player, ParsedDestination parsedDestination) {
|
|
||||||
// Remove the player 1 tick after the login. I'm sure there's GOT to be a better way to do this...
|
|
||||||
this.server.getScheduler().scheduleSyncDelayedTask(this.plugin,
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
safetyTeleporter.teleportSafely(player, player, parsedDestination);
|
|
||||||
}
|
|
||||||
}, 1L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the gamemode for the specified {@link Player}.
|
* Handles the gamemode for the specified {@link Player} with a 1 tick delay.
|
||||||
*
|
*
|
||||||
* @param player The {@link Player}.
|
* @param player The {@link Player}.
|
||||||
* @param world The {@link World} the player is supposed to be in.
|
* @param world The {@link World} the player is supposed to be in.
|
||||||
*/
|
*/
|
||||||
private void handleGameModeAndFlight(final Player player, World world) {
|
private void handleGameModeAndFlight(final Player player, World world) {
|
||||||
// We perform this task one tick later to MAKE SURE that the player actually reaches the
|
|
||||||
// destination world, otherwise we'd be changing the player mode if they havent moved anywhere.
|
|
||||||
this.server.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> {
|
|
||||||
if (!player.isOnline() || !player.getWorld().equals(world)) {
|
if (!player.isOnline() || !player.getWorld().equals(world)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enforcementHandler.handleFlightEnforcement(player);
|
enforcementHandler.handleFlightEnforcement(player);
|
||||||
enforcementHandler.handleGameModeEnforcement(player);
|
enforcementHandler.handleGameModeEnforcement(player);
|
||||||
}, 1L);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ package org.mvplugins.multiverse.core.teleportation;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.dumptruckman.minecraft.util.Logging;
|
import com.dumptruckman.minecraft.util.Logging;
|
||||||
|
import io.vavr.control.Option;
|
||||||
import org.jvnet.hk2.annotations.Service;
|
import org.jvnet.hk2.annotations.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -29,15 +29,16 @@ public class TeleportQueue {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to find out who is teleporting a player.
|
* This method is used to find out who is teleporting a player.
|
||||||
|
*
|
||||||
* @param playerName The teleported player (the teleportee).
|
* @param playerName The teleported player (the teleportee).
|
||||||
* @return The player that teleported the other one (the teleporter).
|
* @return The player that teleported the other one (the teleporter).
|
||||||
*/
|
*/
|
||||||
public Optional<String> popFromQueue(String playerName) {
|
public Option<String> popFromQueue(String playerName) {
|
||||||
if (teleportQueue.containsKey(playerName)) {
|
if (teleportQueue.containsKey(playerName)) {
|
||||||
String teleportee = teleportQueue.get(playerName);
|
String teleportee = teleportQueue.get(playerName);
|
||||||
teleportQueue.remove(playerName);
|
teleportQueue.remove(playerName);
|
||||||
return Optional.of(teleportee);
|
return Option.of(teleportee);
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Option.none();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Difficulty;
|
import org.bukkit.Difficulty;
|
||||||
@ -463,8 +464,8 @@ public class MultiverseWorld {
|
|||||||
*
|
*
|
||||||
* @return A world that exists on the server.
|
* @return A world that exists on the server.
|
||||||
*/
|
*/
|
||||||
public @Nullable World getRespawnWorld() {
|
public @Nullable Option<World> getRespawnWorld() {
|
||||||
return Bukkit.getWorld(worldConfig.getRespawnWorld());
|
return Option.of(Bukkit.getWorld(worldConfig.getRespawnWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user