#1218 Add onLogout to commands.yml

This commit is contained in:
ljacqu 2017-05-21 13:42:49 +02:00
parent 1c46c92b4e
commit 5c6af0330e
11 changed files with 121 additions and 39 deletions

View File

@ -1,8 +1,8 @@
package fr.xephi.authme.process; package fr.xephi.authme.process;
import fr.xephi.authme.process.login.ProcessSyncPlayerLogin; import fr.xephi.authme.process.login.ProcessSyncPlayerLogin;
import fr.xephi.authme.process.logout.ProcessSynchronousPlayerLogout; import fr.xephi.authme.process.logout.ProcessSyncPlayerLogout;
import fr.xephi.authme.process.quit.ProcessSyncronousPlayerQuit; import fr.xephi.authme.process.quit.ProcessSyncPlayerQuit;
import fr.xephi.authme.process.register.ProcessSyncEmailRegister; import fr.xephi.authme.process.register.ProcessSyncEmailRegister;
import fr.xephi.authme.process.register.ProcessSyncPasswordRegister; import fr.xephi.authme.process.register.ProcessSyncPasswordRegister;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -30,29 +30,29 @@ public class SyncProcessManager {
@Inject @Inject
private ProcessSyncPlayerLogin processSyncPlayerLogin; private ProcessSyncPlayerLogin processSyncPlayerLogin;
@Inject @Inject
private ProcessSynchronousPlayerLogout processSynchronousPlayerLogout; private ProcessSyncPlayerLogout processSyncPlayerLogout;
@Inject @Inject
private ProcessSyncronousPlayerQuit processSyncronousPlayerQuit; private ProcessSyncPlayerQuit processSyncPlayerQuit;
public void processSyncEmailRegister(final Player player) { public void processSyncEmailRegister(Player player) {
runTask(() -> processSyncEmailRegister.processEmailRegister(player)); runTask(() -> processSyncEmailRegister.processEmailRegister(player));
} }
public void processSyncPasswordRegister(final Player player) { public void processSyncPasswordRegister(Player player) {
runTask(() -> processSyncPasswordRegister.processPasswordRegister(player)); runTask(() -> processSyncPasswordRegister.processPasswordRegister(player));
} }
public void processSyncPlayerLogout(final Player player) { public void processSyncPlayerLogout(Player player) {
runTask(() -> processSynchronousPlayerLogout.processSyncLogout(player)); runTask(() -> processSyncPlayerLogout.processSyncLogout(player));
} }
public void processSyncPlayerLogin(final Player player) { public void processSyncPlayerLogin(Player player) {
runTask(() -> processSyncPlayerLogin.processPlayerLogin(player)); runTask(() -> processSyncPlayerLogin.processPlayerLogin(player));
} }
public void processSyncPlayerQuit(final Player player) { public void processSyncPlayerQuit(Player player, boolean wasLoggedIn) {
runTask(() -> processSyncronousPlayerQuit.processSyncQuit(player)); runTask(() -> processSyncPlayerQuit.processSyncQuit(player, wasLoggedIn));
} }
private void runTask(Runnable runnable) { private void runTask(Runnable runnable) {

View File

@ -10,6 +10,7 @@ import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService; 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.commandconfig.CommandManager;
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 org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -21,7 +22,7 @@ import javax.inject.Inject;
import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND; import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
public class ProcessSynchronousPlayerLogout implements SynchronousProcess { public class ProcessSyncPlayerLogout implements SynchronousProcess {
@Inject @Inject
private CommonService service; private CommonService service;
@ -41,9 +42,17 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
@Inject @Inject
private TeleportationService teleportationService; private TeleportationService teleportationService;
ProcessSynchronousPlayerLogout() { @Inject
private CommandManager commandManager;
ProcessSyncPlayerLogout() {
} }
/**
* Processes a player which has been logged out.
*
* @param player the player logging out
*/
public void processSyncLogout(Player player) { public void processSyncLogout(Player player) {
final String name = player.getName().toLowerCase(); final String name = player.getName().toLowerCase();
@ -53,6 +62,7 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
} }
applyLogoutEffect(player); applyLogoutEffect(player);
commandManager.runCommandsOnLogout(player);
// 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));

View File

@ -18,6 +18,9 @@ import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
/**
* Async process called when a player quits the server.
*/
public class AsynchronousQuit implements AsynchronousProcess { public class AsynchronousQuit implements AsynchronousProcess {
@Inject @Inject
@ -47,14 +50,19 @@ public class AsynchronousQuit implements AsynchronousProcess {
AsynchronousQuit() { AsynchronousQuit() {
} }
/**
* Processes that the given player has quit the server.
*
* @param player the player who left
*/
public void processQuit(Player player) { public void processQuit(Player player) {
if (player == null || validationService.isUnrestricted(player.getName())) { if (player == null || validationService.isUnrestricted(player.getName())) {
return; return;
} }
final String name = player.getName().toLowerCase(); final String name = player.getName().toLowerCase();
final boolean wasLoggedIn = playerCache.isAuthenticated(name);
if (playerCache.isAuthenticated(name)) { if (wasLoggedIn) {
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) { if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
Location loc = spawnLoader.getPlayerLocationOrSpawn(player); Location loc = spawnLoader.getPlayerLocationOrSpawn(player);
PlayerAuth auth = PlayerAuth.builder() PlayerAuth auth = PlayerAuth.builder()
@ -82,7 +90,7 @@ public class AsynchronousQuit implements AsynchronousProcess {
database.setUnlogged(name); database.setUnlogged(name);
if (plugin.isEnabled()) { if (plugin.isEnabled()) {
syncProcessManager.processSyncPlayerQuit(player); syncProcessManager.processSyncPlayerQuit(player, wasLoggedIn);
} }
// remove player from cache // remove player from cache
if (database instanceof CacheDataSource) { if (database instanceof CacheDataSource) {

View File

@ -0,0 +1,33 @@
package fr.xephi.authme.process.quit;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.settings.commandconfig.CommandManager;
import org.bukkit.entity.Player;
import javax.inject.Inject;
public class ProcessSyncPlayerQuit implements SynchronousProcess {
@Inject
private LimboService limboService;
@Inject
private CommandManager commandManager;
/**
* Processes a player having quit.
*
* @param player the player that left
* @param wasLoggedIn true if the player was logged in when leaving, false otherwise
*/
public void processSyncQuit(Player player, boolean wasLoggedIn) {
if (wasLoggedIn) {
commandManager.runCommandsOnLogout(player);
} else {
limboService.restoreData(player);
}
player.leaveVehicle();
}
}

View File

@ -1,19 +0,0 @@
package fr.xephi.authme.process.quit;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.process.SynchronousProcess;
import org.bukkit.entity.Player;
import javax.inject.Inject;
public class ProcessSyncronousPlayerQuit implements SynchronousProcess {
@Inject
private LimboService limboService;
public void processSyncQuit(Player player) {
limboService.restoreData(player);
player.leaveVehicle();
}
}

View File

@ -15,6 +15,7 @@ public class CommandConfig {
private Map<String, Command> onSessionLogin = new LinkedHashMap<>(); private Map<String, Command> onSessionLogin = new LinkedHashMap<>();
private Map<String, Command> onRegister = new LinkedHashMap<>(); private Map<String, Command> onRegister = new LinkedHashMap<>();
private Map<String, Command> onUnregister = new LinkedHashMap<>(); private Map<String, Command> onUnregister = new LinkedHashMap<>();
private Map<String, Command> onLogout = new LinkedHashMap<>();
public Map<String, Command> getOnJoin() { public Map<String, Command> getOnJoin() {
return onJoin; return onJoin;
@ -55,4 +56,12 @@ public class CommandConfig {
public void setOnUnregister(Map<String, Command> onUnregister) { public void setOnUnregister(Map<String, Command> onUnregister) {
this.onUnregister = onUnregister; this.onUnregister = onUnregister;
} }
public Map<String, Command> getOnLogout() {
return onLogout;
}
public void setOnLogout(Map<String, Command> onLogout) {
this.onLogout = onLogout;
}
} }

View File

@ -36,6 +36,7 @@ public class CommandManager implements Reloadable {
private WrappedTagReplacer<Command, Player> onSessionLoginCommands; private WrappedTagReplacer<Command, Player> onSessionLoginCommands;
private WrappedTagReplacer<Command, Player> onRegisterCommands; private WrappedTagReplacer<Command, Player> onRegisterCommands;
private WrappedTagReplacer<Command, Player> onUnregisterCommands; private WrappedTagReplacer<Command, Player> onUnregisterCommands;
private WrappedTagReplacer<Command, Player> onLogoutCommands;
@Inject @Inject
CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, GeoIpService geoIpService, CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, GeoIpService geoIpService,
@ -93,6 +94,15 @@ public class CommandManager implements Reloadable {
executeCommands(player, onUnregisterCommands.getAdaptedItems(player)); executeCommands(player, onUnregisterCommands.getAdaptedItems(player));
} }
/**
* Runs the configured commands for when a player logs out (by command or by quitting the server).
*
* @param player the player that is no longer logged in
*/
public void runCommandsOnLogout(Player player) {
executeCommands(player, onLogoutCommands.getAdaptedItems(player));
}
private void executeCommands(Player player, List<Command> commands) { private void executeCommands(Player player, List<Command> commands) {
for (Command command : commands) { for (Command command : commands) {
final String execution = command.getCommand(); final String execution = command.getCommand();
@ -117,6 +127,7 @@ public class CommandManager implements Reloadable {
onSessionLoginCommands = newReplacer(commandConfig.getOnSessionLogin()); onSessionLoginCommands = newReplacer(commandConfig.getOnSessionLogin());
onRegisterCommands = newReplacer(commandConfig.getOnRegister()); onRegisterCommands = newReplacer(commandConfig.getOnRegister());
onUnregisterCommands = newReplacer(commandConfig.getOnUnregister()); onUnregisterCommands = newReplacer(commandConfig.getOnUnregister());
onLogoutCommands = newReplacer(commandConfig.getOnLogout());
} }
private WrappedTagReplacer<Command, Player> newReplacer(Map<String, Command> commands) { private WrappedTagReplacer<Command, Player> newReplacer(Map<String, Command> commands) {

View File

@ -48,13 +48,19 @@ public final class CommandSettingsHolder implements SettingsHolder {
" command: 'broadcast %p has joined, welcome back!'", " command: 'broadcast %p has joined, welcome back!'",
" executor: CONSOLE", " executor: CONSOLE",
"", "",
"Supported command events: onLogin, onSessionLogin, onJoin, onRegister, onUnregister" "Supported command events: onLogin, onSessionLogin, onJoin, onLogout, onRegister, onUnregister"
}; };
Map<String, String[]> commentMap = new HashMap<>(); Map<String, String[]> commentMap = new HashMap<>();
commentMap.put("", comments); commentMap.put("", comments);
commentMap.put("onUnregister", new String[]{ commentMap.put("onUnregister", new String[]{
"Commands to run whenever a player is unregistered (by himself, or by an admin)" "Commands to run whenever a player is unregistered (by himself, or by an admin)"
}); });
commentMap.put("onLogout", new String[]{
"These commands are called whenever a logged in player uses /logout or quits.",
"The commands are not run if a player that was not logged in quits the server.",
"Note: if your server crashes, these commands won't be run, so don't rely on them to undo",
"'onLogin' commands that would be dangerous for non-logged in players to have!"
});
return commentMap; return commentMap;
} }

View File

@ -24,10 +24,15 @@
# command: 'broadcast %p has joined, welcome back!' # command: 'broadcast %p has joined, welcome back!'
# executor: CONSOLE # executor: CONSOLE
# #
# Supported command events: onLogin, onSessionLogin, onJoin, onRegister, onUnregister # Supported command events: onLogin, onSessionLogin, onJoin, onLogout, onRegister, onUnregister
onJoin: {} onJoin: {}
onLogin: {} onLogin: {}
onSessionLogin: {} # These commands are called whenever a logged in player uses /logout or quits.
# The commands are not run if a player that was not logged in quits the server.
# Note: if your server crashes, these commands won't be run, so don't rely on them to undo
# 'onLogin' commands that would be dangerous for non-logged in players to have!
onLogout: {}
onRegister: {} onRegister: {}
onSessionLogin: {}
# Commands to run whenever a player is unregistered (by himself, or by an admin) # Commands to run whenever a player is unregistered (by himself, or by an admin)
onUnregister: {} onUnregister: {}

View File

@ -150,6 +150,21 @@ public class CommandManagerTest {
verifyNoMoreInteractions(bukkitService); verifyNoMoreInteractions(bukkitService);
} }
@Test
public void shouldExecuteCommandOnLogout() {
// given
copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.complete.yml");
initManager();
// when
manager.runCommandsOnLogout(player);
// then
verify(bukkitService).dispatchConsoleCommand("broadcast Bobby (127.0.0.3) logged out");
verifyNoMoreInteractions(bukkitService);
verifyZeroInteractions(geoIpService);
}
@Test @Test
public void shouldExecuteCommandsOnRegisterWithIncompleteConfig() { public void shouldExecuteCommandsOnRegisterWithIncompleteConfig() {
// given // given

View File

@ -25,3 +25,7 @@ onSessionLogin:
welcome: welcome:
command: 'msg %p Session login!' command: 'msg %p Session login!'
executor: CONSOLE executor: CONSOLE
onLogout:
announce:
command: 'broadcast %p (%ip) logged out'
executor: CONSOLE