Remove all files
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import ch.jalu.configme.properties.BaseProperty;
|
||||
import ch.jalu.configme.properties.convertresult.ConvertErrorRecorder;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.collect.Sets.newHashSet;
|
||||
|
||||
/**
|
||||
* Property whose value is a set of entries of a given enum.
|
||||
*
|
||||
* @param <E> the enum type
|
||||
*/
|
||||
public class EnumSetProperty<E extends Enum<E>> extends BaseProperty<Set<E>> {
|
||||
|
||||
private final Class<E> enumClass;
|
||||
|
||||
@SafeVarargs
|
||||
public EnumSetProperty(Class<E> enumClass, String path, E... values) {
|
||||
super(path, newHashSet(values));
|
||||
this.enumClass = enumClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<E> getFromReader(PropertyReader reader, ConvertErrorRecorder errorRecorder) {
|
||||
Object entry = reader.getObject(getPath());
|
||||
if (entry instanceof Collection<?>) {
|
||||
return ((Collection<?>) entry).stream()
|
||||
.map(val -> toEnum(String.valueOf(val)))
|
||||
.filter(e -> e != null)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private E toEnum(String str) {
|
||||
for (E e : enumClass.getEnumConstants()) {
|
||||
if (str.equalsIgnoreCase(e.name())) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toExportValue(Set<E> value) {
|
||||
return value.stream()
|
||||
.map(Enum::name)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import ch.jalu.configme.SettingsManagerImpl;
|
||||
import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.migration.MigrationService;
|
||||
import ch.jalu.configme.resource.PropertyResource;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static fr.xephi.authme.util.FileUtils.copyFileFromResource;
|
||||
|
||||
/**
|
||||
* The AuthMe settings manager.
|
||||
*/
|
||||
public class Settings extends SettingsManagerImpl {
|
||||
|
||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Settings.class);
|
||||
private final File pluginFolder;
|
||||
private String passwordEmailMessage;
|
||||
private String verificationEmailMessage;
|
||||
private String recoveryCodeEmailMessage;
|
||||
private String shutdownEmailMessage;
|
||||
private String newPasswordEmailMessage;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pluginFolder the AuthMe plugin folder
|
||||
* @param resource the property resource to read and write properties to
|
||||
* @param migrationService migration service to check the settings file with
|
||||
* @param configurationData configuration data (properties and comments)
|
||||
*/
|
||||
public Settings(File pluginFolder, PropertyResource resource, MigrationService migrationService,
|
||||
ConfigurationData configurationData) {
|
||||
super(resource, configurationData, migrationService);
|
||||
this.pluginFolder = pluginFolder;
|
||||
loadSettingsFromFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the text to use in email registrations.
|
||||
*
|
||||
* @return The email message
|
||||
*/
|
||||
public String getPasswordEmailMessage() {
|
||||
return passwordEmailMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the text for verification emails (before sensitive commands can be used).
|
||||
*
|
||||
* @return The email message
|
||||
*/
|
||||
public String getVerificationEmailMessage() {
|
||||
return verificationEmailMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the text to use when someone requests to receive a recovery code.
|
||||
*
|
||||
* @return The email message
|
||||
*/
|
||||
public String getRecoveryCodeEmailMessage() {
|
||||
return recoveryCodeEmailMessage;
|
||||
}
|
||||
|
||||
public String getShutdownEmailMessage() {return shutdownEmailMessage;}
|
||||
|
||||
public String getNewPasswordEmailMessage() {
|
||||
return newPasswordEmailMessage;
|
||||
}
|
||||
|
||||
private void loadSettingsFromFiles() {
|
||||
newPasswordEmailMessage = readFile("new_email.html");
|
||||
passwordEmailMessage = readFile("email.html");
|
||||
verificationEmailMessage = readFile("verification_code_email.html");
|
||||
recoveryCodeEmailMessage = readFile("recovery_code_email.html");
|
||||
shutdownEmailMessage = readFile("shutdown.html");
|
||||
String country = readFile("GeoLite2-Country.mmdb");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
loadSettingsFromFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file from the plugin folder or copies it from the JAR to the plugin folder.
|
||||
*
|
||||
* @param filename the file to read
|
||||
* @return the file's contents
|
||||
*/
|
||||
private String readFile(String filename) {
|
||||
final File file = new File(pluginFolder, filename);
|
||||
if (copyFileFromResource(file, filename)) {
|
||||
try {
|
||||
return Files.asCharSource(file, StandardCharsets.UTF_8).read();
|
||||
} catch (IOException e) {
|
||||
logger.logException("Failed to read file '" + filename + "':", e);
|
||||
}
|
||||
} else {
|
||||
logger.warning("Failed to copy file '" + filename + "' from JAR");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,400 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.migration.PlainMigrationService;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import ch.jalu.configme.properties.convertresult.PropertyValue;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.output.LogLevel;
|
||||
import fr.xephi.authme.process.register.RegisterSecondaryArgument;
|
||||
import fr.xephi.authme.process.register.RegistrationType;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
import static fr.xephi.authme.settings.properties.DatabaseSettings.MYSQL_POOL_SIZE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_LEAVE_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_ON_WORLDS;
|
||||
|
||||
/**
|
||||
* Service for verifying that the configuration is up-to-date.
|
||||
*/
|
||||
public class SettingsMigrationService extends PlainMigrationService {
|
||||
|
||||
private static ConsoleLogger logger = ConsoleLoggerFactory.get(SettingsMigrationService.class);
|
||||
private final File pluginFolder;
|
||||
|
||||
// Stores old "other accounts command" config if present.
|
||||
// We need to store it in here for retrieval when we build the CommandConfig. Retrieving it from the config.yml is
|
||||
// not possible since this migration service may trigger the config.yml to be resaved. As the old command settings
|
||||
// don't exist in the code anymore, as soon as config.yml is resaved we lose this information.
|
||||
private String oldOtherAccountsCommand;
|
||||
private int oldOtherAccountsCommandThreshold;
|
||||
|
||||
@Inject
|
||||
SettingsMigrationService(@DataFolder File pluginFolder) {
|
||||
this.pluginFolder = pluginFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("checkstyle:BooleanExpressionComplexity")
|
||||
protected boolean performMigrations(PropertyReader reader, ConfigurationData configurationData) {
|
||||
boolean changes = false;
|
||||
|
||||
if ("[a-zA-Z0-9_?]*".equals(reader.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) {
|
||||
configurationData.setValue(ALLOWED_NICKNAME_CHARACTERS, "[a-zA-Z0-9_]*");
|
||||
changes = true;
|
||||
}
|
||||
|
||||
String driverClass = reader.getString("DataSource.mySQLDriverClassName");
|
||||
if ("fr.xephi.authme.libs.org.mariadb.jdbc.Driver".equals(driverClass)) {
|
||||
configurationData.setValue(DatabaseSettings.BACKEND, DataSourceType.MARIADB);
|
||||
changes = true;
|
||||
}
|
||||
|
||||
setOldOtherAccountsCommandFieldsIfSet(reader);
|
||||
|
||||
// Note ljacqu 20160211: Concatenating migration methods with | instead of the usual ||
|
||||
// ensures that all migrations will be performed
|
||||
return changes
|
||||
| performMailTextToFileMigration(reader)
|
||||
| migrateJoinLeaveMessages(reader, configurationData)
|
||||
| migrateForceSpawnSettings(reader, configurationData)
|
||||
| migratePoolSizeSetting(reader, configurationData)
|
||||
| changeBooleanSettingToLogLevelProperty(reader, configurationData)
|
||||
| hasOldHelpHeaderProperty(reader)
|
||||
| hasSupportOldPasswordProperty(reader)
|
||||
| convertToRegistrationType(reader, configurationData)
|
||||
| mergeAndMovePermissionGroupSettings(reader, configurationData)
|
||||
| moveDeprecatedHashAlgorithmIntoLegacySection(reader, configurationData)
|
||||
| moveSaltColumnConfigWithOtherColumnConfigs(reader, configurationData)
|
||||
|| hasDeprecatedProperties(reader);
|
||||
}
|
||||
|
||||
private static boolean hasDeprecatedProperties(PropertyReader reader) {
|
||||
String[] deprecatedProperties = {
|
||||
"Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications",
|
||||
"Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt",
|
||||
"VeryGames", "settings.restrictions.allowAllCommandsIfRegistrationIsOptional", "DataSource.mySQLWebsite",
|
||||
"Hooks.customAttributes", "Security.stop.kickPlayersBeforeStopping",
|
||||
"settings.restrictions.keepCollisionsDisabled", "settings.forceCommands", "settings.forceCommandsAsConsole",
|
||||
"settings.forceRegisterCommands", "settings.forceRegisterCommandsAsConsole",
|
||||
"settings.sessions.sessionExpireOnIpChange", "settings.restrictions.otherAccountsCmd",
|
||||
"settings.restrictions.otherAccountsCmdThreshold, DataSource.mySQLDriverClassName"};
|
||||
for (String deprecatedPath : deprecatedProperties) {
|
||||
if (reader.contains(deprecatedPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------
|
||||
// Old other accounts
|
||||
// --------
|
||||
public boolean hasOldOtherAccountsCommand() {
|
||||
return !StringUtils.isBlank(oldOtherAccountsCommand);
|
||||
}
|
||||
|
||||
public String getOldOtherAccountsCommand() {
|
||||
return oldOtherAccountsCommand;
|
||||
}
|
||||
|
||||
public int getOldOtherAccountsCommandThreshold() {
|
||||
return oldOtherAccountsCommandThreshold;
|
||||
}
|
||||
|
||||
// --------
|
||||
// Specific migrations
|
||||
// --------
|
||||
|
||||
/**
|
||||
* Check if {@code Email.mailText} is present and move it to the Email.html file if it doesn't exist yet.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @return True if a migration has been completed, false otherwise
|
||||
*/
|
||||
private boolean performMailTextToFileMigration(PropertyReader reader) {
|
||||
final String oldSettingPath = "Email.mailText";
|
||||
final String oldMailText = reader.getString(oldSettingPath);
|
||||
if (oldMailText == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File emailFile = new File(pluginFolder, "email.html");
|
||||
final String mailText = oldMailText
|
||||
.replace("<playername>", "<playername />").replace("%playername%", "<playername />")
|
||||
.replace("<servername>", "<servername />").replace("%servername%", "<servername />")
|
||||
.replace("<generatedpass>", "<generatedpass />").replace("%generatedpass%", "<generatedpass />")
|
||||
.replace("<image>", "<image />").replace("%image%", "<image />");
|
||||
if (!emailFile.exists()) {
|
||||
try (FileWriter fw = new FileWriter(emailFile)) {
|
||||
fw.write(mailText);
|
||||
} catch (IOException e) {
|
||||
logger.logException("Could not create email.html configuration file:", e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect deprecated {@code settings.delayJoinLeaveMessages} and inform user of new "remove join messages"
|
||||
* and "remove leave messages" settings.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean migrateJoinLeaveMessages(PropertyReader reader, ConfigurationData configData) {
|
||||
Property<Boolean> oldDelayJoinProperty = newProperty("settings.delayJoinLeaveMessages", false);
|
||||
boolean hasMigrated = moveProperty(oldDelayJoinProperty, DELAY_JOIN_MESSAGE, reader, configData);
|
||||
|
||||
if (hasMigrated) {
|
||||
logger.info(String.format("Note that we now also have the settings %s and %s",
|
||||
REMOVE_JOIN_MESSAGE.getPath(), REMOVE_LEAVE_MESSAGE.getPath()));
|
||||
}
|
||||
return hasMigrated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects old "force spawn loc on join" and "force spawn on these worlds" settings and moves them
|
||||
* to the new paths.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean migrateForceSpawnSettings(PropertyReader reader, ConfigurationData configData) {
|
||||
Property<Boolean> oldForceLocEnabled = newProperty(
|
||||
"settings.restrictions.ForceSpawnLocOnJoinEnabled", false);
|
||||
Property<List<String>> oldForceWorlds = newListProperty(
|
||||
"settings.restrictions.ForceSpawnOnTheseWorlds", "world", "world_nether", "world_the_ed");
|
||||
|
||||
return moveProperty(oldForceLocEnabled, FORCE_SPAWN_LOCATION_AFTER_LOGIN, reader, configData)
|
||||
| moveProperty(oldForceWorlds, FORCE_SPAWN_ON_WORLDS, reader, configData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the old auto poolSize value and replaces it with the default value.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean migratePoolSizeSetting(PropertyReader reader, ConfigurationData configData) {
|
||||
Integer oldValue = reader.getInt(MYSQL_POOL_SIZE.getPath());
|
||||
if (oldValue == null || oldValue > 0) {
|
||||
return false;
|
||||
}
|
||||
configData.setValue(MYSQL_POOL_SIZE, 10);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the old boolean property "hide spam from console" to the new property specifying
|
||||
* the log level.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean changeBooleanSettingToLogLevelProperty(PropertyReader reader,
|
||||
ConfigurationData configData) {
|
||||
final String oldPath = "Security.console.noConsoleSpam";
|
||||
final Property<LogLevel> newProperty = PluginSettings.LOG_LEVEL;
|
||||
if (!newProperty.isValidInResource(reader) && reader.contains(oldPath)) {
|
||||
logger.info("Moving '" + oldPath + "' to '" + newProperty.getPath() + "'");
|
||||
boolean oldValue = Optional.ofNullable(reader.getBoolean(oldPath)).orElse(false);
|
||||
LogLevel level = oldValue ? LogLevel.INFO : LogLevel.FINE;
|
||||
configData.setValue(newProperty, level);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasOldHelpHeaderProperty(PropertyReader reader) {
|
||||
if (reader.contains("settings.helpHeader")) {
|
||||
logger.warning("Help header setting is now in messages/help_xx.yml, "
|
||||
+ "please check the file to set it again");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasSupportOldPasswordProperty(PropertyReader reader) {
|
||||
String path = "settings.security.supportOldPasswordHash";
|
||||
if (reader.contains(path)) {
|
||||
logger.warning("Property '" + path + "' is no longer supported. "
|
||||
+ "Use '" + SecuritySettings.LEGACY_HASHES.getPath() + "' instead.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts old boolean configurations for registration to the new enum properties, if applicable.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean convertToRegistrationType(PropertyReader reader, ConfigurationData configData) {
|
||||
String oldEmailRegisterPath = "settings.registration.enableEmailRegistrationSystem";
|
||||
if (RegistrationSettings.REGISTRATION_TYPE.isValidInResource(reader)
|
||||
|| !reader.contains(oldEmailRegisterPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean useEmail = newProperty(oldEmailRegisterPath, false).determineValue(reader).getValue();
|
||||
RegistrationType registrationType = useEmail ? RegistrationType.EMAIL : RegistrationType.PASSWORD;
|
||||
|
||||
String useConfirmationPath = useEmail
|
||||
? "settings.registration.doubleEmailCheck"
|
||||
: "settings.restrictions.enablePasswordConfirmation";
|
||||
boolean hasConfirmation = newProperty(useConfirmationPath, false).determineValue(reader).getValue();
|
||||
RegisterSecondaryArgument secondaryArgument = hasConfirmation
|
||||
? RegisterSecondaryArgument.CONFIRMATION
|
||||
: RegisterSecondaryArgument.NONE;
|
||||
|
||||
logger.warning("Merging old registration settings into '"
|
||||
+ RegistrationSettings.REGISTRATION_TYPE.getPath() + "'");
|
||||
configData.setValue(RegistrationSettings.REGISTRATION_TYPE, registrationType);
|
||||
configData.setValue(RegistrationSettings.REGISTER_SECOND_ARGUMENT, secondaryArgument);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates old permission group settings to the new configurations.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean mergeAndMovePermissionGroupSettings(PropertyReader reader, ConfigurationData configData) {
|
||||
boolean performedChanges;
|
||||
|
||||
// We have two old settings replaced by only one: move the first non-empty one
|
||||
Property<String> oldUnloggedInGroup = newProperty("settings.security.unLoggedinGroup", "");
|
||||
Property<String> oldRegisteredGroup = newProperty("GroupOptions.RegisteredPlayerGroup", "");
|
||||
if (!oldUnloggedInGroup.determineValue(reader).getValue().isEmpty()) {
|
||||
performedChanges = moveProperty(oldUnloggedInGroup, PluginSettings.REGISTERED_GROUP, reader, configData);
|
||||
} else {
|
||||
performedChanges = moveProperty(oldRegisteredGroup, PluginSettings.REGISTERED_GROUP, reader, configData);
|
||||
}
|
||||
|
||||
// Move paths of other old options
|
||||
performedChanges |= moveProperty(newProperty("GroupOptions.UnregisteredPlayerGroup", ""),
|
||||
PluginSettings.UNREGISTERED_GROUP, reader, configData);
|
||||
performedChanges |= moveProperty(newProperty("permission.EnablePermissionCheck", false),
|
||||
PluginSettings.ENABLE_PERMISSION_CHECK, reader, configData);
|
||||
return performedChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a deprecated hash is used, it is added to the legacy hashes option and the active hash
|
||||
* is changed to SHA256.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyReader reader,
|
||||
ConfigurationData configData) {
|
||||
HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.determineValue(reader).getValue();
|
||||
// Skip CUSTOM (has no class) and PLAINTEXT (is force-migrated later on in the startup process)
|
||||
if (currentHash != HashAlgorithm.CUSTOM && currentHash != HashAlgorithm.PLAINTEXT) {
|
||||
Class<?> encryptionClass = currentHash.getClazz();
|
||||
if (encryptionClass.isAnnotationPresent(Deprecated.class)) {
|
||||
configData.setValue(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
|
||||
Set<HashAlgorithm> legacyHashes = SecuritySettings.LEGACY_HASHES.determineValue(reader).getValue();
|
||||
legacyHashes.add(currentHash);
|
||||
configData.setValue(SecuritySettings.LEGACY_HASHES, legacyHashes);
|
||||
logger.warning("The hash algorithm '" + currentHash
|
||||
+ "' is no longer supported for active use. New hashes will be in SHA256.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the property for the password salt column name to the same path as all other column name properties.
|
||||
*
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean moveSaltColumnConfigWithOtherColumnConfigs(PropertyReader reader,
|
||||
ConfigurationData configData) {
|
||||
Property<String> oldProperty = newProperty("ExternalBoardOptions.mySQLColumnSalt",
|
||||
DatabaseSettings.MYSQL_COL_SALT.getDefaultValue());
|
||||
return moveProperty(oldProperty, DatabaseSettings.MYSQL_COL_SALT, reader, configData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the old config to run a command when alt accounts are detected and sets them to this instance
|
||||
* for further processing.
|
||||
*
|
||||
* @param reader The property reader
|
||||
*/
|
||||
private void setOldOtherAccountsCommandFieldsIfSet(PropertyReader reader) {
|
||||
Property<String> commandProperty = newProperty("settings.restrictions.otherAccountsCmd", "");
|
||||
Property<Integer> commandThresholdProperty = newProperty("settings.restrictions.otherAccountsCmdThreshold", 0);
|
||||
|
||||
PropertyValue<String> commandPropValue = commandProperty.determineValue(reader);
|
||||
int commandThreshold = commandThresholdProperty.determineValue(reader).getValue();
|
||||
if (commandPropValue.isValidInResource() && commandThreshold >= 2) {
|
||||
oldOtherAccountsCommand = commandPropValue.getValue();
|
||||
oldOtherAccountsCommandThreshold = commandThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for an old property path and moves it to a new path if it is present and the new path is not yet set.
|
||||
*
|
||||
* @param oldProperty The old property (create a temporary {@link Property} object with the path)
|
||||
* @param newProperty The new property to move the value to
|
||||
* @param reader The property reader
|
||||
* @param configData Configuration data
|
||||
* @param <T> The type of the property
|
||||
* @return True if a migration has been done, false otherwise
|
||||
*/
|
||||
protected static <T> boolean moveProperty(Property<T> oldProperty,
|
||||
Property<T> newProperty,
|
||||
PropertyReader reader,
|
||||
ConfigurationData configData) {
|
||||
PropertyValue<T> oldPropertyValue = oldProperty.determineValue(reader);
|
||||
if (oldPropertyValue.isValidInResource()) {
|
||||
if (reader.contains(newProperty.getPath())) {
|
||||
logger.info("Detected deprecated property " + oldProperty.getPath());
|
||||
} else {
|
||||
logger.info("Renaming " + oldProperty.getPath() + " to " + newProperty.getPath());
|
||||
configData.setValue(newProperty, oldPropertyValue.getValue());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.Argon2;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Logs warning messages in cases where the configured values suggest a misconfiguration.
|
||||
* <p>
|
||||
* Note that this class does not modify any settings and it is called after the settings have been fully loaded.
|
||||
* For actual migrations (= verifications which trigger changes and a resave of the settings),
|
||||
* see {@link SettingsMigrationService}.
|
||||
*/
|
||||
public class SettingsWarner {
|
||||
|
||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(SettingsWarner.class);
|
||||
|
||||
@Inject
|
||||
private Settings settings;
|
||||
|
||||
@Inject
|
||||
private AuthMe authMe;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
SettingsWarner() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs warning when necessary to notify the user about misconfigurations.
|
||||
*/
|
||||
public void logWarningsForMisconfigurations() {
|
||||
// Force single session disabled
|
||||
if (!settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)) {
|
||||
logger.warning("WARNING!!! By disabling ForceSingleSession, your server protection is inadequate!");
|
||||
}
|
||||
|
||||
// Use TLS property only affects port 25
|
||||
if (!settings.getProperty(EmailSettings.PORT25_USE_TLS)
|
||||
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
|
||||
logger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25");
|
||||
}
|
||||
|
||||
// Output hint if sessions are enabled that the timeout must be positive
|
||||
if (settings.getProperty(PluginSettings.SESSIONS_ENABLED)
|
||||
&& settings.getProperty(PluginSettings.SESSIONS_TIMEOUT) <= 0) {
|
||||
logger.warning("Warning: Session timeout needs to be positive in order to work!");
|
||||
}
|
||||
|
||||
// Warn if spigot.yml has settings.bungeecord set to true but config.yml has Hooks.bungeecord set to false
|
||||
if (isTrue(bukkitService.isBungeeCordConfiguredForSpigot())
|
||||
&& !settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
logger.warning("Note: Hooks.bungeecord is set to false but your server appears to be running in"
|
||||
+ " bungeecord mode (see your spigot.yml). In order to allow the datasource caching and the"
|
||||
+ " AuthMeBungee add-on to work properly you have to enable this option!");
|
||||
}
|
||||
|
||||
if (!isTrue(bukkitService.isBungeeCordConfiguredForSpigot())
|
||||
&& settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
logger.warning("Note: Hooks.bungeecord is set to true but your server appears to be running in"
|
||||
+ " non-bungeecord mode (see your spigot.yml). In order to prevent untrusted payload attack, "
|
||||
+ "BungeeCord hook will be automatically disabled!");
|
||||
}
|
||||
|
||||
|
||||
// Check if argon2 library is present and can be loaded
|
||||
if (settings.getProperty(SecuritySettings.PASSWORD_HASH).equals(HashAlgorithm.ARGON2)
|
||||
&& !Argon2.isLibraryLoaded()) {
|
||||
logger.warning("WARNING!!! You use Argon2 Hash Algorithm method but we can't find the Argon2 "
|
||||
+ "library on your system! See https://github.com/AuthMe/AuthMeReloaded/wiki/Argon2-as-Password-Hash");
|
||||
authMe.stopOrUnload();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isTrue(Optional<Boolean> value) {
|
||||
return value.isPresent() && value.get();
|
||||
}
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.service.PluginHookService;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Manager for spawn points. It loads spawn definitions from AuthMe and third-party plugins
|
||||
* and is responsible for returning the correct spawn point as per the settings.
|
||||
* <p>
|
||||
* The spawn priority setting defines from which sources and in which order the spawn point
|
||||
* should be taken from. In AuthMe, we can distinguish between the regular spawn and a "first spawn",
|
||||
* to which players will be teleported who have joined for the first time.
|
||||
*/
|
||||
public class SpawnLoader implements Reloadable {
|
||||
|
||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(SpawnLoader.class);
|
||||
|
||||
private final File authMeConfigurationFile;
|
||||
private final Settings settings;
|
||||
private final PluginHookService pluginHookService;
|
||||
private FileConfiguration authMeConfiguration;
|
||||
private String[] spawnPriority;
|
||||
private Location essentialsSpawn;
|
||||
private Location cmiSpawn;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pluginFolder The AuthMe data folder
|
||||
* @param settings The setting instance
|
||||
* @param pluginHookService The plugin hooks instance
|
||||
*/
|
||||
@Inject
|
||||
SpawnLoader(@DataFolder File pluginFolder, Settings settings, PluginHookService pluginHookService) {
|
||||
File spawnFile = new File(pluginFolder, "spawn.yml");
|
||||
FileUtils.copyFileFromResource(spawnFile, "spawn.yml");
|
||||
this.authMeConfigurationFile = spawnFile;
|
||||
this.settings = settings;
|
||||
this.pluginHookService = pluginHookService;
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)loads the spawn file and relevant settings.
|
||||
*/
|
||||
@Override
|
||||
public void reload() {
|
||||
spawnPriority = settings.getProperty(RestrictionSettings.SPAWN_PRIORITY).split(",");
|
||||
authMeConfiguration = YamlConfiguration.loadConfiguration(authMeConfigurationFile);
|
||||
loadEssentialsSpawn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe spawn location.
|
||||
*
|
||||
* @return The location of the regular AuthMe spawn point
|
||||
*/
|
||||
public Location getSpawn() {
|
||||
return getLocationFromConfiguration(authMeConfiguration, "spawn");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the AuthMe spawn point.
|
||||
*
|
||||
* @param location The location to use
|
||||
*
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
public boolean setSpawn(Location location) {
|
||||
return setLocation("spawn", location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe first spawn location.
|
||||
*
|
||||
* @return The location of the AuthMe spawn point for first timers
|
||||
*/
|
||||
public Location getFirstSpawn() {
|
||||
return getLocationFromConfiguration(authMeConfiguration, "firstspawn");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the AuthMe first spawn location.
|
||||
*
|
||||
* @param location The location to use
|
||||
*
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
public boolean setFirstSpawn(Location location) {
|
||||
return setLocation("firstspawn", location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the spawn point defined in EssentialsSpawn.
|
||||
*/
|
||||
public void loadEssentialsSpawn() {
|
||||
// EssentialsSpawn cannot run without Essentials, so it's fine to get the Essentials data folder
|
||||
File essentialsFolder = pluginHookService.getEssentialsDataFolder();
|
||||
if (essentialsFolder == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
File essentialsSpawnFile = new File(essentialsFolder, "spawn.yml");
|
||||
if (essentialsSpawnFile.exists()) {
|
||||
essentialsSpawn = getLocationFromConfiguration(
|
||||
YamlConfiguration.loadConfiguration(essentialsSpawnFile), "spawns.default");
|
||||
} else {
|
||||
essentialsSpawn = null;
|
||||
logger.info("Essentials spawn file not found: '" + essentialsSpawnFile.getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the spawn point defined in EssentialsSpawn.
|
||||
*/
|
||||
public void unloadEssentialsSpawn() {
|
||||
essentialsSpawn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the spawn point defined in CMI.
|
||||
*/
|
||||
public void loadCmiSpawn() {
|
||||
File cmiFolder = pluginHookService.getCmiDataFolder();
|
||||
if (cmiFolder == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
File cmiConfig = new File(cmiFolder, "config.yml");
|
||||
if (cmiConfig.exists()) {
|
||||
cmiSpawn = getLocationFromCmiConfiguration(YamlConfiguration.loadConfiguration(cmiConfig));
|
||||
} else {
|
||||
cmiSpawn = null;
|
||||
logger.info("CMI config file not found: '" + cmiConfig.getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the spawn point defined in CMI.
|
||||
*/
|
||||
public void unloadCmiSpawn() {
|
||||
cmiSpawn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the spawn location for the given player. The source of the spawn location varies
|
||||
* depending on the spawn priority setting.
|
||||
*
|
||||
* @param player The player to retrieve the spawn point for
|
||||
*
|
||||
* @return The spawn location, or the default spawn location upon failure
|
||||
*
|
||||
* @see RestrictionSettings#SPAWN_PRIORITY
|
||||
*/
|
||||
public Location getSpawnLocation(Player player) {
|
||||
if (player == null || player.getWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
World world = player.getWorld();
|
||||
Location spawnLoc = null;
|
||||
for (String priority : spawnPriority) {
|
||||
switch (priority.toLowerCase(Locale.ROOT).trim()) {
|
||||
case "default":
|
||||
if (world.getSpawnLocation() != null) {
|
||||
if (!isValidSpawnPoint(world.getSpawnLocation())) {
|
||||
for (World spawnWorld : Bukkit.getWorlds()) {
|
||||
if (isValidSpawnPoint(spawnWorld.getSpawnLocation())) {
|
||||
world = spawnWorld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
logger.warning("Seems like AuthMe is unable to find a proper spawn location. "
|
||||
+ "Set a location with the command '/authme setspawn'");
|
||||
}
|
||||
spawnLoc = world.getSpawnLocation();
|
||||
}
|
||||
break;
|
||||
case "multiverse":
|
||||
if (settings.getProperty(HooksSettings.MULTIVERSE)) {
|
||||
spawnLoc = pluginHookService.getMultiverseSpawn(world);
|
||||
}
|
||||
break;
|
||||
case "essentials":
|
||||
spawnLoc = essentialsSpawn;
|
||||
break;
|
||||
case "cmi":
|
||||
spawnLoc = cmiSpawn;
|
||||
break;
|
||||
case "authme":
|
||||
spawnLoc = getSpawn();
|
||||
break;
|
||||
default:
|
||||
// ignore
|
||||
}
|
||||
if (spawnLoc != null) {
|
||||
logger.debug("Spawn location determined as `{0}` for world `{1}`", spawnLoc, world.getName());
|
||||
return spawnLoc;
|
||||
}
|
||||
}
|
||||
logger.debug("Fall back to default world spawn location. World: `{0}`", world.getName());
|
||||
|
||||
return world.getSpawnLocation(); // return default location
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given location is a valid spawn point [!= (0,0,0)].
|
||||
*
|
||||
* @param location The location to check
|
||||
*
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
private boolean isValidSpawnPoint(Location location) {
|
||||
if (location.getX() == 0 && location.getY() == 0 && location.getZ() == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the location under the given prefix.
|
||||
*
|
||||
* @param prefix The prefix to save the spawn under
|
||||
* @param location The location to persist
|
||||
*
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
private boolean setLocation(String prefix, Location location) {
|
||||
if (location != null && location.getWorld() != null) {
|
||||
authMeConfiguration.set(prefix + ".world", location.getWorld().getName());
|
||||
authMeConfiguration.set(prefix + ".x", location.getX());
|
||||
authMeConfiguration.set(prefix + ".y", location.getY());
|
||||
authMeConfiguration.set(prefix + ".z", location.getZ());
|
||||
authMeConfiguration.set(prefix + ".yaw", location.getYaw());
|
||||
authMeConfiguration.set(prefix + ".pitch", location.getPitch());
|
||||
return saveAuthMeConfig();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean saveAuthMeConfig() {
|
||||
try {
|
||||
authMeConfiguration.save(authMeConfigurationFile);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
logger.logException("Could not save spawn config (" + authMeConfigurationFile + ")", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return player's location if player is alive, or player's spawn location if dead.
|
||||
*
|
||||
* @param player player to retrieve
|
||||
*
|
||||
* @return location of the given player if alive, spawn location if dead.
|
||||
*/
|
||||
public Location getPlayerLocationOrSpawn(Player player) {
|
||||
if (player.getHealth() <= 0.0) {
|
||||
return getSpawnLocation(player);
|
||||
}
|
||||
return player.getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link Location} object from the given path in the file configuration.
|
||||
*
|
||||
* @param configuration The file configuration to read from
|
||||
* @param pathPrefix The path to get the spawn point from
|
||||
*
|
||||
* @return Location corresponding to the values in the path
|
||||
*/
|
||||
private static Location getLocationFromConfiguration(FileConfiguration configuration, String pathPrefix) {
|
||||
if (containsAllSpawnFields(configuration, pathPrefix)) {
|
||||
String prefix = pathPrefix + ".";
|
||||
String worldName = configuration.getString(prefix + "world");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (!StringUtils.isBlank(worldName) && world != null) {
|
||||
return new Location(world, configuration.getDouble(prefix + "x"),
|
||||
configuration.getDouble(prefix + "y"), configuration.getDouble(prefix + "z"),
|
||||
getFloat(configuration, prefix + "yaw"), getFloat(configuration, prefix + "pitch"));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link Location} object based on the CMI configuration.
|
||||
*
|
||||
* @param configuration The CMI file configuration to read from
|
||||
*
|
||||
* @return Location corresponding to the values in the path
|
||||
*/
|
||||
private static Location getLocationFromCmiConfiguration(FileConfiguration configuration) {
|
||||
final String pathPrefix = "Spawn.Main";
|
||||
if (isLocationCompleteInCmiConfig(configuration, pathPrefix)) {
|
||||
String prefix = pathPrefix + ".";
|
||||
String worldName = configuration.getString(prefix + "World");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (!StringUtils.isBlank(worldName) && world != null) {
|
||||
return new Location(world, configuration.getDouble(prefix + "X"),
|
||||
configuration.getDouble(prefix + "Y"), configuration.getDouble(prefix + "Z"),
|
||||
getFloat(configuration, prefix + "Yaw"), getFloat(configuration, prefix + "Pitch"));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the file configuration contains all fields necessary to define a spawn
|
||||
* under the given path.
|
||||
*
|
||||
* @param configuration The file configuration to use
|
||||
* @param pathPrefix The path to verify
|
||||
*
|
||||
* @return True if all spawn fields are present, false otherwise
|
||||
*/
|
||||
private static boolean containsAllSpawnFields(FileConfiguration configuration, String pathPrefix) {
|
||||
String[] fields = {"world", "x", "y", "z", "yaw", "pitch"};
|
||||
for (String field : fields) {
|
||||
if (!configuration.contains(pathPrefix + "." + field)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the CMI file configuration contains all spawn fields under the given path.
|
||||
*
|
||||
* @param cmiConfiguration The file configuration from CMI
|
||||
* @param pathPrefix The path to verify
|
||||
*
|
||||
* @return True if all spawn fields are present, false otherwise
|
||||
*/
|
||||
private static boolean isLocationCompleteInCmiConfig(FileConfiguration cmiConfiguration, String pathPrefix) {
|
||||
String[] fields = {"World", "X", "Y", "Z", "Yaw", "Pitch"};
|
||||
for (String field : fields) {
|
||||
if (!cmiConfiguration.contains(pathPrefix + "." + field)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a property as a float from the given file configuration.
|
||||
*
|
||||
* @param configuration The file configuration to use
|
||||
* @param path The path of the property to retrieve
|
||||
*
|
||||
* @return The float
|
||||
*/
|
||||
private static float getFloat(FileConfiguration configuration, String path) {
|
||||
Object value = configuration.get(path);
|
||||
// This behavior is consistent with FileConfiguration#getDouble
|
||||
return (value instanceof Number) ? ((Number) value).floatValue() : 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
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 + ")";
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
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))));
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
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!");
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
/**
|
||||
* The executor of the command.
|
||||
*/
|
||||
public enum Executor {
|
||||
|
||||
/** The player of the event. */
|
||||
PLAYER,
|
||||
|
||||
/** The console user. */
|
||||
CONSOLE
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.configurationdata.ConfigurationDataBuilder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
/**
|
||||
* Utility class responsible for retrieving all {@link Property} fields from {@link SettingsHolder} classes.
|
||||
*/
|
||||
public final class AuthMeSettingsRetriever {
|
||||
|
||||
private AuthMeSettingsRetriever() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the configuration data for all property fields in AuthMe {@link SettingsHolder} classes.
|
||||
*
|
||||
* @return configuration data
|
||||
*/
|
||||
public static ConfigurationData buildConfigurationData() {
|
||||
return ConfigurationDataBuilder.createConfiguration(
|
||||
DatabaseSettings.class, PluginSettings.class, RestrictionSettings.class,
|
||||
EmailSettings.class, HooksSettings.class, ProtectionSettings.class,
|
||||
PurgeSettings.class, SecuritySettings.class, RegistrationSettings.class,
|
||||
LimboSettings.class, BackupSettings.class, ConverterSettings.class);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class BackupSettings implements SettingsHolder {
|
||||
|
||||
@Comment("General configuration for backups: if false, no backups are possible")
|
||||
public static final Property<Boolean> ENABLED =
|
||||
newProperty("BackupSystem.ActivateBackup", false);
|
||||
|
||||
@Comment("Create backup at every start of server")
|
||||
public static final Property<Boolean> ON_SERVER_START =
|
||||
newProperty("BackupSystem.OnServerStart", false);
|
||||
|
||||
@Comment("Create backup at every stop of server")
|
||||
public static final Property<Boolean> ON_SERVER_STOP =
|
||||
newProperty("BackupSystem.OnServerStop", true);
|
||||
|
||||
@Comment("Windows only: MySQL installation path")
|
||||
public static final Property<String> MYSQL_WINDOWS_PATH =
|
||||
newProperty("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||
|
||||
private BackupSettings() {
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.configurationdata.CommentsConfiguration;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class ConverterSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Rakamak file name")
|
||||
public static final Property<String> RAKAMAK_FILE_NAME =
|
||||
newProperty("Converter.Rakamak.fileName", "users.rak");
|
||||
|
||||
@Comment("Rakamak use IP?")
|
||||
public static final Property<Boolean> RAKAMAK_USE_IP =
|
||||
newProperty("Converter.Rakamak.useIP", false);
|
||||
|
||||
@Comment("Rakamak IP file name")
|
||||
public static final Property<String> RAKAMAK_IP_FILE_NAME =
|
||||
newProperty("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
|
||||
@Comment("CrazyLogin database file name")
|
||||
public static final Property<String> CRAZYLOGIN_FILE_NAME =
|
||||
newProperty("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
|
||||
@Comment("LoginSecurity: convert from SQLite; if false we use MySQL")
|
||||
public static final Property<Boolean> LOGINSECURITY_USE_SQLITE =
|
||||
newProperty("Converter.loginSecurity.useSqlite", true);
|
||||
|
||||
@Comment("LoginSecurity MySQL: database host")
|
||||
public static final Property<String> LOGINSECURITY_MYSQL_HOST =
|
||||
newProperty("Converter.loginSecurity.mySql.host", "");
|
||||
|
||||
@Comment("LoginSecurity MySQL: database name")
|
||||
public static final Property<String> LOGINSECURITY_MYSQL_DATABASE =
|
||||
newProperty("Converter.loginSecurity.mySql.database", "");
|
||||
|
||||
@Comment("LoginSecurity MySQL: database user")
|
||||
public static final Property<String> LOGINSECURITY_MYSQL_USER =
|
||||
newProperty("Converter.loginSecurity.mySql.user", "");
|
||||
|
||||
@Comment("LoginSecurity MySQL: password for database user")
|
||||
public static final Property<String> LOGINSECURITY_MYSQL_PASSWORD =
|
||||
newProperty("Converter.loginSecurity.mySql.password", "");
|
||||
|
||||
private ConverterSettings() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerComments(CommentsConfiguration conf) {
|
||||
conf.setComment("Converter",
|
||||
"Converter settings: see https://github.com/AuthMe/AuthMeReloaded/wiki/Converters");
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class DatabaseSettings implements SettingsHolder {
|
||||
|
||||
@Comment({"What type of database do you want to use?",
|
||||
"Valid values: SQLITE, MARIADB, MYSQL, POSTGRESQL"})
|
||||
public static final Property<DataSourceType> BACKEND =
|
||||
newProperty(DataSourceType.class, "DataSource.backend", DataSourceType.SQLITE);
|
||||
|
||||
@Comment({"Enable the database caching system, should be disabled on bungeecord environments",
|
||||
"or when a website integration is being used."})
|
||||
public static final Property<Boolean> USE_CACHING =
|
||||
newProperty("DataSource.caching", true);
|
||||
|
||||
@Comment("Database host address")
|
||||
public static final Property<String> MYSQL_HOST =
|
||||
newProperty("DataSource.mySQLHost", "127.0.0.1");
|
||||
|
||||
@Comment("Database port")
|
||||
public static final Property<String> MYSQL_PORT =
|
||||
newProperty("DataSource.mySQLPort", "3306");
|
||||
|
||||
@Comment("Connect to MySQL database over SSL")
|
||||
public static final Property<Boolean> MYSQL_USE_SSL =
|
||||
newProperty("DataSource.mySQLUseSSL", true);
|
||||
|
||||
@Comment({"Verification of server's certificate.",
|
||||
"We would not recommend to set this option to false.",
|
||||
"Set this option to false at your own risk if and only if you know what you're doing"})
|
||||
public static final Property<Boolean> MYSQL_CHECK_SERVER_CERTIFICATE =
|
||||
newProperty( "DataSource.mySQLCheckServerCertificate", true );
|
||||
|
||||
@Comment({"Authorize client to retrieve RSA server public key.",
|
||||
"Advanced option, ignore if you don't know what it means."})
|
||||
public static final Property<Boolean> MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL =
|
||||
newProperty( "DataSource.mySQLAllowPublicKeyRetrieval", true );
|
||||
|
||||
@Comment("Username to connect to the MySQL database")
|
||||
public static final Property<String> MYSQL_USERNAME =
|
||||
newProperty("DataSource.mySQLUsername", "authme");
|
||||
|
||||
@Comment("Password to connect to the MySQL database")
|
||||
public static final Property<String> MYSQL_PASSWORD =
|
||||
newProperty("DataSource.mySQLPassword", "12345");
|
||||
|
||||
@Comment("Database Name, use with converters or as SQLITE database name")
|
||||
public static final Property<String> MYSQL_DATABASE =
|
||||
newProperty("DataSource.mySQLDatabase", "authme");
|
||||
|
||||
@Comment("Table of the database")
|
||||
public static final Property<String> MYSQL_TABLE =
|
||||
newProperty("DataSource.mySQLTablename", "authme");
|
||||
|
||||
@Comment("Column of IDs to sort data")
|
||||
public static final Property<String> MYSQL_COL_ID =
|
||||
newProperty("DataSource.mySQLColumnId", "id");
|
||||
|
||||
@Comment("Column for storing or checking players nickname")
|
||||
public static final Property<String> MYSQL_COL_NAME =
|
||||
newProperty("DataSource.mySQLColumnName", "username");
|
||||
|
||||
@Comment("Column for storing or checking players RealName")
|
||||
public static final Property<String> MYSQL_COL_REALNAME =
|
||||
newProperty("DataSource.mySQLRealName", "realname");
|
||||
|
||||
@Comment("Column for storing players passwords")
|
||||
public static final Property<String> MYSQL_COL_PASSWORD =
|
||||
newProperty("DataSource.mySQLColumnPassword", "password");
|
||||
|
||||
@Comment("Column for storing players passwords salts")
|
||||
public static final Property<String> MYSQL_COL_SALT =
|
||||
newProperty("DataSource.mySQLColumnSalt", "");
|
||||
|
||||
@Comment("Column for storing players emails")
|
||||
public static final Property<String> MYSQL_COL_EMAIL =
|
||||
newProperty("DataSource.mySQLColumnEmail", "email");
|
||||
|
||||
@Comment("Column for storing if a player is logged in or not")
|
||||
public static final Property<String> MYSQL_COL_ISLOGGED =
|
||||
newProperty("DataSource.mySQLColumnLogged", "isLogged");
|
||||
|
||||
@Comment("Column for storing if a player has a valid session or not")
|
||||
public static final Property<String> MYSQL_COL_HASSESSION =
|
||||
newProperty("DataSource.mySQLColumnHasSession", "hasSession");
|
||||
|
||||
@Comment("Column for storing a player's TOTP key (for two-factor authentication)")
|
||||
public static final Property<String> MYSQL_COL_TOTP_KEY =
|
||||
newProperty("DataSource.mySQLtotpKey", "totp");
|
||||
|
||||
@Comment("Column for storing the player's last IP")
|
||||
public static final Property<String> MYSQL_COL_LAST_IP =
|
||||
newProperty("DataSource.mySQLColumnIp", "ip");
|
||||
|
||||
@Comment("Column for storing players lastlogins")
|
||||
public static final Property<String> MYSQL_COL_LASTLOGIN =
|
||||
newProperty("DataSource.mySQLColumnLastLogin", "lastlogin");
|
||||
|
||||
@Comment("Column storing the registration date")
|
||||
public static final Property<String> MYSQL_COL_REGISTER_DATE =
|
||||
newProperty("DataSource.mySQLColumnRegisterDate", "regdate");
|
||||
|
||||
@Comment("Column for storing the IP address at the time of registration")
|
||||
public static final Property<String> MYSQL_COL_REGISTER_IP =
|
||||
newProperty("DataSource.mySQLColumnRegisterIp", "regip");
|
||||
|
||||
@Comment("Column for storing player LastLocation - X")
|
||||
public static final Property<String> MYSQL_COL_LASTLOC_X =
|
||||
newProperty("DataSource.mySQLlastlocX", "x");
|
||||
|
||||
@Comment("Column for storing player LastLocation - Y")
|
||||
public static final Property<String> MYSQL_COL_LASTLOC_Y =
|
||||
newProperty("DataSource.mySQLlastlocY", "y");
|
||||
|
||||
@Comment("Column for storing player LastLocation - Z")
|
||||
public static final Property<String> MYSQL_COL_LASTLOC_Z =
|
||||
newProperty("DataSource.mySQLlastlocZ", "z");
|
||||
|
||||
@Comment("Column for storing player LastLocation - World Name")
|
||||
public static final Property<String> MYSQL_COL_LASTLOC_WORLD =
|
||||
newProperty("DataSource.mySQLlastlocWorld", "world");
|
||||
|
||||
@Comment("Column for storing player LastLocation - Yaw")
|
||||
public static final Property<String> MYSQL_COL_LASTLOC_YAW =
|
||||
newProperty("DataSource.mySQLlastlocYaw", "yaw");
|
||||
|
||||
@Comment("Column for storing player LastLocation - Pitch")
|
||||
public static final Property<String> MYSQL_COL_LASTLOC_PITCH =
|
||||
newProperty("DataSource.mySQLlastlocPitch", "pitch");
|
||||
|
||||
@Comment("Column for storing players uuids (optional)")
|
||||
public static final Property<String> MYSQL_COL_PLAYER_UUID =
|
||||
newProperty( "DataSource.mySQLPlayerUUID", "" );
|
||||
|
||||
@Comment("Column for storing players groups")
|
||||
public static final Property<String> MYSQL_COL_GROUP =
|
||||
newProperty("ExternalBoardOptions.mySQLColumnGroup", "");
|
||||
|
||||
@Comment("Overrides the size of the DB Connection Pool, default = 10")
|
||||
public static final Property<Integer> MYSQL_POOL_SIZE =
|
||||
newProperty("DataSource.poolSize", 10);
|
||||
|
||||
@Comment({"The maximum lifetime of a connection in the pool, default = 1800 seconds",
|
||||
"You should set this at least 30 seconds less than mysql server wait_timeout"})
|
||||
public static final Property<Integer> MYSQL_CONNECTION_MAX_LIFETIME =
|
||||
newProperty("DataSource.maxLifetime", 1800);
|
||||
|
||||
private DatabaseSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class EmailSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Email SMTP server host")
|
||||
public static final Property<String> SMTP_HOST =
|
||||
newProperty("Email.mailSMTP", "smtp.163.com");
|
||||
|
||||
@Comment("Email SMTP server port")
|
||||
public static final Property<Integer> SMTP_PORT =
|
||||
newProperty("Email.mailPort", 465);
|
||||
|
||||
@Comment("Only affects port 25: enable TLS/STARTTLS?")
|
||||
public static final Property<Boolean> PORT25_USE_TLS =
|
||||
newProperty("Email.useTls", true);
|
||||
|
||||
@Comment("Email account which sends the mails")
|
||||
public static final Property<String> MAIL_ACCOUNT =
|
||||
newProperty("Email.mailAccount", "");
|
||||
|
||||
@Comment("Email account password")
|
||||
public static final Property<String> MAIL_PASSWORD =
|
||||
newProperty("Email.mailPassword", "");
|
||||
|
||||
@Comment("Email address, fill when mailAccount is not the email address of the account")
|
||||
public static final Property<String> MAIL_ADDRESS =
|
||||
newProperty("Email.mailAddress", "");
|
||||
|
||||
@Comment("Custom sender name, replacing the mailAccount name in the email")
|
||||
public static final Property<String> MAIL_SENDER_NAME =
|
||||
newProperty("Email.mailSenderName", "");
|
||||
|
||||
@Comment("Recovery password length")
|
||||
public static final Property<Integer> RECOVERY_PASSWORD_LENGTH =
|
||||
newProperty("Email.RecoveryPasswordLength", 12);
|
||||
|
||||
@Comment("Mail Subject")
|
||||
public static final Property<String> RECOVERY_MAIL_SUBJECT =
|
||||
newProperty("Email.mailSubject", "Your new AuthMe password");
|
||||
|
||||
@Comment("Like maxRegPerIP but with email")
|
||||
public static final Property<Integer> MAX_REG_PER_EMAIL =
|
||||
newProperty("Email.maxRegPerEmail", 1);
|
||||
|
||||
@Comment("Recall players to add an email?")
|
||||
public static final Property<Boolean> RECALL_PLAYERS =
|
||||
newProperty("Email.recallPlayers", false);
|
||||
|
||||
@Comment("Delay in minute for the recall scheduler")
|
||||
public static final Property<Integer> DELAY_RECALL =
|
||||
newProperty("Email.delayRecall", 5);
|
||||
|
||||
@Comment("Send the new password drawn in an image?")
|
||||
public static final Property<Boolean> PASSWORD_AS_IMAGE =
|
||||
newProperty("Email.generateImage", false);
|
||||
|
||||
@Comment("The OAuth2 token")
|
||||
public static final Property<String> OAUTH2_TOKEN =
|
||||
newProperty("Email.emailOauth2Token", "");
|
||||
@Comment("Email notifications when the server shuts down")
|
||||
public static final Property<Boolean> SHUTDOWN_MAIL =
|
||||
newProperty("Email.shutDownEmail", false);
|
||||
@Comment("Email notification address when the server is shut down")
|
||||
public static final Property<String> SHUTDOWN_MAIL_ADDRESS =
|
||||
newProperty("Email.shutDownEmailAddress", "your@mail.com");
|
||||
|
||||
private EmailSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class HooksSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Do we need to hook with multiverse for spawn checking?")
|
||||
public static final Property<Boolean> MULTIVERSE =
|
||||
newProperty("Hooks.multiverse", true);
|
||||
|
||||
@Comment("Do we need to hook with BungeeCord?")
|
||||
public static final Property<Boolean> BUNGEECORD =
|
||||
newProperty("Hooks.bungeecord", false);
|
||||
|
||||
@Comment("Allow FloodGatePlayer Join Without checkIsValidName()")
|
||||
public static final Property<Boolean> HOOK_FLOODGATE_PLAYER =
|
||||
newProperty("Hooks.floodgate", false);
|
||||
|
||||
|
||||
@Comment("Send player to this BungeeCord server after register/login")
|
||||
public static final Property<String> BUNGEECORD_SERVER =
|
||||
newProperty("Hooks.sendPlayerTo", "");
|
||||
|
||||
@Comment("Do we need to disable Essentials SocialSpy on join?")
|
||||
public static final Property<Boolean> DISABLE_SOCIAL_SPY =
|
||||
newProperty("Hooks.disableSocialSpy", false);
|
||||
|
||||
@Comment("Do we need to force /motd Essentials command on join?")
|
||||
public static final Property<Boolean> USE_ESSENTIALS_MOTD =
|
||||
newProperty("Hooks.useEssentialsMotd", false);
|
||||
|
||||
@Comment({
|
||||
"-1 means disabled. If you want that only activated players",
|
||||
"can log into your server, you can set here the group number",
|
||||
"of unactivated users, needed for some forum/CMS support"})
|
||||
public static final Property<Integer> NON_ACTIVATED_USERS_GROUP =
|
||||
newProperty("ExternalBoardOptions.nonActivedUserGroup", -1);
|
||||
|
||||
@Comment("Other MySQL columns where we need to put the username (case-sensitive)")
|
||||
public static final Property<List<String>> MYSQL_OTHER_USERNAME_COLS =
|
||||
newListProperty("ExternalBoardOptions.mySQLOtherUsernameColumns");
|
||||
|
||||
@Comment("How much log2 rounds needed in BCrypt (do not change if you do not know what it does)")
|
||||
public static final Property<Integer> BCRYPT_LOG2_ROUND =
|
||||
newProperty("ExternalBoardOptions.bCryptLog2Round", 12);
|
||||
|
||||
@Comment("phpBB table prefix defined during the phpBB installation process")
|
||||
public static final Property<String> PHPBB_TABLE_PREFIX =
|
||||
newProperty("ExternalBoardOptions.phpbbTablePrefix", "phpbb_");
|
||||
|
||||
@Comment("phpBB activated group ID; 2 is the default registered group defined by phpBB")
|
||||
public static final Property<Integer> PHPBB_ACTIVATED_GROUP_ID =
|
||||
newProperty("ExternalBoardOptions.phpbbActivatedGroupId", 2);
|
||||
|
||||
@Comment("IP Board table prefix defined during the IP Board installation process")
|
||||
public static final Property<String> IPB_TABLE_PREFIX =
|
||||
newProperty("ExternalBoardOptions.IPBTablePrefix", "ipb_");
|
||||
|
||||
@Comment("IP Board default group ID; 3 is the default registered group defined by IP Board")
|
||||
public static final Property<Integer> IPB_ACTIVATED_GROUP_ID =
|
||||
newProperty("ExternalBoardOptions.IPBActivatedGroupId", 3);
|
||||
|
||||
@Comment("Xenforo table prefix defined during the Xenforo installation process")
|
||||
public static final Property<String> XF_TABLE_PREFIX =
|
||||
newProperty("ExternalBoardOptions.XFTablePrefix", "xf_");
|
||||
|
||||
@Comment("XenForo default group ID; 2 is the default registered group defined by Xenforo")
|
||||
public static final Property<Integer> XF_ACTIVATED_GROUP_ID =
|
||||
newProperty("ExternalBoardOptions.XFActivatedGroupId", 2);
|
||||
|
||||
@Comment("Wordpress prefix defined during WordPress installation")
|
||||
public static final Property<String> WORDPRESS_TABLE_PREFIX =
|
||||
newProperty("ExternalBoardOptions.wordpressTablePrefix", "wp_");
|
||||
|
||||
|
||||
private HooksSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.configurationdata.CommentsConfiguration;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import fr.xephi.authme.data.limbo.AllowFlightRestoreType;
|
||||
import fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType;
|
||||
import fr.xephi.authme.data.limbo.persistence.LimboPersistenceType;
|
||||
import fr.xephi.authme.data.limbo.persistence.SegmentSize;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
/**
|
||||
* Settings for the LimboPlayer feature.
|
||||
*/
|
||||
public final class LimboSettings implements SettingsHolder {
|
||||
|
||||
@Comment({
|
||||
"Besides storing the data in memory, you can define if/how the data should be persisted",
|
||||
"on disk. This is useful in case of a server crash, so next time the server starts we can",
|
||||
"properly restore things like OP status, ability to fly, and walk/fly speed.",
|
||||
"DISABLED: no disk storage,",
|
||||
"INDIVIDUAL_FILES: each player data in its own file,",
|
||||
"DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below"
|
||||
})
|
||||
public static final Property<LimboPersistenceType> LIMBO_PERSISTENCE_TYPE =
|
||||
newProperty(LimboPersistenceType.class, "limbo.persistence.type", LimboPersistenceType.INDIVIDUAL_FILES);
|
||||
|
||||
@Comment({
|
||||
"This setting only affects DISTRIBUTED_FILES persistence. The distributed file",
|
||||
"persistence attempts to reduce the number of files by distributing players into various",
|
||||
"buckets based on their UUID. This setting defines into how many files the players should",
|
||||
"be distributed. Possible values: ONE, FOUR, EIGHT, SIXTEEN, THIRTY_TWO, SIXTY_FOUR,",
|
||||
"ONE_TWENTY for 128, TWO_FIFTY for 256.",
|
||||
"For example, if you expect 100 non-logged in players, setting to SIXTEEN will average",
|
||||
"6.25 players per file (100 / 16).",
|
||||
"Note: if you change this setting all data will be migrated. If you have a lot of data,",
|
||||
"change this setting only on server restart, not with /authme reload."
|
||||
})
|
||||
public static final Property<SegmentSize> DISTRIBUTION_SIZE =
|
||||
newProperty(SegmentSize.class, "limbo.persistence.distributionSize", SegmentSize.SIXTEEN);
|
||||
|
||||
@Comment({
|
||||
"Whether the player is allowed to fly: RESTORE, ENABLE, DISABLE, NOTHING.",
|
||||
"RESTORE sets back the old property from the player. NOTHING will prevent AuthMe",
|
||||
"from modifying the 'allow flight' property on the player."
|
||||
})
|
||||
public static final Property<AllowFlightRestoreType> RESTORE_ALLOW_FLIGHT =
|
||||
newProperty(AllowFlightRestoreType.class, "limbo.restoreAllowFlight", AllowFlightRestoreType.RESTORE);
|
||||
|
||||
@Comment({
|
||||
"Restore fly speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.",
|
||||
"RESTORE: restore the speed the player had;",
|
||||
"DEFAULT: always set to default speed;",
|
||||
"MAX_RESTORE: take the maximum of the player's current speed and the previous one",
|
||||
"RESTORE_NO_ZERO: Like 'restore' but sets speed to default if the player's speed was 0"
|
||||
})
|
||||
public static final Property<WalkFlySpeedRestoreType> RESTORE_FLY_SPEED =
|
||||
newProperty(WalkFlySpeedRestoreType.class, "limbo.restoreFlySpeed", WalkFlySpeedRestoreType.RESTORE_NO_ZERO);
|
||||
|
||||
@Comment({
|
||||
"Restore walk speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.",
|
||||
"See above for a description of the values."
|
||||
})
|
||||
public static final Property<WalkFlySpeedRestoreType> RESTORE_WALK_SPEED =
|
||||
newProperty(WalkFlySpeedRestoreType.class, "limbo.restoreWalkSpeed", WalkFlySpeedRestoreType.RESTORE_NO_ZERO);
|
||||
|
||||
private LimboSettings() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerComments(CommentsConfiguration conf) {
|
||||
String[] limboExplanation = {
|
||||
"Before a user logs in, various properties are temporarily removed from the player,",
|
||||
"such as OP status, ability to fly, and walk/fly speed.",
|
||||
"Once the user is logged in, we add back the properties we previously saved.",
|
||||
"In this section, you may define how these properties should be handled.",
|
||||
"Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players"
|
||||
};
|
||||
conf.setComment("limbo", limboExplanation);
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import fr.xephi.authme.output.LogLevel;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class PluginSettings implements SettingsHolder {
|
||||
|
||||
@Comment({
|
||||
"Do you want to enable the session feature?",
|
||||
"If enabled, when a player authenticates successfully,",
|
||||
"his IP and his nickname is saved.",
|
||||
"The next time the player joins the server, if his IP",
|
||||
"is the same as last time and the timeout hasn't",
|
||||
"expired, he will not need to authenticate."
|
||||
})
|
||||
public static final Property<Boolean> SESSIONS_ENABLED =
|
||||
newProperty("settings.sessions.enabled", true);
|
||||
|
||||
@Comment({
|
||||
"After how many minutes should a session expire?",
|
||||
"A player's session ends after the timeout or if his IP has changed"
|
||||
})
|
||||
public static final Property<Integer> SESSIONS_TIMEOUT =
|
||||
newProperty("settings.sessions.timeout", 43200);
|
||||
|
||||
@Comment({
|
||||
"Message language, available languages:",
|
||||
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md"
|
||||
})
|
||||
public static final Property<String> MESSAGES_LANGUAGE =
|
||||
newProperty("settings.messagesLanguage", "zhcn");
|
||||
|
||||
@Comment({
|
||||
"Enables switching a player to defined permission groups before they log in.",
|
||||
"See below for a detailed explanation."
|
||||
})
|
||||
public static final Property<Boolean> ENABLE_PERMISSION_CHECK =
|
||||
newProperty("GroupOptions.enablePermissionCheck", false);
|
||||
|
||||
@Comment({
|
||||
"This is a very important option: if a registered player joins the server",
|
||||
"AuthMe will switch him to unLoggedInGroup. This should prevent all major exploits.",
|
||||
"You can set up your permission plugin with this special group to have no permissions,",
|
||||
"or only permission to chat (or permission to send private messages etc.).",
|
||||
"The better way is to set up this group with few permissions, so if a player",
|
||||
"tries to exploit an account they can do only what you've defined for the group.",
|
||||
"After login, the player will be moved to his correct permissions group!",
|
||||
"Please note that the group name is case-sensitive, so 'admin' is different from 'Admin'",
|
||||
"Otherwise your group will be wiped and the player will join in the default group []!",
|
||||
"Example: registeredPlayerGroup: 'NotLogged'"
|
||||
})
|
||||
public static final Property<String> REGISTERED_GROUP =
|
||||
newProperty("GroupOptions.registeredPlayerGroup", "");
|
||||
|
||||
@Comment({
|
||||
"Similar to above, unregistered players can be set to the following",
|
||||
"permissions group"
|
||||
})
|
||||
public static final Property<String> UNREGISTERED_GROUP =
|
||||
newProperty("GroupOptions.unregisteredPlayerGroup", "");
|
||||
|
||||
@Comment("Forces authme to hook into Vault instead of a specific permission handler system.")
|
||||
public static final Property<Boolean> FORCE_VAULT_HOOK =
|
||||
newProperty("settings.forceVaultHook", false);
|
||||
|
||||
@Comment({
|
||||
"Log level: INFO, FINE, DEBUG. Use INFO for general messages,",
|
||||
"FINE for some additional detailed ones (like password failed),",
|
||||
"and DEBUG for debugging"
|
||||
})
|
||||
public static final Property<LogLevel> LOG_LEVEL =
|
||||
newProperty(LogLevel.class, "settings.logLevel", LogLevel.FINE);
|
||||
|
||||
@Comment({
|
||||
"By default we schedule async tasks when talking to the database. If you want",
|
||||
"typical communication with the database to happen synchronously, set this to false"
|
||||
})
|
||||
public static final Property<Boolean> USE_ASYNC_TASKS =
|
||||
newProperty("settings.useAsyncTasks", true);
|
||||
|
||||
@Comment("The name of the server, used in some placeholders.")
|
||||
public static final Property<String> SERVER_NAME = newProperty("settings.serverName", "Your Minecraft Server");
|
||||
|
||||
private PluginSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
|
||||
public final class ProtectionSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Enable some servers protection (country based login, antibot)")
|
||||
public static final Property<Boolean> ENABLE_PROTECTION =
|
||||
newProperty("Protection.enableProtection", true);
|
||||
|
||||
@Comment("Apply the protection also to registered usernames")
|
||||
public static final Property<Boolean> ENABLE_PROTECTION_REGISTERED =
|
||||
newProperty("Protection.enableProtectionRegistered", true);
|
||||
|
||||
@Comment({
|
||||
"Countries allowed to join the server and register. For country codes, see",
|
||||
"https://dev.maxmind.com/geoip/legacy/codes/iso3166/",
|
||||
"Use \"LOCALHOST\" for local addresses.",
|
||||
"PLEASE USE QUOTES!"})
|
||||
public static final Property<List<String>> COUNTRIES_WHITELIST =
|
||||
newListProperty("Protection.countries", "CN", "LOCALHOST");
|
||||
|
||||
@Comment({
|
||||
"Countries not allowed to join the server and register",
|
||||
"PLEASE USE QUOTES!"})
|
||||
public static final Property<List<String>> COUNTRIES_BLACKLIST =
|
||||
newListProperty("Protection.countriesBlacklist", "A1");
|
||||
|
||||
@Comment("Do we need to enable automatic antibot system?")
|
||||
public static final Property<Boolean> ENABLE_ANTIBOT =
|
||||
newProperty("Protection.enableAntiBot", true);
|
||||
|
||||
@Comment("The interval in seconds")
|
||||
public static final Property<Integer> ANTIBOT_INTERVAL =
|
||||
newProperty("Protection.antiBotInterval", 5);
|
||||
|
||||
@Comment({
|
||||
"Max number of players allowed to login in the interval",
|
||||
"before the AntiBot system is enabled automatically"})
|
||||
public static final Property<Integer> ANTIBOT_SENSIBILITY =
|
||||
newProperty("Protection.antiBotSensibility", 10);
|
||||
|
||||
@Comment("Duration in minutes of the antibot automatic system")
|
||||
public static final Property<Integer> ANTIBOT_DURATION =
|
||||
newProperty("Protection.antiBotDuration", 10);
|
||||
|
||||
@Comment("Delay in seconds before the antibot activation")
|
||||
public static final Property<Integer> ANTIBOT_DELAY =
|
||||
newProperty("Protection.antiBotDelay", 60);
|
||||
|
||||
@Comment("Kicks the player that issued a command before the defined time after the join process")
|
||||
public static final Property<Integer> QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS =
|
||||
newProperty("Protection.quickCommands.denyCommandsBeforeMilliseconds", 3000);
|
||||
|
||||
private ProtectionSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class PurgeSettings implements SettingsHolder {
|
||||
|
||||
@Comment("If enabled, AuthMe automatically purges old, unused accounts")
|
||||
public static final Property<Boolean> USE_AUTO_PURGE =
|
||||
newProperty("Purge.useAutoPurge", false);
|
||||
|
||||
@Comment("Number of days after which an account should be purged")
|
||||
public static final Property<Integer> DAYS_BEFORE_REMOVE_PLAYER =
|
||||
newProperty("Purge.daysBeforeRemovePlayer", 60);
|
||||
|
||||
@Comment("Do we need to remove the player.dat file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_PLAYER_DAT =
|
||||
newProperty("Purge.removePlayerDat", false);
|
||||
|
||||
@Comment("Do we need to remove the Essentials/userdata/player.yml file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_ESSENTIALS_FILES =
|
||||
newProperty("Purge.removeEssentialsFile", false);
|
||||
|
||||
@Comment("World in which the players.dat are stored")
|
||||
public static final Property<String> DEFAULT_WORLD =
|
||||
newProperty("Purge.defaultWorld", "world");
|
||||
|
||||
@Comment("Remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge?")
|
||||
public static final Property<Boolean> REMOVE_LIMITED_CREATIVE_INVENTORIES =
|
||||
newProperty("Purge.removeLimitedCreativesInventories", false);
|
||||
|
||||
@Comment("Do we need to remove the AntiXRayData/PlayerData/player file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_ANTI_XRAY_FILE =
|
||||
newProperty("Purge.removeAntiXRayFile", false);
|
||||
|
||||
@Comment("Do we need to remove permissions?")
|
||||
public static final Property<Boolean> REMOVE_PERMISSIONS =
|
||||
newProperty("Purge.removePermissions", false);
|
||||
|
||||
private PurgeSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import fr.xephi.authme.process.register.RegisterSecondaryArgument;
|
||||
import fr.xephi.authme.process.register.RegistrationType;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class RegistrationSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Enable registration on the server?")
|
||||
public static final Property<Boolean> IS_ENABLED =
|
||||
newProperty("settings.registration.enabled", true);
|
||||
|
||||
@Comment({
|
||||
"Send every X seconds a message to a player to",
|
||||
"remind him that he has to login/register"})
|
||||
public static final Property<Integer> MESSAGE_INTERVAL =
|
||||
newProperty("settings.registration.messageInterval", 5);
|
||||
|
||||
@Comment({
|
||||
"Only registered and logged in players can play.",
|
||||
"See restrictions for exceptions"})
|
||||
public static final Property<Boolean> FORCE =
|
||||
newProperty("settings.registration.force", true);
|
||||
|
||||
@Comment({
|
||||
"Type of registration: PASSWORD or EMAIL",
|
||||
"PASSWORD = account is registered with a password supplied by the user;",
|
||||
"EMAIL = password is generated and sent to the email provided by the user.",
|
||||
"More info at https://github.com/AuthMe/AuthMeReloaded/wiki/Registration"
|
||||
})
|
||||
public static final Property<RegistrationType> REGISTRATION_TYPE =
|
||||
newProperty(RegistrationType.class, "settings.registration.type", RegistrationType.PASSWORD);
|
||||
|
||||
@Comment({
|
||||
"Second argument the /register command should take: ",
|
||||
"NONE = no 2nd argument",
|
||||
"CONFIRMATION = must repeat first argument (pass or email)",
|
||||
"EMAIL_OPTIONAL = for password register: 2nd argument can be empty or have email address",
|
||||
"EMAIL_MANDATORY = for password register: 2nd argument MUST be an email address"
|
||||
})
|
||||
public static final Property<RegisterSecondaryArgument> REGISTER_SECOND_ARGUMENT =
|
||||
newProperty(RegisterSecondaryArgument.class, "settings.registration.secondArg",
|
||||
RegisterSecondaryArgument.CONFIRMATION);
|
||||
|
||||
@Comment({
|
||||
"Do we force kick a player after a successful registration?",
|
||||
"Do not use with login feature below"})
|
||||
public static final Property<Boolean> FORCE_KICK_AFTER_REGISTER =
|
||||
newProperty("settings.registration.forceKickAfterRegister", false);
|
||||
|
||||
@Comment("Does AuthMe need to enforce a /login after a successful registration?")
|
||||
public static final Property<Boolean> FORCE_LOGIN_AFTER_REGISTER =
|
||||
newProperty("settings.registration.forceLoginAfterRegister", false);
|
||||
@Comment("Should we delay the join message and display it once the player has logged in?")
|
||||
public static final Property<Boolean> DELAY_JOIN_MESSAGE =
|
||||
newProperty("settings.delayJoinMessage", true);
|
||||
|
||||
@Comment({
|
||||
"The custom join message that will be sent after a successful login,",
|
||||
"keep empty to use the original one.",
|
||||
"Available variables:",
|
||||
"{PLAYERNAME}: the player name (no colors)",
|
||||
"{DISPLAYNAME}: the player display name (with colors)",
|
||||
"{DISPLAYNAMENOCOLOR}: the player display name (without colors)"})
|
||||
public static final Property<String> CUSTOM_JOIN_MESSAGE =
|
||||
newProperty("settings.customJoinMessage", "");
|
||||
|
||||
@Comment("Should we remove the leave messages of unlogged users?")
|
||||
public static final Property<Boolean> REMOVE_UNLOGGED_LEAVE_MESSAGE =
|
||||
newProperty("settings.removeUnloggedLeaveMessage", true);
|
||||
|
||||
@Comment("Should we remove join messages altogether?")
|
||||
public static final Property<Boolean> REMOVE_JOIN_MESSAGE =
|
||||
newProperty("settings.removeJoinMessage", true);
|
||||
|
||||
@Comment("Should we remove leave messages altogether?")
|
||||
public static final Property<Boolean> REMOVE_LEAVE_MESSAGE =
|
||||
newProperty("settings.removeLeaveMessage", true);
|
||||
|
||||
@Comment("Do we need to add potion effect Blinding before login/register?")
|
||||
public static final Property<Boolean> APPLY_BLIND_EFFECT =
|
||||
newProperty("settings.applyBlindEffect", false);
|
||||
|
||||
@Comment({
|
||||
"Do we need to prevent people to login with another case?",
|
||||
"If Xephi is registered, then Xephi can login, but not XEPHI/xephi/XePhI"})
|
||||
public static final Property<Boolean> PREVENT_OTHER_CASE =
|
||||
newProperty("settings.preventOtherCase", true);
|
||||
|
||||
|
||||
private RegistrationSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class RestrictionSettings implements SettingsHolder {
|
||||
|
||||
@Comment({
|
||||
"Can not authenticated players chat?",
|
||||
"Keep in mind that this feature also blocks all commands not",
|
||||
"listed in the list below."})
|
||||
public static final Property<Boolean> ALLOW_CHAT =
|
||||
newProperty("settings.restrictions.allowChat", false);
|
||||
|
||||
@Comment("Hide the chat log from players who are not authenticated?")
|
||||
public static final Property<Boolean> HIDE_CHAT =
|
||||
newProperty("settings.restrictions.hideChat", false);
|
||||
|
||||
@Comment("Allowed commands for unauthenticated players")
|
||||
public static final Property<Set<String>> ALLOW_COMMANDS =
|
||||
newLowercaseStringSetProperty("settings.restrictions.allowCommands",
|
||||
"/login", "/log", "/l", "/register", "/reg", "/email", "/captcha", "/2fa", "/totp");
|
||||
|
||||
@Comment({
|
||||
"Max number of allowed registrations per IP",
|
||||
"The value 0 means an unlimited number of registrations!"})
|
||||
public static final Property<Integer> MAX_REGISTRATION_PER_IP =
|
||||
newProperty("settings.restrictions.maxRegPerIp", 3);
|
||||
|
||||
@Comment("Minimum allowed username length")
|
||||
public static final Property<Integer> MIN_NICKNAME_LENGTH =
|
||||
newProperty("settings.restrictions.minNicknameLength", 3);
|
||||
|
||||
@Comment("Maximum allowed username length")
|
||||
public static final Property<Integer> MAX_NICKNAME_LENGTH =
|
||||
newProperty("settings.restrictions.maxNicknameLength", 16);
|
||||
|
||||
@Comment({
|
||||
"When this setting is enabled, online players can't be kicked out",
|
||||
"due to \"Logged in from another Location\"",
|
||||
"This setting will prevent potential security exploits."})
|
||||
public static final Property<Boolean> FORCE_SINGLE_SESSION =
|
||||
newProperty("settings.restrictions.ForceSingleSession", true);
|
||||
|
||||
@Comment({
|
||||
"If enabled, every player that spawn in one of the world listed in",
|
||||
"\"ForceSpawnLocOnJoin.worlds\" will be teleported to the spawnpoint after successful",
|
||||
"authentication. The quit location of the player will be overwritten.",
|
||||
"This is different from \"teleportUnAuthedToSpawn\" that teleport player",
|
||||
"to the spawnpoint on join."})
|
||||
public static final Property<Boolean> FORCE_SPAWN_LOCATION_AFTER_LOGIN =
|
||||
newProperty("settings.restrictions.ForceSpawnLocOnJoin.enabled", false);
|
||||
|
||||
@Comment({
|
||||
"WorldNames where we need to force the spawn location",
|
||||
"Case-sensitive!"})
|
||||
public static final Property<List<String>> FORCE_SPAWN_ON_WORLDS =
|
||||
newListProperty("settings.restrictions.ForceSpawnLocOnJoin.worlds",
|
||||
"world", "world_nether", "world_the_end");
|
||||
|
||||
@Comment("This option will save the quit location of the players.")
|
||||
public static final Property<Boolean> SAVE_QUIT_LOCATION =
|
||||
newProperty("settings.restrictions.SaveQuitLocation", false);
|
||||
|
||||
@Comment({
|
||||
"To activate the restricted user feature you need",
|
||||
"to enable this option and configure the AllowedRestrictedUser field."})
|
||||
public static final Property<Boolean> ENABLE_RESTRICTED_USERS =
|
||||
newProperty("settings.restrictions.AllowRestrictedUser", true);
|
||||
|
||||
@Comment({
|
||||
"The restricted user feature will kick players listed below",
|
||||
"if they don't match the defined IP address. Names are case-insensitive.",
|
||||
"You can use * as wildcard (127.0.0.*), or regex with a \"regex:\" prefix regex:127\\.0\\.0\\..*",
|
||||
"Example:",
|
||||
" AllowedRestrictedUser:",
|
||||
" - playername;127.0.0.1",
|
||||
" - playername;regex:127\\.0\\.0\\..*"})
|
||||
public static final Property<Set<String>> RESTRICTED_USERS =
|
||||
newLowercaseStringSetProperty("settings.restrictions.AllowedRestrictedUser",
|
||||
"server_land;127.0.0.1","server;127.0.0.1","bukkit;127.0.0.1","purpur;127.0.0.1",
|
||||
"system;127.0.0.1","admin;127.0.0.1","md_5;127.0.0.1","administrator;127.0.0.1","notch;127.0.0.1",
|
||||
"spigot;127.0.0.1","bukkit;127.0.0.1","bukkitcraft;127.0.0.1","paperclip;127.0.0.1","papermc;127.0.0.1",
|
||||
"spigotmc;127.0.0.1","root;127.0.0.1","console;127.0.0.1","purpur;127.0.0.1","authme;127.0.0.1",
|
||||
"owner;127.0.0.1");
|
||||
|
||||
@Comment("Ban unknown IPs trying to log in with a restricted username?")
|
||||
public static final Property<Boolean> BAN_UNKNOWN_IP =
|
||||
newProperty("settings.restrictions.banUnsafedIP", false);
|
||||
|
||||
@Comment("Should unregistered players be kicked immediately?")
|
||||
public static final Property<Boolean> KICK_NON_REGISTERED =
|
||||
newProperty("settings.restrictions.kickNonRegistered", false);
|
||||
|
||||
@Comment("Should players be kicked on wrong password?")
|
||||
public static final Property<Boolean> KICK_ON_WRONG_PASSWORD =
|
||||
newProperty("settings.restrictions.kickOnWrongPassword", false);
|
||||
|
||||
@Comment({
|
||||
"Should not logged in players be teleported to the spawn?",
|
||||
"After the authentication they will be teleported back to",
|
||||
"their normal position."})
|
||||
public static final Property<Boolean> TELEPORT_UNAUTHED_TO_SPAWN =
|
||||
newProperty("settings.restrictions.teleportUnAuthedToSpawn", false);
|
||||
|
||||
@Comment("Can unregistered players walk around?")
|
||||
public static final Property<Boolean> ALLOW_UNAUTHED_MOVEMENT =
|
||||
newProperty("settings.restrictions.allowMovement", false);
|
||||
|
||||
@Comment({
|
||||
"After how many seconds should players who fail to login or register",
|
||||
"be kicked? Set to 0 to disable."})
|
||||
public static final Property<Integer> TIMEOUT =
|
||||
newProperty("settings.restrictions.timeout", 120);
|
||||
|
||||
@Comment("Regex pattern of allowed characters in the player name.")
|
||||
public static final Property<String> ALLOWED_NICKNAME_CHARACTERS =
|
||||
newProperty("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*");
|
||||
|
||||
|
||||
@Comment({
|
||||
"How far can unregistered players walk?",
|
||||
"Set to 0 for unlimited radius"
|
||||
})
|
||||
public static final Property<Integer> ALLOWED_MOVEMENT_RADIUS =
|
||||
newProperty("settings.restrictions.allowedMovementRadius", 0);
|
||||
|
||||
@Comment("Should we protect the player inventory before logging in? Requires ProtocolLib.")
|
||||
public static final Property<Boolean> PROTECT_INVENTORY_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.ProtectInventoryBeforeLogIn", false);
|
||||
|
||||
@Comment("Should we deny the tabcomplete feature before logging in? Requires ProtocolLib.")
|
||||
public static final Property<Boolean> DENY_TABCOMPLETE_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.DenyTabCompleteBeforeLogin", false);
|
||||
|
||||
@Comment({
|
||||
"Should we display all other accounts from a player when he joins?",
|
||||
"permission: /authme.admin.accounts"})
|
||||
public static final Property<Boolean> DISPLAY_OTHER_ACCOUNTS =
|
||||
newProperty("settings.restrictions.displayOtherAccounts", false);
|
||||
|
||||
@Comment("Spawn priority; values: authme, essentials, cmi, multiverse, default")
|
||||
public static final Property<String> SPAWN_PRIORITY =
|
||||
newProperty("settings.restrictions.spawnPriority", "authme,essentials,cmi,multiverse,default");
|
||||
|
||||
@Comment("Maximum Login authorized by IP")
|
||||
public static final Property<Integer> MAX_LOGIN_PER_IP =
|
||||
newProperty("settings.restrictions.maxLoginPerIp", 3);
|
||||
|
||||
@Comment("Maximum Join authorized by IP")
|
||||
public static final Property<Integer> MAX_JOIN_PER_IP =
|
||||
newProperty("settings.restrictions.maxJoinPerIp", 3);
|
||||
|
||||
@Comment("AuthMe will NEVER teleport players if set to true!")
|
||||
public static final Property<Boolean> NO_TELEPORT =
|
||||
newProperty("settings.restrictions.noTeleport", false);
|
||||
|
||||
@Comment({
|
||||
"Regex syntax for allowed chars in passwords. The default [!-~] allows all visible ASCII",
|
||||
"characters, which is what we recommend. See also http://asciitable.com",
|
||||
"You can test your regex with https://regex101.com"
|
||||
})
|
||||
public static final Property<String> ALLOWED_PASSWORD_REGEX =
|
||||
newProperty("settings.restrictions.allowedPasswordCharacters", "[!-~]*");
|
||||
|
||||
@Comment("Regex syntax for allowed chars in email.")
|
||||
public static final Property<String> ALLOWED_EMAIL_REGEX =
|
||||
newProperty("settings.restrictions.allowedEmailCharacters", "^[A-Za-z0-9]{4,15}@(qq|outlook|163|gmail|icloud).com$");
|
||||
|
||||
|
||||
@Comment("Force survival gamemode when player joins?")
|
||||
public static final Property<Boolean> FORCE_SURVIVAL_MODE =
|
||||
newProperty("settings.GameMode.ForceSurvivalMode", false);
|
||||
|
||||
@Comment({
|
||||
"Below you can list all account names that AuthMe will ignore",
|
||||
"for registration or login. Configure it at your own risk!!",
|
||||
"This option adds compatibility with BuildCraft and some other mods.",
|
||||
"It is case-insensitive! Example:",
|
||||
"UnrestrictedName:",
|
||||
"- 'npcPlayer'",
|
||||
"- 'npcPlayer2'"
|
||||
})
|
||||
public static final Property<Set<String>> UNRESTRICTED_NAMES =
|
||||
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedName");
|
||||
|
||||
|
||||
@Comment({
|
||||
"Below you can list all inventories names that AuthMe will ignore",
|
||||
"for registration or login. Configure it at your own risk!!",
|
||||
"This option adds compatibility with some mods.",
|
||||
"It is case-insensitive! Example:",
|
||||
"UnrestrictedInventories:",
|
||||
"- 'myCustomInventory1'",
|
||||
"- 'myCustomInventory2'"
|
||||
})
|
||||
public static final Property<Set<String>> UNRESTRICTED_INVENTORIES =
|
||||
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedInventories");
|
||||
|
||||
|
||||
private RestrictionSettings() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import ch.jalu.configme.Comment;
|
||||
import ch.jalu.configme.SettingsHolder;
|
||||
import ch.jalu.configme.properties.BooleanProperty;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.EnumSetProperty;
|
||||
import java.util.Set;
|
||||
import fr.xephi.authme.listener.PlayerQuitListener;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty;
|
||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public final class SecuritySettings implements SettingsHolder {
|
||||
|
||||
@Comment({"Stop the server if we can't contact the sql database",
|
||||
"Take care with this, if you set this to false,",
|
||||
"AuthMe will automatically disable and the server won't be protected!"})
|
||||
public static final Property<Boolean> STOP_SERVER_ON_PROBLEM =
|
||||
newProperty("Security.SQLProblem.stopServer", true);
|
||||
|
||||
@Comment("Enable the new feature to prevent ghost players?")
|
||||
public static final Property<Boolean> ANTI_GHOST_PLAYERS = newProperty("3rdPartyFeature.fixes.antiGhostPlayer", false);
|
||||
|
||||
@Comment({"(BETA Feature)Choose the best teleport method by server brand?",
|
||||
"(Enable this if you are using Paper)"})
|
||||
public static final Property<Boolean> SMART_ASYNC_TELEPORT = newProperty("3rdPartyFeature.optimizes.smartAsyncTeleport",false);
|
||||
|
||||
@Comment("(BETA Feature)Send a GUI captcha to unregistered players?")
|
||||
public static final Property<Boolean> GUI_CAPTCHA = newProperty("3rdPartyFeature.captcha.guiCaptcha",false);
|
||||
|
||||
// @Comment({"Kick the players when they didn't finish the gui captcha in time? " ,
|
||||
// "(0 is disabled)"})
|
||||
// public static final Property<Integer> CAPTCHA_TIMEOUT = newProperty("3rdPartyFeature.captcha.timeout",0);
|
||||
//@Comment({"Using which API to get hash data?",
|
||||
//"Available options: github, gitee, ghproxy (if your server is in China, please use gitee or ghproxy.)"})
|
||||
//public static final Property<String> SHA_CHECK_METHOD = newProperty("Plugin.hashing.hashApi","github");
|
||||
|
||||
//@Comment("Should we use the local cache sometimes instead of requesting API?")
|
||||
//public static final Property<Boolean> USE_LOCAL_CACHE = newProperty("Plugin.hashing.useLocalCache",false);
|
||||
|
||||
//@Comment("DON'T TOUCH!!!")
|
||||
//public static final Property<String> SHA_CHECK_CACHE = newProperty("Plugin.hashing.hashCached","");
|
||||
|
||||
@Comment("Copy AuthMe log output in a separate file as well?")
|
||||
public static final Property<Boolean> USE_LOGGING =
|
||||
newProperty("Security.console.logConsole", true);
|
||||
|
||||
@Comment({"Query haveibeenpwned.com with a hashed version of the password.",
|
||||
"This is used to check whether it is safe."})
|
||||
public static final Property<Boolean> HAVE_I_BEEN_PWNED_CHECK =
|
||||
newProperty("Security.account.haveIBeenPwned.check", false);
|
||||
|
||||
@Comment({"If the password is used more than this number of times, it is considered unsafe."})
|
||||
public static final Property<Integer> HAVE_I_BEEN_PWNED_LIMIT =
|
||||
newProperty("Security.account.haveIBeenPwned.limit", 0);
|
||||
|
||||
@Comment("Enable captcha when a player uses wrong password too many times")
|
||||
public static final Property<Boolean> ENABLE_LOGIN_FAILURE_CAPTCHA =
|
||||
newProperty("Security.captcha.useCaptcha", false);
|
||||
|
||||
@Comment("Check for updates on enabled from GitHub?")
|
||||
public static final Property<Boolean> CHECK_FOR_UPDATES =
|
||||
newProperty("Plugin.updates.checkForUpdates", true);
|
||||
|
||||
@Comment("Max allowed tries before a captcha is required")
|
||||
public static final Property<Integer> MAX_LOGIN_TRIES_BEFORE_CAPTCHA =
|
||||
newProperty("Security.captcha.maxLoginTry", 8);
|
||||
|
||||
@Comment("Captcha length")
|
||||
public static final Property<Integer> CAPTCHA_LENGTH =
|
||||
newProperty("Security.captcha.captchaLength", 6);
|
||||
|
||||
@Comment("Minutes after which login attempts count is reset for a player")
|
||||
public static final Property<Integer> CAPTCHA_COUNT_MINUTES_BEFORE_RESET =
|
||||
newProperty("Security.captcha.captchaCountReset", 120);
|
||||
|
||||
@Comment("Require captcha before a player may register?")
|
||||
public static final Property<Boolean> ENABLE_CAPTCHA_FOR_REGISTRATION =
|
||||
newProperty("Security.captcha.requireForRegistration", false);
|
||||
|
||||
@Comment("Minimum length of password")
|
||||
public static final Property<Integer> MIN_PASSWORD_LENGTH =
|
||||
newProperty("settings.security.minPasswordLength", 8);
|
||||
|
||||
@Comment("Maximum length of password")
|
||||
public static final Property<Integer> MAX_PASSWORD_LENGTH =
|
||||
newProperty("settings.security.passwordMaxLength", 26);
|
||||
|
||||
@Comment({
|
||||
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
|
||||
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
|
||||
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, CUSTOM (for developers only). See full list at",
|
||||
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md",
|
||||
"If you use ARGON2, check that you have the argon2 c library on your system"
|
||||
})
|
||||
public static final Property<HashAlgorithm> PASSWORD_HASH =
|
||||
newProperty(HashAlgorithm.class, "settings.security.passwordHash", HashAlgorithm.SHA256);
|
||||
|
||||
@Comment({
|
||||
"If a password check fails, AuthMe will also try to check with the following hash methods.",
|
||||
"Use this setting when you change from one hash method to another.",
|
||||
"AuthMe will update the password to the new hash. Example:",
|
||||
"legacyHashes:",
|
||||
"- 'SHA1'"
|
||||
})
|
||||
public static final Property<Set<HashAlgorithm>> LEGACY_HASHES =
|
||||
new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes");
|
||||
|
||||
@Comment("Salt length for the SALTED2MD5 MD5(MD5(password)+salt)")
|
||||
public static final Property<Integer> DOUBLE_MD5_SALT_LENGTH =
|
||||
newProperty("settings.security.doubleMD5SaltLength", 8);
|
||||
|
||||
@Comment("Number of rounds to use if passwordHash is set to PBKDF2. Default is 10000")
|
||||
public static final Property<Integer> PBKDF2_NUMBER_OF_ROUNDS =
|
||||
newProperty("settings.security.pbkdf2Rounds", 10000);
|
||||
|
||||
@Comment({"Prevent unsafe passwords from being used; put them in lowercase!",
|
||||
"You should always set 'help' as unsafePassword due to possible conflicts.",
|
||||
"unsafePasswords:",
|
||||
"- '123456'",
|
||||
"- 'password'",
|
||||
"- 'help'"})
|
||||
public static final Property<Set<String>> UNSAFE_PASSWORDS =
|
||||
newLowercaseStringSetProperty("settings.security.unsafePasswords",
|
||||
"12345678", "password", "qwertyui", "123456789", "87654321", "1234567890", "asdfghjkl","zxcvbnm,","asdfghjk","12312312","123123123","32132132","321321321");
|
||||
|
||||
@Comment("Tempban a user's IP address if they enter the wrong password too many times")
|
||||
public static final Property<Boolean> TEMPBAN_ON_MAX_LOGINS =
|
||||
newProperty("Security.tempban.enableTempban", false);
|
||||
|
||||
@Comment("How many times a user can attempt to login before their IP being tempbanned")
|
||||
public static final Property<Integer> MAX_LOGIN_TEMPBAN =
|
||||
newProperty("Security.tempban.maxLoginTries", 8);
|
||||
|
||||
@Comment({"The length of time a IP address will be tempbanned in minutes",
|
||||
"Default: 480 minutes, or 8 hours"})
|
||||
public static final Property<Integer> TEMPBAN_LENGTH =
|
||||
newProperty("Security.tempban.tempbanLength", 480);
|
||||
|
||||
@Comment({"How many minutes before resetting the count for failed logins by IP and username",
|
||||
"Default: 480 minutes (8 hours)"})
|
||||
public static final Property<Integer> TEMPBAN_MINUTES_BEFORE_RESET =
|
||||
newProperty("Security.tempban.minutesBeforeCounterReset", 480);
|
||||
|
||||
@Comment({"The command to execute instead of using the internal ban system, empty if disabled.",
|
||||
"Available placeholders: %player%, %ip%"})
|
||||
public static final Property<String> TEMPBAN_CUSTOM_COMMAND =
|
||||
newProperty("Security.tempban.customCommand", "");
|
||||
|
||||
@Comment("Number of characters a recovery code should have (0 to disable)")
|
||||
public static final Property<Integer> RECOVERY_CODE_LENGTH =
|
||||
newProperty("Security.recoveryCode.length", 8);
|
||||
|
||||
@Comment("How many hours is a recovery code valid for?")
|
||||
public static final Property<Integer> RECOVERY_CODE_HOURS_VALID =
|
||||
newProperty("Security.recoveryCode.validForHours", 6);
|
||||
|
||||
@Comment("Max number of tries to enter recovery code")
|
||||
public static final Property<Integer> RECOVERY_CODE_MAX_TRIES =
|
||||
newProperty("Security.recoveryCode.maxTries", 4);
|
||||
|
||||
@Comment({"How long a player has after password recovery to change their password",
|
||||
"without logging in. This is in minutes.",
|
||||
"Default: 2 minutes"})
|
||||
public static final Property<Integer> PASSWORD_CHANGE_TIMEOUT =
|
||||
newProperty("Security.recoveryCode.passwordChangeTimeout", 5);
|
||||
|
||||
@Comment({
|
||||
"Seconds a user has to wait for before a password recovery mail may be sent again",
|
||||
"This prevents an attacker from abusing AuthMe's email feature."
|
||||
})
|
||||
public static final Property<Integer> EMAIL_RECOVERY_COOLDOWN_SECONDS =
|
||||
newProperty("Security.emailRecovery.cooldown", 60);
|
||||
|
||||
@Comment({
|
||||
"The mail shown using /email show will be partially hidden",
|
||||
"E.g. (if enabled)",
|
||||
" original email: my.email@example.com",
|
||||
" hidden email: my.***@***mple.com"
|
||||
})
|
||||
public static final Property<Boolean> USE_EMAIL_MASKING =
|
||||
newProperty("Security.privacy.enableEmailMasking", false);
|
||||
|
||||
@Comment("Minutes after which a verification code will expire")
|
||||
public static final Property<Integer> VERIFICATION_CODE_EXPIRATION_MINUTES =
|
||||
newProperty("Security.privacy.verificationCodeExpiration", 10);
|
||||
|
||||
private SecuritySettings() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user