#729 Refactor spawn handling into separate service (work in progress)

This commit is contained in:
ljacqu
2016-06-12 12:46:03 +02:00
parent f0e42b61c5
commit 68d5145cd7
12 changed files with 663 additions and 232 deletions
@@ -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());
}
}
+2 -28
View File
@@ -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);