#1046 Add onFirstLogin to commands.yml

- Allow to configure commands run on player's first login (login of player with a previously null lastlogin date)
This commit is contained in:
ljacqu 2017-11-28 21:41:30 +01:00
parent 7932c1bf90
commit f1c1848985
10 changed files with 65 additions and 10 deletions

View File

@ -47,8 +47,8 @@ public class SyncProcessManager {
runTask(() -> processSyncPlayerLogout.processSyncLogout(player)); runTask(() -> processSyncPlayerLogout.processSyncLogout(player));
} }
public void processSyncPlayerLogin(Player player) { public void processSyncPlayerLogin(Player player, boolean isFirstLogin) {
runTask(() -> processSyncPlayerLogin.processPlayerLogin(player)); runTask(() -> processSyncPlayerLogin.processPlayerLogin(player, isFirstLogin));
} }
public void processSyncPlayerQuit(Player player, boolean wasLoggedIn) { public void processSyncPlayerQuit(Player player, boolean wasLoggedIn) {

View File

@ -220,6 +220,8 @@ public class AsynchronousLogin implements AsynchronousProcess {
*/ */
private void performLogin(Player player, PlayerAuth auth) { private void performLogin(Player player, PlayerAuth auth) {
if (player.isOnline()) { if (player.isOnline()) {
final boolean isFirstLogin = (auth.getLastLogin() == null);
// Update auth to reflect this new login // Update auth to reflect this new login
final String ip = PlayerUtils.getPlayerIp(player); final String ip = PlayerUtils.getPlayerIp(player);
auth.setRealName(player.getName()); auth.setRealName(player.getName());
@ -258,7 +260,7 @@ 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.
syncProcessManager.processSyncPlayerLogin(player); syncProcessManager.processSyncPlayerLogin(player, isFirstLogin);
} 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

@ -62,7 +62,13 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
} }
} }
public void processPlayerLogin(Player player) { /**
* Performs operations in sync mode for a player that has just logged in.
*
* @param player the player that was logged in
* @param isFirstLogin true if this is the first time the player logged in
*/
public void processPlayerLogin(Player player, boolean isFirstLogin) {
final String name = player.getName().toLowerCase(); final String name = player.getName().toLowerCase();
final LimboPlayer limbo = limboService.getLimboPlayer(name); final LimboPlayer limbo = limboService.getLimboPlayer(name);
@ -93,6 +99,9 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
welcomeMessageConfiguration.sendWelcomeMessage(player); welcomeMessageConfiguration.sendWelcomeMessage(player);
// Login is now finished; we can force all commands // Login is now finished; we can force all commands
if (isFirstLogin) {
commandManager.runCommandsOnFirstLogin(player);
}
commandManager.runCommandsOnLogin(player); commandManager.runCommandsOnLogin(player);
// Send Bungee stuff. The service will check if it is enabled or not. // Send Bungee stuff. The service will check if it is enabled or not.

View File

@ -13,6 +13,7 @@ public class CommandConfig {
private Map<String, Command> onJoin = new LinkedHashMap<>(); private Map<String, Command> onJoin = new LinkedHashMap<>();
private Map<String, Command> onLogin = new LinkedHashMap<>(); private Map<String, Command> onLogin = new LinkedHashMap<>();
private Map<String, Command> onSessionLogin = new LinkedHashMap<>(); private Map<String, Command> onSessionLogin = new LinkedHashMap<>();
private Map<String, Command> onFirstLogin = 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<>(); private Map<String, Command> onLogout = new LinkedHashMap<>();
@ -41,6 +42,14 @@ public class CommandConfig {
this.onSessionLogin = onSessionLogin; this.onSessionLogin = onSessionLogin;
} }
public Map<String, Command> getOnFirstLogin() {
return onFirstLogin;
}
public void setOnFirstLogin(Map<String, Command> onFirstLogin) {
this.onFirstLogin = onFirstLogin;
}
public Map<String, Command> getOnRegister() { public Map<String, Command> getOnRegister() {
return onRegister; return onRegister;
} }

View File

@ -34,6 +34,7 @@ public class CommandManager implements Reloadable {
private WrappedTagReplacer<Command, Player> onJoinCommands; private WrappedTagReplacer<Command, Player> onJoinCommands;
private WrappedTagReplacer<Command, Player> onLoginCommands; private WrappedTagReplacer<Command, Player> onLoginCommands;
private WrappedTagReplacer<Command, Player> onSessionLoginCommands; private WrappedTagReplacer<Command, Player> onSessionLoginCommands;
private WrappedTagReplacer<Command, Player> onFirstLoginCommands;
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; private WrappedTagReplacer<Command, Player> onLogoutCommands;
@ -75,7 +76,6 @@ public class CommandManager implements Reloadable {
executeCommands(player, onLoginCommands.getAdaptedItems(player)); executeCommands(player, onLoginCommands.getAdaptedItems(player));
} }
/** /**
* Runs the configured commands for when a player has logged in successfully due to session. * Runs the configured commands for when a player has logged in successfully due to session.
* *
@ -85,6 +85,15 @@ public class CommandManager implements Reloadable {
executeCommands(player, onSessionLoginCommands.getAdaptedItems(player)); executeCommands(player, onSessionLoginCommands.getAdaptedItems(player));
} }
/**
* Runs the configured commands for when a player logs in the first time.
*
* @param player the player that has logged in for the first time
*/
public void runCommandsOnFirstLogin(Player player) {
executeCommands(player, onFirstLoginCommands.getAdaptedItems(player));
}
/** /**
* Runs the configured commands for when a player has been unregistered. * Runs the configured commands for when a player has been unregistered.
* *
@ -124,6 +133,7 @@ public class CommandManager implements Reloadable {
CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS);
onJoinCommands = newReplacer(commandConfig.getOnJoin()); onJoinCommands = newReplacer(commandConfig.getOnJoin());
onLoginCommands = newReplacer(commandConfig.getOnLogin()); onLoginCommands = newReplacer(commandConfig.getOnLogin());
onFirstLoginCommands = newReplacer(commandConfig.getOnFirstLogin());
onSessionLoginCommands = newReplacer(commandConfig.getOnSessionLogin()); onSessionLoginCommands = newReplacer(commandConfig.getOnSessionLogin());
onRegisterCommands = newReplacer(commandConfig.getOnRegister()); onRegisterCommands = newReplacer(commandConfig.getOnRegister());
onUnregisterCommands = newReplacer(commandConfig.getOnUnregister()); onUnregisterCommands = newReplacer(commandConfig.getOnUnregister());

View File

@ -23,7 +23,7 @@ class CommandMigrationService implements MigrationService {
/** List of all properties in {@link CommandConfig}. */ /** List of all properties in {@link CommandConfig}. */
@VisibleForTesting @VisibleForTesting
static final List<String> COMMAND_CONFIG_PROPERTIES = ImmutableList.of( static final List<String> COMMAND_CONFIG_PROPERTIES = ImmutableList.of(
"onJoin", "onLogin", "onSessionLogin", "onRegister", "onUnregister", "onLogout"); "onJoin", "onLogin", "onSessionLogin", "onFirstLogin", "onRegister", "onUnregister", "onLogout");
@Inject @Inject
private SettingsMigrationService settingsMigrationService; private SettingsMigrationService settingsMigrationService;

View File

@ -22,7 +22,7 @@ public final class CommandSettingsHolder implements SettingsHolder {
@SectionComments @SectionComments
public static Map<String, String[]> sectionComments() { public static Map<String, String[]> sectionComments() {
String[] comments = { String[] rootComments = {
"This configuration file allows you to execute commands on various events.", "This configuration file allows you to execute commands on various events.",
"Supported placeholders in commands:", "Supported placeholders in commands:",
" %p is replaced with the player name.", " %p is replaced with the player name.",
@ -48,10 +48,14 @@ 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, onLogout, onRegister, onUnregister" "Supported command events: onLogin, onSessionLogin, onFirstLogin, onJoin, onLogout, onRegister, "
+ "onUnregister"
}; };
Map<String, String[]> commentMap = new HashMap<>(); Map<String, String[]> commentMap = new HashMap<>();
commentMap.put("", comments); commentMap.put("", rootComments);
commentMap.put("onFirstLogin", new String[]{
"Commands to run for players logging in whose 'last login date' was empty"
});
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)"
}); });

View File

@ -24,7 +24,9 @@
# command: 'broadcast %p has joined, welcome back!' # command: 'broadcast %p has joined, welcome back!'
# executor: CONSOLE # executor: CONSOLE
# #
# Supported command events: onLogin, onSessionLogin, onJoin, onLogout, onRegister, onUnregister # Supported command events: onLogin, onSessionLogin, onFirstLogin, onJoin, onLogout, onRegister, onUnregister
# Commands to run for players logging in whose 'last login date' was empty
onFirstLogin: {}
onJoin: {} onJoin: {}
onLogin: {} onLogin: {}
# These commands are called whenever a logged in player uses /logout or quits. # These commands are called whenever a logged in player uses /logout or quits.

View File

@ -107,6 +107,21 @@ public class CommandManagerTest {
verifyZeroInteractions(geoIpService); verifyZeroInteractions(geoIpService);
} }
@Test
public void shouldExecuteCommandsOnFirstLogin() {
// given
copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.complete.yml");
initManager();
// when
manager.runCommandsOnFirstLogin(player);
// then
verify(bukkitService).dispatchConsoleCommand("pay Bobby 30");
verifyNoMoreInteractions(bukkitService);
verifyZeroInteractions(geoIpService);
}
@Test @Test
public void shouldExecuteCommandsOnJoin() { public void shouldExecuteCommandsOnJoin() {
// given // given

View File

@ -25,6 +25,10 @@ onSessionLogin:
welcome: welcome:
command: 'msg %p Session login!' command: 'msg %p Session login!'
executor: CONSOLE executor: CONSOLE
onFirstLogin:
give_money:
command: 'pay %p 30'
executor: CONSOLE
onUnregister: {} onUnregister: {}
onLogout: onLogout:
announce: announce: