Sync repo files to b22
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
/**
|
||||
* Command to be run.
|
||||
*/
|
||||
public class Command {
|
||||
|
||||
/** The command to execute. */
|
||||
private String command;
|
||||
/** The executor of the command. */
|
||||
private Executor executor = Executor.PLAYER;
|
||||
/** Delay before executing the command (in ticks) */
|
||||
private long delay = 0;
|
||||
|
||||
/**
|
||||
* Default constructor (for bean mapping).
|
||||
*/
|
||||
public Command() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this Command object, setting the given command text on the copy.
|
||||
*
|
||||
* @param command the command text to use in the copy
|
||||
* @return copy of the source with the new command
|
||||
*/
|
||||
public Command copyWithCommand(String command) {
|
||||
Command copy = new Command();
|
||||
setValuesToCopyWithNewCommand(copy, command);
|
||||
return copy;
|
||||
}
|
||||
|
||||
protected void setValuesToCopyWithNewCommand(Command copy, String newCommand) {
|
||||
copy.command = newCommand;
|
||||
copy.executor = this.executor;
|
||||
copy.delay = this.delay;
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
public void setExecutor(Executor executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public long getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public void setDelay(long delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return command + " (" + executor + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Command configuration.
|
||||
*
|
||||
* @see CommandManager
|
||||
*/
|
||||
public class CommandConfig {
|
||||
|
||||
private Map<String, Command> onJoin = new LinkedHashMap<>();
|
||||
private Map<String, OnLoginCommand> onLogin = new LinkedHashMap<>();
|
||||
private Map<String, Command> onSessionLogin = new LinkedHashMap<>();
|
||||
private Map<String, OnLoginCommand> onFirstLogin = new LinkedHashMap<>();
|
||||
private Map<String, Command> onRegister = new LinkedHashMap<>();
|
||||
private Map<String, Command> onUnregister = new LinkedHashMap<>();
|
||||
private Map<String, Command> onLogout = new LinkedHashMap<>();
|
||||
|
||||
public Map<String, Command> getOnJoin() {
|
||||
return onJoin;
|
||||
}
|
||||
|
||||
public void setOnJoin(Map<String, Command> onJoin) {
|
||||
this.onJoin = onJoin;
|
||||
}
|
||||
|
||||
public Map<String, OnLoginCommand> getOnLogin() {
|
||||
return onLogin;
|
||||
}
|
||||
|
||||
public void setOnLogin(Map<String, OnLoginCommand> onLogin) {
|
||||
this.onLogin = onLogin;
|
||||
}
|
||||
|
||||
public Map<String, Command> getOnSessionLogin() {
|
||||
return onSessionLogin;
|
||||
}
|
||||
|
||||
public void setOnSessionLogin(Map<String, Command> onSessionLogin) {
|
||||
this.onSessionLogin = onSessionLogin;
|
||||
}
|
||||
|
||||
public Map<String, OnLoginCommand> getOnFirstLogin() {
|
||||
return onFirstLogin;
|
||||
}
|
||||
|
||||
public void setOnFirstLogin(Map<String, OnLoginCommand> onFirstLogin) {
|
||||
this.onFirstLogin = onFirstLogin;
|
||||
}
|
||||
|
||||
public Map<String, Command> getOnRegister() {
|
||||
return onRegister;
|
||||
}
|
||||
|
||||
public void setOnRegister(Map<String, Command> onRegister) {
|
||||
this.onRegister = onRegister;
|
||||
}
|
||||
|
||||
public Map<String, Command> getOnUnregister() {
|
||||
return onUnregister;
|
||||
}
|
||||
|
||||
public void setOnUnregister(Map<String, Command> onUnregister) {
|
||||
this.onUnregister = onUnregister;
|
||||
}
|
||||
|
||||
public Map<String, Command> getOnLogout() {
|
||||
return onLogout;
|
||||
}
|
||||
|
||||
public void setOnLogout(Map<String, Command> onLogout) {
|
||||
this.onLogout = onLogout;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
import ch.jalu.configme.SettingsManager;
|
||||
import ch.jalu.configme.SettingsManagerBuilder;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.GeoIpService;
|
||||
import fr.xephi.authme.service.yaml.YamlFileResourceProvider;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.PlayerUtils;
|
||||
import fr.xephi.authme.util.lazytags.Tag;
|
||||
import fr.xephi.authme.util.lazytags.WrappedTagReplacer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static fr.xephi.authme.util.lazytags.TagBuilder.createTag;
|
||||
|
||||
/**
|
||||
* Manages configurable commands to be run when various events occur.
|
||||
*/
|
||||
public class CommandManager implements Reloadable {
|
||||
|
||||
private final File dataFolder;
|
||||
private final BukkitService bukkitService;
|
||||
private final GeoIpService geoIpService;
|
||||
private final CommandMigrationService commandMigrationService;
|
||||
private final List<Tag<Player>> availableTags = buildAvailableTags();
|
||||
|
||||
private WrappedTagReplacer<Command, Player> onJoinCommands;
|
||||
private WrappedTagReplacer<OnLoginCommand, Player> onLoginCommands;
|
||||
private WrappedTagReplacer<Command, Player> onSessionLoginCommands;
|
||||
private WrappedTagReplacer<OnLoginCommand, Player> onFirstLoginCommands;
|
||||
private WrappedTagReplacer<Command, Player> onRegisterCommands;
|
||||
private WrappedTagReplacer<Command, Player> onUnregisterCommands;
|
||||
private WrappedTagReplacer<Command, Player> onLogoutCommands;
|
||||
|
||||
@Inject
|
||||
CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, GeoIpService geoIpService,
|
||||
CommandMigrationService commandMigrationService) {
|
||||
this.dataFolder = dataFolder;
|
||||
this.bukkitService = bukkitService;
|
||||
this.geoIpService = geoIpService;
|
||||
this.commandMigrationService = commandMigrationService;
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the configured commands for when a player has joined.
|
||||
*
|
||||
* @param player the joining player
|
||||
*/
|
||||
public void runCommandsOnJoin(Player player) {
|
||||
executeCommands(player, onJoinCommands.getAdaptedItems(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the configured commands for when a player has successfully registered.
|
||||
*
|
||||
* @param player the player who has registered
|
||||
*/
|
||||
public void runCommandsOnRegister(Player player) {
|
||||
executeCommands(player, onRegisterCommands.getAdaptedItems(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the configured commands for when a player has logged in successfully.
|
||||
*
|
||||
* @param player the player that logged in
|
||||
* @param otherAccounts account names whose IP is the same as the player's
|
||||
*/
|
||||
public void runCommandsOnLogin(Player player, List<String> otherAccounts) {
|
||||
final int numberOfOtherAccounts = otherAccounts.size();
|
||||
executeCommands(player, onLoginCommands.getAdaptedItems(player),
|
||||
cmd -> shouldCommandBeRun(cmd, numberOfOtherAccounts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the configured commands for when a player has logged in successfully due to session.
|
||||
*
|
||||
* @param player the player that logged in
|
||||
*/
|
||||
public void runCommandsOnSessionLogin(Player 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
|
||||
* @param otherAccounts account names whose IP is the same as the player's
|
||||
*/
|
||||
public void runCommandsOnFirstLogin(Player player, List<String> otherAccounts) {
|
||||
final int numberOfOtherAccounts = otherAccounts.size();
|
||||
executeCommands(player, onFirstLoginCommands.getAdaptedItems(player),
|
||||
cmd -> shouldCommandBeRun(cmd, numberOfOtherAccounts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the configured commands for when a player has been unregistered.
|
||||
*
|
||||
* @param player the player that has been unregistered
|
||||
*/
|
||||
public void runCommandsOnUnregister(Player 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) {
|
||||
executeCommands(player, commands, c -> true);
|
||||
}
|
||||
|
||||
private <T extends Command> void executeCommands(Player player, List<T> commands, Predicate<T> predicate) {
|
||||
for (T cmd : commands) {
|
||||
if (predicate.test(cmd)) {
|
||||
long delay = cmd.getDelay();
|
||||
if (delay > 0) {
|
||||
bukkitService.scheduleSyncDelayedTask(() -> dispatchCommand(player, cmd), delay);
|
||||
} else {
|
||||
dispatchCommand(player, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchCommand(Player player, Command command) {
|
||||
if (Executor.CONSOLE.equals(command.getExecutor())) {
|
||||
bukkitService.dispatchConsoleCommand(command.getCommand());
|
||||
} else {
|
||||
bukkitService.dispatchCommand(player, command.getCommand());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldCommandBeRun(OnLoginCommand command, int numberOfOtherAccounts) {
|
||||
return (!command.getIfNumberOfAccountsAtLeast().isPresent()
|
||||
|| command.getIfNumberOfAccountsAtLeast().get() <= numberOfOtherAccounts)
|
||||
&& (!command.getIfNumberOfAccountsLessThan().isPresent()
|
||||
|| command.getIfNumberOfAccountsLessThan().get() > numberOfOtherAccounts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
File file = new File(dataFolder, "commands.yml");
|
||||
FileUtils.copyFileFromResource(file, "commands.yml");
|
||||
|
||||
SettingsManager settingsManager = SettingsManagerBuilder
|
||||
.withResource(YamlFileResourceProvider.loadFromFile(file))
|
||||
.configurationData(CommandSettingsHolder.class)
|
||||
.migrationService(commandMigrationService)
|
||||
.create();
|
||||
CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS);
|
||||
onJoinCommands = newReplacer(commandConfig.getOnJoin());
|
||||
onLoginCommands = newOnLoginCmdReplacer(commandConfig.getOnLogin());
|
||||
onFirstLoginCommands = newOnLoginCmdReplacer(commandConfig.getOnFirstLogin());
|
||||
onSessionLoginCommands = newReplacer(commandConfig.getOnSessionLogin());
|
||||
onRegisterCommands = newReplacer(commandConfig.getOnRegister());
|
||||
onUnregisterCommands = newReplacer(commandConfig.getOnUnregister());
|
||||
onLogoutCommands = newReplacer(commandConfig.getOnLogout());
|
||||
}
|
||||
|
||||
private WrappedTagReplacer<Command, Player> newReplacer(Map<String, Command> commands) {
|
||||
return new WrappedTagReplacer<>(availableTags, commands.values(), Command::getCommand,
|
||||
Command::copyWithCommand);
|
||||
}
|
||||
|
||||
private WrappedTagReplacer<OnLoginCommand, Player> newOnLoginCmdReplacer(Map<String, OnLoginCommand> commands) {
|
||||
return new WrappedTagReplacer<>(availableTags, commands.values(), Command::getCommand,
|
||||
OnLoginCommand::copyWithCommand);
|
||||
}
|
||||
|
||||
private List<Tag<Player>> buildAvailableTags() {
|
||||
return Arrays.asList(
|
||||
createTag("%p", Player::getName),
|
||||
createTag("%nick", Player::getDisplayName),
|
||||
createTag("%ip", PlayerUtils::getPlayerIp),
|
||||
createTag("%country", pl -> geoIpService.getCountryName(PlayerUtils.getPlayerIp(pl))));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.migration.MigrationService;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import fr.xephi.authme.settings.SettingsMigrationService;
|
||||
import fr.xephi.authme.util.RandomStringUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Migrates the commands from their old location, in config.yml, to the dedicated commands configuration file.
|
||||
*/
|
||||
class CommandMigrationService implements MigrationService {
|
||||
|
||||
/** List of all properties in {@link CommandConfig}. */
|
||||
@VisibleForTesting
|
||||
static final List<String> COMMAND_CONFIG_PROPERTIES = ImmutableList.of(
|
||||
"onJoin", "onLogin", "onSessionLogin", "onFirstLogin", "onRegister", "onUnregister", "onLogout");
|
||||
|
||||
@Inject
|
||||
private SettingsMigrationService settingsMigrationService;
|
||||
|
||||
CommandMigrationService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkAndMigrate(PropertyReader reader, ConfigurationData configurationData) {
|
||||
final CommandConfig commandConfig = CommandSettingsHolder.COMMANDS.determineValue(reader).getValue();
|
||||
if (moveOtherAccountsConfig(commandConfig) || isAnyCommandMissing(reader)) {
|
||||
configurationData.setValue(CommandSettingsHolder.COMMANDS, commandConfig);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean moveOtherAccountsConfig(CommandConfig commandConfig) {
|
||||
if (settingsMigrationService.hasOldOtherAccountsCommand()) {
|
||||
OnLoginCommand command = new OnLoginCommand();
|
||||
command.setCommand(replaceOldPlaceholdersWithNew(settingsMigrationService.getOldOtherAccountsCommand()));
|
||||
command.setExecutor(Executor.CONSOLE);
|
||||
command.setIfNumberOfAccountsAtLeast(
|
||||
Optional.of(settingsMigrationService.getOldOtherAccountsCommandThreshold()));
|
||||
|
||||
Map<String, OnLoginCommand> onLoginCommands = commandConfig.getOnLogin();
|
||||
onLoginCommands.put(RandomStringUtils.generate(10), command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String replaceOldPlaceholdersWithNew(String oldOtherAccountsCommand) {
|
||||
return oldOtherAccountsCommand
|
||||
.replace("%playername%", "%p")
|
||||
.replace("%playerip%", "%ip");
|
||||
}
|
||||
|
||||
private static boolean isAnyCommandMissing(PropertyReader reader) {
|
||||
return COMMAND_CONFIG_PROPERTIES.stream().anyMatch(property -> reader.getObject(property) == null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.configurationdata.CommentsConfiguration;
|
||||
import ch.jalu.configme.properties.BeanProperty;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
/**
|
||||
* Settings holder class for the commands.yml settings.
|
||||
*/
|
||||
public final class CommandSettingsHolder implements SettingsHolder {
|
||||
|
||||
public static final Property<CommandConfig> COMMANDS =
|
||||
new BeanProperty<>(CommandConfig.class, "", new CommandConfig());
|
||||
|
||||
private CommandSettingsHolder() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerComments(CommentsConfiguration conf) {
|
||||
String[] rootComments = {
|
||||
"This configuration file allows you to execute commands on various events.",
|
||||
"Supported placeholders in commands:",
|
||||
" %p is replaced with the player name.",
|
||||
" %nick is replaced with the player's nick name",
|
||||
" %ip is replaced with the player's IP address",
|
||||
" %country is replaced with the player's country",
|
||||
"",
|
||||
"For example, if you want to send a welcome message to a player who just registered:",
|
||||
"onRegister:",
|
||||
" welcome:",
|
||||
" command: 'msg %p Welcome to the server!'",
|
||||
" executor: CONSOLE",
|
||||
"",
|
||||
"This will make the console execute the msg command to the player.",
|
||||
"Each command under an event has a name you can choose freely (e.g. 'welcome' as above),",
|
||||
"after which a mandatory 'command' field defines the command to run,",
|
||||
"and 'executor' defines who will run the command (either PLAYER or CONSOLE). Longer example:",
|
||||
"onLogin:",
|
||||
" welcome:",
|
||||
" command: 'msg %p Welcome back!'",
|
||||
" executor: PLAYER",
|
||||
" broadcast:",
|
||||
" command: 'broadcast %p has joined, welcome back!'",
|
||||
" executor: CONSOLE",
|
||||
"",
|
||||
"You can also add delay to command. It will run after the specified ticks. Example:",
|
||||
"onLogin:",
|
||||
" rules:",
|
||||
" command: 'rules'",
|
||||
" executor: PLAYER",
|
||||
" delay: 200",
|
||||
"",
|
||||
"Supported command events: onLogin, onSessionLogin, onFirstLogin, onJoin, onLogout, onRegister, "
|
||||
+ "onUnregister",
|
||||
"",
|
||||
"For onLogin and onFirstLogin, you can use 'ifNumberOfAccountsLessThan' and 'ifNumberOfAccountsAtLeast'",
|
||||
"to specify limits to how many accounts a player can have (matched by IP) for a command to be run:",
|
||||
"onLogin:",
|
||||
" warnOnManyAccounts:",
|
||||
" command: 'say Uh oh! %p has many alt accounts!'",
|
||||
" executor: CONSOLE",
|
||||
" ifNumberOfAccountsAtLeast: 5"
|
||||
};
|
||||
|
||||
conf.setComment("", rootComments);
|
||||
conf.setComment("onFirstLogin",
|
||||
"Commands to run for players logging in whose 'last login date' was empty");
|
||||
conf.setComment("onUnregister",
|
||||
"Commands to run whenever a player is unregistered (by himself, or by an admin)");
|
||||
conf.setComment("onLogout",
|
||||
"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!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
/**
|
||||
* The executor of the command.
|
||||
*/
|
||||
public enum Executor {
|
||||
|
||||
/** The player of the event. */
|
||||
PLAYER,
|
||||
|
||||
/** The console user. */
|
||||
CONSOLE
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Configurable command for when a player logs in.
|
||||
*/
|
||||
public class OnLoginCommand extends Command {
|
||||
|
||||
private Optional<Integer> ifNumberOfAccountsAtLeast = Optional.empty();
|
||||
private Optional<Integer> ifNumberOfAccountsLessThan = Optional.empty();
|
||||
|
||||
/**
|
||||
* Default constructor (for bean mapping).
|
||||
*/
|
||||
public OnLoginCommand() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, using the given command as new {@link Command#command command}.
|
||||
*
|
||||
* @param command the command text to use in the copy
|
||||
* @return copy of the source with the new command
|
||||
*/
|
||||
@Override
|
||||
public OnLoginCommand copyWithCommand(String command) {
|
||||
OnLoginCommand copy = new OnLoginCommand();
|
||||
setValuesToCopyWithNewCommand(copy, command);
|
||||
copy.ifNumberOfAccountsAtLeast = this.ifNumberOfAccountsAtLeast;
|
||||
copy.ifNumberOfAccountsLessThan = this.ifNumberOfAccountsLessThan;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public Optional<Integer> getIfNumberOfAccountsAtLeast() {
|
||||
return ifNumberOfAccountsAtLeast;
|
||||
}
|
||||
|
||||
public void setIfNumberOfAccountsAtLeast(Optional<Integer> ifNumberOfAccountsAtLeast) {
|
||||
this.ifNumberOfAccountsAtLeast = ifNumberOfAccountsAtLeast;
|
||||
}
|
||||
|
||||
public Optional<Integer> getIfNumberOfAccountsLessThan() {
|
||||
return ifNumberOfAccountsLessThan;
|
||||
}
|
||||
|
||||
public void setIfNumberOfAccountsLessThan(Optional<Integer> ifNumberOfAccountsLessThan) {
|
||||
this.ifNumberOfAccountsLessThan = ifNumberOfAccountsLessThan;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user