#729 Refactor spawn handling into separate service (work in progress)
This commit is contained in:
@@ -4,7 +4,9 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -30,7 +32,7 @@ public class BukkitService {
|
||||
private Method getOnlinePlayers;
|
||||
|
||||
@Inject
|
||||
public BukkitService(AuthMe authMe) {
|
||||
BukkitService(AuthMe authMe) {
|
||||
this.authMe = authMe;
|
||||
getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField();
|
||||
}
|
||||
@@ -167,6 +169,27 @@ public class BukkitService {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls an event with the given details.
|
||||
*
|
||||
* @param event Event details
|
||||
* @throws IllegalStateException Thrown when an asynchronous event is
|
||||
* fired from synchronous code.
|
||||
*/
|
||||
public void callEvent(Event event) {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world with the given name.
|
||||
*
|
||||
* @param name the name of the world to retrieve
|
||||
* @return a world with the given name, or null if none exists
|
||||
*/
|
||||
public World getWorld(String name) {
|
||||
return Bukkit.getWorld(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run upon initialization to verify whether or not the Bukkit implementation
|
||||
* returns the online players as a Collection.
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.events.AbstractTeleportEvent;
|
||||
import fr.xephi.authme.events.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.events.FirstSpawnTeleportEvent;
|
||||
import fr.xephi.authme.events.SpawnTeleportEvent;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN;
|
||||
|
||||
/**
|
||||
* Handles teleportation (placement of player to spawn).
|
||||
*/
|
||||
public class TeleportationService implements Reloadable {
|
||||
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
|
||||
@Inject
|
||||
private Messages messages;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
private Set<String> spawnOnLoginWorlds;
|
||||
|
||||
TeleportationService() { }
|
||||
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void reload() {
|
||||
// Use a Set for better performance with #contains()
|
||||
spawnOnLoginWorlds = new HashSet<>(settings.getProperty(RestrictionSettings.FORCE_SPAWN_ON_WORLDS));
|
||||
}
|
||||
|
||||
public void teleportOnJoin(final Player player) {
|
||||
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||
return;
|
||||
} else if (teleportToFirstSpawn(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN) || mustForceSpawnAfterLogin(player.getWorld())) {
|
||||
teleportToSpawn(player, playerCache.isAuthenticated(player.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public void teleportOnLogin(final Player player, PlayerAuth auth, LimboPlayer limbo) {
|
||||
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mustForceSpawnAfterLogin(player.getWorld())) {
|
||||
teleportToSpawn(player, true);
|
||||
} else if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)) {
|
||||
if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION) && auth.getQuitLocY() != 0) {
|
||||
Location location = buildLocationFromAuth(player, auth);
|
||||
teleportBackFromSpawn(player, location);
|
||||
} else {
|
||||
teleportBackFromSpawn(player, limbo.getLoc());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean teleportToFirstSpawn(final Player player) {
|
||||
if (player.hasPlayedBefore()) {
|
||||
return false;
|
||||
}
|
||||
Location firstSpawn = spawnLoader.getFirstSpawn();
|
||||
if (firstSpawn == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
performTeleportation(player, new FirstSpawnTeleportEvent(player, player.getLocation(), firstSpawn));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isEventValid(AbstractTeleportEvent event) {
|
||||
return !event.isCancelled() && event.getTo() != null && event.getTo().getWorld() != null;
|
||||
}
|
||||
|
||||
private Location buildLocationFromAuth(Player player, PlayerAuth auth) {
|
||||
World world = bukkitService.getWorld(auth.getWorld());
|
||||
if (world == null) {
|
||||
world = player.getWorld();
|
||||
}
|
||||
return new Location(world, auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ());
|
||||
}
|
||||
|
||||
private void teleportBackFromSpawn(final Player player, final Location location) {
|
||||
performTeleportation(player, new AuthMeTeleportEvent(player, location));
|
||||
}
|
||||
|
||||
private void teleportToSpawn(final Player player, final boolean isAuthenticated) {
|
||||
final Location spawnLoc = spawnLoader.getSpawnLocation(player);
|
||||
performTeleportation(player, new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, isAuthenticated));
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the teleportation event and performs teleportation according to it (potentially modified
|
||||
* by external listeners). Note that not teleportation is performed if the event's location is empty.
|
||||
*
|
||||
* @param player the player to teleport
|
||||
* @param event the event to emit and according to which to teleport
|
||||
*/
|
||||
private void performTeleportation(final Player player, final AbstractTeleportEvent event) {
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
bukkitService.callEvent(event);
|
||||
if (player.isOnline() && isEventValid(event)) {
|
||||
player.teleport(event.getTo());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean mustForceSpawnAfterLogin(World world) {
|
||||
return settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)
|
||||
&& spawnOnLoginWorlds.contains(world.getName());
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,8 @@ import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.events.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -117,6 +115,7 @@ public final class Utils {
|
||||
return permsMan.addGroup(player, group);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isUnrestricted(Player player) {
|
||||
// TODO ljacqu 20160602: Checking for Settings.isAllowRestrictedIp is wrong! Nothing in the config suggests
|
||||
// that this setting has anything to do with unrestricted names
|
||||
@@ -124,32 +123,7 @@ public final class Utils {
|
||||
&& Settings.getUnrestrictedName.contains(player.getName().toLowerCase());
|
||||
}
|
||||
|
||||
public static void packCoords(double x, double y, double z, String w, final Player pl) {
|
||||
World theWorld;
|
||||
if (w.equals("unavailableworld")) {
|
||||
theWorld = pl.getWorld();
|
||||
} else {
|
||||
theWorld = Bukkit.getWorld(w);
|
||||
}
|
||||
if (theWorld == null) {
|
||||
theWorld = pl.getWorld();
|
||||
}
|
||||
final World world = theWorld;
|
||||
final Location loc = new Location(world, x, y, z);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(pl, loc);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
pl.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void teleportToSpawn(Player player) {
|
||||
if (Settings.isTeleportToSpawnEnabled && !Settings.noTeleport) {
|
||||
Location spawn = plugin.getSpawnLocation(player);
|
||||
|
||||
Reference in New Issue
Block a user