#1113 Handle LimboPlayer tasks via LimboService

- Add methods to LimboService for handling messages to make it the only relevant Limbo class for outside classes
  - Move LimboPlayerTaskManager to limbo package and make it package-private
- Create MessageTask and TimeoutTask immediately when LimboPlayer is created
- #1112 MessageTask: improve efficiency by keeping reference to Player
This commit is contained in:
ljacqu 2017-03-07 20:35:48 +01:00
parent 021497b9e6
commit 4bb10c5d6d
15 changed files with 207 additions and 269 deletions

View File

@ -3,9 +3,9 @@ package fr.xephi.authme.command.executable.captcha;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.CaptchaManager; import fr.xephi.authme.data.CaptchaManager;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
@ -23,7 +23,7 @@ public class CaptchaCommand extends PlayerCommand {
private CommonService commonService; private CommonService commonService;
@Inject @Inject
private LimboPlayerTaskManager limboPlayerTaskManager; private LimboService limboService;
@Override @Override
public void runCommand(Player player, List<String> arguments) { public void runCommand(Player player, List<String> arguments) {
@ -43,7 +43,7 @@ public class CaptchaCommand extends PlayerCommand {
if (isCorrectCode) { if (isCorrectCode) {
commonService.send(player, MessageKey.CAPTCHA_SUCCESS); commonService.send(player, MessageKey.CAPTCHA_SUCCESS);
commonService.send(player, MessageKey.LOGIN_MESSAGE); commonService.send(player, MessageKey.LOGIN_MESSAGE);
limboPlayerTaskManager.unmuteMessageTask(player); limboService.unmuteMessageTask(player);
} else { } else {
String newCode = captchaManager.generateCode(player.getName()); String newCode = captchaManager.generateCode(player.getName());
commonService.send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode); commonService.send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode);

View File

@ -0,0 +1,97 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
/**
* Registers tasks associated with a LimboPlayer.
*/
class LimboPlayerTaskManager {
@Inject
private Messages messages;
@Inject
private Settings settings;
@Inject
private BukkitService bukkitService;
@Inject
private PlayerCache playerCache;
LimboPlayerTaskManager() {
}
/**
* Registers a {@link MessageTask} for the given player name.
*
* @param player the player
* @param limbo the associated limbo player of the player
* @param isRegistered whether the player is registered or not
* (false shows "please register", true shows "please log in")
*/
void registerMessageTask(Player player, LimboPlayer limbo, boolean isRegistered) {
int interval = settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
MessageKey key = getMessageKey(isRegistered);
if (interval > 0) {
MessageTask messageTask = new MessageTask(player, messages.retrieve(key));
bukkitService.runTaskTimer(messageTask, 2 * TICKS_PER_SECOND, interval * TICKS_PER_SECOND);
limbo.setMessageTask(messageTask);
}
}
/**
* Registers a {@link TimeoutTask} for the given player according to the configuration.
*
* @param player the player to register a timeout task for
* @param limbo the associated limbo player
*/
void registerTimeoutTask(Player player, LimboPlayer limbo) {
final int timeout = settings.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
if (timeout > 0) {
String message = messages.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR);
BukkitTask task = bukkitService.runTaskLater(new TimeoutTask(player, message, playerCache), timeout);
limbo.setTimeoutTask(task);
}
}
/**
* Null-safe method to set the muted flag on a message task.
*
* @param task the task to modify (or null)
* @param isMuted the value to set if task is not null
*/
static void setMuted(MessageTask task, boolean isMuted) {
if (task != null) {
task.setMuted(isMuted);
}
}
/**
* Returns the appropriate message key according to the registration status and settings.
*
* @param isRegistered whether or not the username is registered
* @return the message key to display to the user
*/
private static MessageKey getMessageKey(boolean isRegistered) {
if (isRegistered) {
return MessageKey.LOGIN_MESSAGE;
} else {
return MessageKey.REGISTER_MESSAGE;
}
}
}

View File

@ -10,6 +10,7 @@ import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
@ -18,7 +19,7 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
public class LimboService { public class LimboService {
private Map<String, LimboPlayer> entries = new ConcurrentHashMap<>(); private final Map<String, LimboPlayer> entries = new ConcurrentHashMap<>();
@Inject @Inject
private SpawnLoader spawnLoader; private SpawnLoader spawnLoader;
@ -29,6 +30,9 @@ public class LimboService {
@Inject @Inject
private Settings settings; private Settings settings;
@Inject
private LimboPlayerTaskManager taskManager;
LimboService() { LimboService() {
} }
@ -62,6 +66,7 @@ public class LimboService {
player.setWalkSpeed(walkSpeed); player.setWalkSpeed(walkSpeed);
player.setFlySpeed(flySpeed); player.setFlySpeed(flySpeed);
limbo.clearTasks(); limbo.clearTasks();
ConsoleLogger.debug("Restored LimboPlayer stats for `{0}`", lowerName);
} }
} }
@ -89,8 +94,9 @@ public class LimboService {
* Creates a LimboPlayer for the given player and revokes all "limbo data" from the player. * Creates a LimboPlayer for the given player and revokes all "limbo data" from the player.
* *
* @param player the player to process * @param player the player to process
* @param isRegistered whether or not the player is registered
*/ */
public void createLimboPlayer(Player player) { public void createLimboPlayer(Player player, boolean isRegistered) {
final String name = player.getName().toLowerCase(); final String name = player.getName().toLowerCase();
LimboPlayer existingLimbo = entries.remove(name); LimboPlayer existingLimbo = entries.remove(name);
@ -100,10 +106,53 @@ public class LimboService {
} }
LimboPlayer limboPlayer = newLimboPlayer(player); LimboPlayer limboPlayer = newLimboPlayer(player);
taskManager.registerMessageTask(player, limboPlayer, isRegistered);
taskManager.registerTimeoutTask(player, limboPlayer);
revokeLimboStates(player); revokeLimboStates(player);
entries.put(name, limboPlayer); entries.put(name, limboPlayer);
} }
/**
* Creates new tasks for the given player and cancels the old ones for a newly registered player.
* This resets his time to log in (TimeoutTask) and updates the messages he is shown (MessageTask).
*
* @param player the player to reset the tasks for
*/
public void replaceTasksAfterRegistration(Player player) {
getLimboOrLogError(player, "reset tasks")
.ifPresent(limbo -> {
taskManager.registerTimeoutTask(player, limbo);
taskManager.registerMessageTask(player, limbo, true);
});
}
/**
* Resets the message task associated with the player's LimboPlayer.
*
* @param player the player to set a new message task for
* @param isRegistered whether or not the player is registered
*/
public void resetMessageTask(Player player, boolean isRegistered) {
getLimboOrLogError(player, "reset message task")
.ifPresent(limbo -> taskManager.registerMessageTask(player, limbo, isRegistered));
}
/**
* @param player the player whose message task should be muted
*/
public void muteMessageTask(Player player) {
getLimboOrLogError(player, "mute message task")
.ifPresent(limbo -> LimboPlayerTaskManager.setMuted(limbo.getMessageTask(), true));
}
/**
* @param player the player whose message task should be unmuted
*/
public void unmuteMessageTask(Player player) {
getLimboOrLogError(player, "unmute message task")
.ifPresent(limbo -> LimboPlayerTaskManager.setMuted(limbo.getMessageTask(), false));
}
/** /**
* Creates a LimboPlayer with the given player's details. * Creates a LimboPlayer with the given player's details.
* *
@ -143,4 +192,19 @@ public class LimboService {
player.setWalkSpeed(0.0f); player.setWalkSpeed(0.0f);
} }
} }
/**
* Returns the limbo player for the given player or logs an error.
*
* @param player the player to retrieve the limbo player for
* @param context the action for which the limbo player is being retrieved (for logging)
* @return Optional with the limbo player
*/
private Optional<LimboPlayer> getLimboOrLogError(Player player, String context) {
LimboPlayer limbo = entries.get(player.getName().toLowerCase());
if (limbo == null) {
ConsoleLogger.debug("No LimboPlayer found for `{0}`. Action: {1}", player.getName(), context);
}
return Optional.ofNullable(limbo);
}
} }

View File

@ -20,7 +20,6 @@ import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.util.PlayerUtils; import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Server; import org.bukkit.Server;
@ -62,9 +61,6 @@ public class AsynchronousJoin implements AsynchronousProcess {
@Inject @Inject
private BukkitService bukkitService; private BukkitService bukkitService;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
@Inject @Inject
private AsynchronousLogin asynchronousLogin; private AsynchronousLogin asynchronousLogin;
@ -153,9 +149,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> { bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
// TODO #1113: Find an elegant way to deop unregistered players (and disable fly status etc.?) // TODO #1113: Find an elegant way to deop unregistered players (and disable fly status etc.?)
limboService.createLimboPlayer(player); limboService.createLimboPlayer(player, isAuthAvailable);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, isAuthAvailable);
player.setNoDamageTicks(registrationTimeout); player.setNoDamageTicks(registrationTimeout);
if (pluginHookService.isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) { if (pluginHookService.isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) {

View File

@ -6,6 +6,7 @@ import fr.xephi.authme.data.CaptchaManager;
import fr.xephi.authme.data.TempbanManager; import fr.xephi.authme.data.TempbanManager;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent; import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
@ -23,7 +24,6 @@ import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.util.PlayerUtils; import fr.xephi.authme.util.PlayerUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -66,7 +66,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
private TempbanManager tempbanManager; private TempbanManager tempbanManager;
@Inject @Inject
private LimboPlayerTaskManager limboPlayerTaskManager; private LimboService limboService;
AsynchronousLogin() { AsynchronousLogin() {
} }
@ -114,8 +114,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
if (auth == null) { if (auth == null) {
service.send(player, MessageKey.UNKNOWN_USER); service.send(player, MessageKey.UNKNOWN_USER);
// Recreate the message task to immediately send the message again as response // Recreate the message task to immediately send the message again as response
// and to make sure we send the right register message (password vs. email registration) limboService.resetMessageTask(player, false);
limboPlayerTaskManager.registerMessageTask(name, false);
return null; return null;
} }
@ -190,7 +189,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
// If the authentication fails check if Captcha is required and send a message to the player // If the authentication fails check if Captcha is required and send a message to the player
if (captchaManager.isCaptchaRequired(player.getName())) { if (captchaManager.isCaptchaRequired(player.getName())) {
limboPlayerTaskManager.muteMessageTask(player); limboService.muteMessageTask(player);
service.send(player, MessageKey.USAGE_CAPTCHA, service.send(player, MessageKey.USAGE_CAPTCHA,
captchaManager.getCaptchaCodeOrGenerateNew(player.getName())); captchaManager.getCaptchaCodeOrGenerateNew(player.getName()));
} }
@ -241,7 +240,6 @@ public class AsynchronousLogin implements AsynchronousProcess {
// task, we schedule it in the end // task, we schedule it in the end
// so that we can be sure, and have not to care if it might be // so that we can be sure, and have not to care if it might be
// processed in other order. // processed in other order.
limboPlayerTaskManager.clearTasks(player);
syncProcessManager.processSyncPlayerLogin(player); syncProcessManager.processSyncPlayerLogin(player);
} else { } else {
ConsoleLogger.warning("Player '" + player.getName() + "' wasn't online during login process, aborted..."); ConsoleLogger.warning("Player '" + player.getName() + "' wasn't online during login process, aborted...");

View File

@ -7,13 +7,12 @@ import fr.xephi.authme.events.LogoutEvent;
import fr.xephi.authme.listener.protocollib.ProtocolLibService; import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.TeleportationService;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -34,9 +33,6 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
@Inject @Inject
private ProtocolLibService protocolLibService; private ProtocolLibService protocolLibService;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
@Inject @Inject
private LimboService limboService; private LimboService limboService;
@ -59,9 +55,6 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
applyLogoutEffect(player); applyLogoutEffect(player);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, true);
// Player is now logout... Time to fire event ! // Player is now logout... Time to fire event !
bukkitService.callEvent(new LogoutEvent(player)); bukkitService.callEvent(new LogoutEvent(player));
@ -81,7 +74,7 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
} }
// Set player's data to unauthenticated // Set player's data to unauthenticated
limboService.createLimboPlayer(player); limboService.createLimboPlayer(player, true);
service.setGroup(player, AuthGroupType.REGISTERED_UNAUTHENTICATED); service.setGroup(player, AuthGroupType.REGISTERED_UNAUTHENTICATED);
} }

View File

@ -1,11 +1,11 @@
package fr.xephi.authme.process.register; package fr.xephi.authme.process.register;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.util.PlayerUtils; import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -18,7 +18,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
private CommonService service; private CommonService service;
@Inject @Inject
private LimboPlayerTaskManager limboPlayerTaskManager; private LimboService limboService;
ProcessSyncEmailRegister() { ProcessSyncEmailRegister() {
} }
@ -27,9 +27,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
service.setGroup(player, AuthGroupType.REGISTERED_UNAUTHENTICATED); service.setGroup(player, AuthGroupType.REGISTERED_UNAUTHENTICATED);
service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED); service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
final String name = player.getName().toLowerCase(); limboService.replaceTasksAfterRegistration(player);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, true);
player.saveData(); player.saveData();
ConsoleLogger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player)); ConsoleLogger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.process.register; package fr.xephi.authme.process.register;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.process.SynchronousProcess;
@ -9,7 +10,6 @@ import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.commandconfig.CommandManager;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.util.PlayerUtils; import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -26,7 +26,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
private CommonService service; private CommonService service;
@Inject @Inject
private LimboPlayerTaskManager limboPlayerTaskManager; private LimboService limboService;
@Inject @Inject
private CommandManager commandManager; private CommandManager commandManager;
@ -40,9 +40,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
* @param player the player * @param player the player
*/ */
private void requestLogin(Player player) { private void requestLogin(Player player) {
final String name = player.getName().toLowerCase(); limboService.replaceTasksAfterRegistration(player);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, true);
if (player.isInsideVehicle() && player.getVehicle() != null) { if (player.isInsideVehicle() && player.getVehicle() != null) {
player.getVehicle().eject(); player.getVehicle().eject();

View File

@ -15,7 +15,6 @@ import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.TeleportationService; import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
@ -45,9 +44,6 @@ public class AsynchronousUnregister implements AsynchronousProcess {
@Inject @Inject
private LimboService limboService; private LimboService limboService;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
@Inject @Inject
private TeleportationService teleportationService; private TeleportationService teleportationService;
@ -112,10 +108,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
player.saveData(); player.saveData();
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> { bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
limboService.createLimboPlayer(player); limboService.createLimboPlayer(player, false);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, false);
applyBlindEffect(player); applyBlindEffect(player);
}); });
} }

View File

@ -1,131 +0,0 @@
package fr.xephi.authme.task;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
/**
* Registers tasks associated with a LimboPlayer.
*/
public class LimboPlayerTaskManager {
@Inject
private Messages messages;
@Inject
private Settings settings;
@Inject
private BukkitService bukkitService;
@Inject
private LimboService limboService;
@Inject
private PlayerCache playerCache;
LimboPlayerTaskManager() {
}
/**
* Registers a {@link MessageTask} for the given player name.
*
* @param name the name of the player to schedule a repeating message task for
* @param isRegistered whether the name is registered or not
* (false shows "please register", true shows "please log in")
*/
public void registerMessageTask(String name, boolean isRegistered) {
final int interval = settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
final MessageKey key = getMessageKey(isRegistered);
if (interval > 0) {
final LimboPlayer limboPlayer = limboService.getLimboPlayer(name);
if (limboPlayer == null) {
ConsoleLogger.info("LimboPlayer for '" + name + "' is not available (MessageTask)");
} else {
MessageTask messageTask = new MessageTask(name, messages.retrieve(key), bukkitService, playerCache);
bukkitService.runTaskTimer(messageTask, 2 * TICKS_PER_SECOND, interval * TICKS_PER_SECOND);
limboPlayer.setMessageTask(messageTask);
}
}
}
/**
* Registers a {@link TimeoutTask} for the given player according to the configuration.
*
* @param player the player to register a timeout task for
*/
public void registerTimeoutTask(Player player) {
final int timeout = settings.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
if (timeout > 0) {
final LimboPlayer limboPlayer = limboService.getLimboPlayer(player.getName());
if (limboPlayer == null) {
ConsoleLogger.info("LimboPlayer for '" + player.getName() + "' is not available (TimeoutTask)");
} else {
String message = messages.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR);
BukkitTask task = bukkitService.runTaskLater(new TimeoutTask(player, message, playerCache), timeout);
limboPlayer.setTimeoutTask(task);
}
}
}
public void muteMessageTask(Player player) {
LimboPlayer limbo = limboService.getLimboPlayer(player.getName());
if (limbo != null) {
setMuted(limbo.getMessageTask(), true);
}
}
public void unmuteMessageTask(Player player) {
LimboPlayer limbo = limboService.getLimboPlayer(player.getName());
if (limbo != null) {
setMuted(limbo.getMessageTask(), false);
}
}
public void clearTasks(Player player) {
LimboPlayer limbo = limboService.getLimboPlayer(player.getName());
if (limbo != null) {
limbo.clearTasks();
}
}
/**
* Returns the appropriate message key according to the registration status and settings.
*
* @param isRegistered whether or not the username is registered
* @return the message key to display to the user
*/
private MessageKey getMessageKey(boolean isRegistered) {
if (isRegistered) {
return MessageKey.LOGIN_MESSAGE;
} else {
return MessageKey.REGISTER_MESSAGE;
}
}
/**
* Null-safe method to set the muted flag on a message task.
*
* @param task the task to modify (or null)
* @param isMuted the value to set if task is not null
*/
private static void setMuted(MessageTask task, boolean isMuted) {
if (task != null) {
task.setMuted(isMuted);
}
}
}

View File

@ -1,7 +1,5 @@
package fr.xephi.authme.task; package fr.xephi.authme.task;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@ -10,20 +8,16 @@ import org.bukkit.scheduler.BukkitRunnable;
*/ */
public class MessageTask extends BukkitRunnable { public class MessageTask extends BukkitRunnable {
private final String name; private final Player player;
private final String[] message; private final String[] message;
private final BukkitService bukkitService;
private final PlayerCache playerCache;
private boolean isMuted; private boolean isMuted;
/* /*
* Constructor. * Constructor.
*/ */
public MessageTask(String name, String[] lines, BukkitService bukkitService, PlayerCache playerCache) { public MessageTask(Player player, String[] lines) {
this.name = name; this.player = player;
this.message = lines; this.message = lines;
this.bukkitService = bukkitService;
this.playerCache = playerCache;
isMuted = false; isMuted = false;
} }
@ -33,21 +27,8 @@ public class MessageTask extends BukkitRunnable {
@Override @Override
public void run() { public void run() {
if (playerCache.isAuthenticated(name)) { if (!isMuted) {
cancel(); player.sendMessage(message);
}
if (isMuted) {
return;
}
for (Player player : bukkitService.getOnlinePlayers()) {
if (player.getName().equalsIgnoreCase(name)) {
for (String ms : message) {
player.sendMessage(ms);
}
break;
}
} }
} }
} }

View File

@ -2,9 +2,9 @@ package fr.xephi.authme.command.executable.captcha;
import fr.xephi.authme.data.CaptchaManager; import fr.xephi.authme.data.CaptchaManager;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -38,7 +38,7 @@ public class CaptchaCommandTest {
private CommonService commandService; private CommonService commandService;
@Mock @Mock
private LimboPlayerTaskManager limboPlayerTaskManager; private LimboService limboService;
@Test @Test
public void shouldDetectIfPlayerIsLoggedIn() { public void shouldDetectIfPlayerIsLoggedIn() {
@ -90,7 +90,7 @@ public class CaptchaCommandTest {
verifyNoMoreInteractions(captchaManager); verifyNoMoreInteractions(captchaManager);
verify(commandService).send(player, MessageKey.CAPTCHA_SUCCESS); verify(commandService).send(player, MessageKey.CAPTCHA_SUCCESS);
verify(commandService).send(player, MessageKey.LOGIN_MESSAGE); verify(commandService).send(player, MessageKey.LOGIN_MESSAGE);
verify(limboPlayerTaskManager).unmuteMessageTask(player); verify(limboService).unmuteMessageTask(player);
verifyNoMoreInteractions(commandService); verifyNoMoreInteractions(commandService);
} }

View File

@ -1,15 +1,15 @@
package fr.xephi.authme.task; package fr.xephi.authme.data.limbo;
import fr.xephi.authme.TestHelper; import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -51,9 +51,6 @@ public class LimboPlayerTaskManagerTest {
@Mock @Mock
private BukkitService bukkitService; private BukkitService bukkitService;
@Mock
private LimboService limboService;
@Mock @Mock
private PlayerCache playerCache; private PlayerCache playerCache;
@ -65,16 +62,15 @@ public class LimboPlayerTaskManagerTest {
@Test @Test
public void shouldRegisterMessageTask() { public void shouldRegisterMessageTask() {
// given // given
String name = "bobby"; Player player = mock(Player.class);
LimboPlayer limboPlayer = mock(LimboPlayer.class); LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(limboService.getLimboPlayer(name)).willReturn(limboPlayer);
MessageKey key = MessageKey.REGISTER_MESSAGE; MessageKey key = MessageKey.REGISTER_MESSAGE;
given(messages.retrieve(key)).willReturn(new String[]{"Please register!"}); given(messages.retrieve(key)).willReturn(new String[]{"Please register!"});
int interval = 12; int interval = 12;
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(interval); given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(interval);
// when // when
limboPlayerTaskManager.registerMessageTask(name, false); limboPlayerTaskManager.registerMessageTask(player, limboPlayer, false);
// then // then
verify(limboPlayer).setMessageTask(any(MessageTask.class)); verify(limboPlayer).setMessageTask(any(MessageTask.class));
@ -83,32 +79,16 @@ public class LimboPlayerTaskManagerTest {
any(MessageTask.class), eq(2L * TICKS_PER_SECOND), eq((long) interval * TICKS_PER_SECOND)); any(MessageTask.class), eq(2L * TICKS_PER_SECOND), eq((long) interval * TICKS_PER_SECOND));
} }
@Test
public void shouldNotScheduleTaskForMissingLimboPlayer() {
// given
String name = "ghost";
given(limboService.getLimboPlayer(name)).willReturn(null);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(5);
// when
limboPlayerTaskManager.registerMessageTask(name, true);
// then
verify(limboService).getLimboPlayer(name);
verifyZeroInteractions(bukkitService);
verifyZeroInteractions(messages);
}
@Test @Test
public void shouldNotScheduleTaskForZeroAsInterval() { public void shouldNotScheduleTaskForZeroAsInterval() {
// given // given
String name = "Tester1"; Player player = mock(Player.class);
LimboPlayer limboPlayer = mock(LimboPlayer.class); LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(0); given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(0);
// when // when
limboPlayerTaskManager.registerMessageTask(name, true); limboPlayerTaskManager.registerMessageTask(player, limboPlayer, true);
// then // then
verifyZeroInteractions(limboPlayer, bukkitService); verifyZeroInteractions(limboPlayer, bukkitService);
@ -117,16 +97,14 @@ public class LimboPlayerTaskManagerTest {
@Test @Test
public void shouldCancelExistingMessageTask() { public void shouldCancelExistingMessageTask() {
// given // given
Player player = mock(Player.class);
LimboPlayer limboPlayer = new LimboPlayer(null, true, "grp", false, 0.1f, 0.0f); LimboPlayer limboPlayer = new LimboPlayer(null, true, "grp", false, 0.1f, 0.0f);
MessageTask existingMessageTask = mock(MessageTask.class); MessageTask existingMessageTask = mock(MessageTask.class);
limboPlayer.setMessageTask(existingMessageTask); limboPlayer.setMessageTask(existingMessageTask);
String name = "bobby";
given(limboService.getLimboPlayer(name)).willReturn(limboPlayer);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8); given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8);
// when // when
limboPlayerTaskManager.registerMessageTask(name, false); limboPlayerTaskManager.registerMessageTask(player, limboPlayer, false);
// then // then
assertThat(limboPlayer.getMessageTask(), not(nullValue())); assertThat(limboPlayer.getMessageTask(), not(nullValue()));
@ -138,17 +116,14 @@ public class LimboPlayerTaskManagerTest {
@Test @Test
public void shouldRegisterTimeoutTask() { public void shouldRegisterTimeoutTask() {
// given // given
String name = "l33tPlayer";
Player player = mock(Player.class); Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = mock(LimboPlayer.class); LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(limboService.getLimboPlayer(name)).willReturn(limboPlayer);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(30); given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(30);
BukkitTask bukkitTask = mock(BukkitTask.class); BukkitTask bukkitTask = mock(BukkitTask.class);
given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask); given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when // when
limboPlayerTaskManager.registerTimeoutTask(player); limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer);
// then // then
verify(limboPlayer).setTimeoutTask(bukkitTask); verify(limboPlayer).setTimeoutTask(bukkitTask);
@ -156,22 +131,6 @@ public class LimboPlayerTaskManagerTest {
verify(messages).retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR); verify(messages).retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR);
} }
@Test
public void shouldNotRegisterTimeoutTaskForMissingLimboPlayer() {
// given
String name = "Phantom_";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
given(limboService.getLimboPlayer(name)).willReturn(null);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(27);
// when
limboPlayerTaskManager.registerTimeoutTask(player);
// then
verifyZeroInteractions(bukkitService, messages);
}
@Test @Test
public void shouldNotRegisterTimeoutTaskForZeroTimeout() { public void shouldNotRegisterTimeoutTaskForZeroTimeout() {
// given // given
@ -180,7 +139,7 @@ public class LimboPlayerTaskManagerTest {
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0); given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0);
// when // when
limboPlayerTaskManager.registerTimeoutTask(player); limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer);
// then // then
verifyZeroInteractions(limboPlayer, bukkitService); verifyZeroInteractions(limboPlayer, bukkitService);
@ -189,19 +148,16 @@ public class LimboPlayerTaskManagerTest {
@Test @Test
public void shouldCancelExistingTimeoutTask() { public void shouldCancelExistingTimeoutTask() {
// given // given
String name = "l33tPlayer";
Player player = mock(Player.class); Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = new LimboPlayer(null, false, "", true, 0.3f, 0.1f); LimboPlayer limboPlayer = new LimboPlayer(null, false, "", true, 0.3f, 0.1f);
BukkitTask existingTask = mock(BukkitTask.class); BukkitTask existingTask = mock(BukkitTask.class);
limboPlayer.setTimeoutTask(existingTask); limboPlayer.setTimeoutTask(existingTask);
given(limboService.getLimboPlayer(name)).willReturn(limboPlayer);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18); given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);
BukkitTask bukkitTask = mock(BukkitTask.class); BukkitTask bukkitTask = mock(BukkitTask.class);
given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask); given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when // when
limboPlayerTaskManager.registerTimeoutTask(player); limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer);
// then // then
verify(existingTask).cancel(); verify(existingTask).cancel();

View File

@ -3,18 +3,18 @@ package fr.xephi.authme.process.login;
import fr.xephi.authme.TestHelper; import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent; import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -58,7 +58,7 @@ public class AsynchronousLoginTest {
@Mock @Mock
private CommonService commonService; private CommonService commonService;
@Mock @Mock
private LimboPlayerTaskManager limboPlayerTaskManager; private LimboService limboService;
@Mock @Mock
private BukkitService bukkitService; private BukkitService bukkitService;
@Mock @Mock

View File

@ -14,7 +14,6 @@ import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.TeleportationService; import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -54,8 +53,6 @@ public class AsynchronousUnregisterTest {
@Mock @Mock
private LimboService limboService; private LimboService limboService;
@Mock @Mock
private LimboPlayerTaskManager limboPlayerTaskManager;
@Mock
private TeleportationService teleportationService; private TeleportationService teleportationService;
@Mock @Mock
private AuthGroupHandler authGroupHandler; private AuthGroupHandler authGroupHandler;
@ -84,7 +81,7 @@ public class AsynchronousUnregisterTest {
// then // then
verify(service).send(player, MessageKey.WRONG_PASSWORD); verify(service).send(player, MessageKey.WRONG_PASSWORD);
verify(passwordSecurity).comparePassword(userPassword, password, name); verify(passwordSecurity).comparePassword(userPassword, password, name);
verifyZeroInteractions(dataSource, limboPlayerTaskManager, limboService, authGroupHandler, teleportationService); verifyZeroInteractions(dataSource, limboService, authGroupHandler, teleportationService);
verify(player, only()).getName(); verify(player, only()).getName();
} }
@ -170,7 +167,7 @@ public class AsynchronousUnregisterTest {
verify(dataSource).removeAuth(name); verify(dataSource).removeAuth(name);
verify(playerCache).removePlayer(name); verify(playerCache).removePlayer(name);
verify(authGroupHandler).setGroup(player, AuthGroupType.UNREGISTERED); verify(authGroupHandler).setGroup(player, AuthGroupType.UNREGISTERED);
verifyZeroInteractions(teleportationService, limboPlayerTaskManager); verifyZeroInteractions(teleportationService, limboService);
verify(bukkitService, never()).runTask(any(Runnable.class)); verify(bukkitService, never()).runTask(any(Runnable.class));
} }