Move new configs outside of 'custom' package
- Create properties package for storing the config properties - Move NewSetting class to main settings pkg
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class BackupSettings implements SettingsClass {
|
||||
|
||||
@Comment("Enable or disable automatic backup")
|
||||
public static final Property<Boolean> ENABLED =
|
||||
newProperty("BackupSystem.ActivateBackup", false);
|
||||
|
||||
@Comment("Set backup at every start of server")
|
||||
public static final Property<Boolean> ON_SERVER_START =
|
||||
newProperty("BackupSystem.OnServerStart", false);
|
||||
|
||||
@Comment("Set 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() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING;
|
||||
|
||||
public class ConverterSettings implements SettingsClass {
|
||||
|
||||
@Comment("Rakamak file name")
|
||||
public static final Property<String> RAKAMAK_FILE_NAME =
|
||||
newProperty(STRING, "Converter.Rakamak.fileName", "users.rak");
|
||||
|
||||
@Comment("Rakamak use IP?")
|
||||
public static final Property<Boolean> RAKAMAK_USE_IP =
|
||||
newProperty(BOOLEAN, "Converter.Rakamak.useIP", false);
|
||||
|
||||
@Comment("Rakamak IP file name")
|
||||
public static final Property<String> RAKAMAK_IP_FILE_NAME =
|
||||
newProperty(STRING, "Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
|
||||
@Comment("CrazyLogin database file name")
|
||||
public static final Property<String> CRAZYLOGIN_FILE_NAME =
|
||||
newProperty(STRING, "Converter.CrazyLogin.fileName", "accounts.db");
|
||||
|
||||
private ConverterSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class DatabaseSettings implements SettingsClass {
|
||||
|
||||
@Comment({"What type of database do you want to use?",
|
||||
"Valid values: sqlite, mysql"})
|
||||
public static final Property<DataSource.DataSourceType> BACKEND =
|
||||
newProperty(DataSource.DataSourceType.class, "DataSource.backend", DataSource.DataSourceType.SQLITE);
|
||||
|
||||
@Comment("Enable database caching, should improve database performance")
|
||||
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("Username about Database Connection Infos")
|
||||
public static final Property<String> MYSQL_USERNAME =
|
||||
newProperty("DataSource.mySQLUsername", "authme");
|
||||
|
||||
@Comment("Password about Database Connection Infos")
|
||||
public static final Property<String> MYSQL_PASSWORD =
|
||||
newProperty("DataSource.mySQLPassword", "123456");
|
||||
|
||||
@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("ExternalBoardOptions.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 players ips")
|
||||
public static final Property<String> MYSQL_COL_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 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 players groups")
|
||||
public static final Property<String> MYSQL_COL_GROUP =
|
||||
newProperty("ExternalBoardOptions.mySQLColumnGroup", "");
|
||||
|
||||
@Comment("Enable this when you allow registration through a website")
|
||||
public static final Property<Boolean> MYSQL_WEBSITE =
|
||||
newProperty("DataSource.mySQLWebsite", false);
|
||||
|
||||
private DatabaseSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.INTEGER;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
|
||||
public class EmailSettings implements SettingsClass {
|
||||
|
||||
@Comment("Email SMTP server host")
|
||||
public static final Property<String> SMTP_HOST =
|
||||
newProperty(STRING, "Email.mailSMTP", "smtp.gmail.com");
|
||||
|
||||
@Comment("Email SMTP server port")
|
||||
public static final Property<Integer> SMTP_PORT =
|
||||
newProperty(INTEGER, "Email.mailPort", 465);
|
||||
|
||||
@Comment("Email account which sends the mails")
|
||||
public static final Property<String> MAIL_ACCOUNT =
|
||||
newProperty(STRING, "Email.mailAccount", "");
|
||||
|
||||
@Comment("Email account password")
|
||||
public static final Property<String> MAIL_PASSWORD =
|
||||
newProperty(STRING, "Email.mailPassword", "");
|
||||
|
||||
@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(INTEGER, "Email.RecoveryPasswordLength", 8);
|
||||
|
||||
@Comment("Mail Subject")
|
||||
public static final Property<String> RECOVERY_MAIL_SUBJECT =
|
||||
newProperty(STRING, "Email.mailSubject", "Your new AuthMe password");
|
||||
|
||||
@Comment("Like maxRegPerIP but with email")
|
||||
public static final Property<Integer> MAX_REG_PER_EMAIL =
|
||||
newProperty(INTEGER, "Email.maxRegPerEmail", 1);
|
||||
|
||||
@Comment("Recall players to add an email?")
|
||||
public static final Property<Boolean> RECALL_PLAYERS =
|
||||
newProperty(BOOLEAN, "Email.recallPlayers", false);
|
||||
|
||||
@Comment("Delay in minute for the recall scheduler")
|
||||
public static final Property<Integer> DELAY_RECALL =
|
||||
newProperty(INTEGER, "Email.delayRecall", 5);
|
||||
|
||||
@Comment("Blacklist these domains for emails")
|
||||
public static final Property<List<String>> DOMAIN_BLACKLIST =
|
||||
newProperty(STRING_LIST, "Email.emailBlacklisted", "10minutemail.com");
|
||||
|
||||
@Comment("Whitelist ONLY these domains for emails")
|
||||
public static final Property<List<String>> DOMAIN_WHITELIST =
|
||||
newProperty(STRING_LIST, "Email.emailWhitelisted");
|
||||
|
||||
@Comment("Send the new password drawn in an image?")
|
||||
public static final Property<Boolean> PASSWORD_AS_IMAGE =
|
||||
newProperty(BOOLEAN, "Email.generateImage", false);
|
||||
|
||||
@Comment("The OAuth2 token")
|
||||
public static final Property<String> OAUTH2_TOKEN =
|
||||
newProperty(STRING, "Email.emailOauth2Token", "");
|
||||
|
||||
private EmailSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class HooksSettings implements SettingsClass {
|
||||
|
||||
@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("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("Do we need to cache custom Attributes?")
|
||||
public static final Property<Boolean> CACHE_CUSTOM_ATTRIBUTES =
|
||||
newProperty("Hooks.customAttributes", false);
|
||||
|
||||
@Comment("These features are only available on VeryGames Server Provider")
|
||||
public static final Property<Boolean> ENABLE_VERYGAMES_IP_CHECK =
|
||||
newProperty("VeryGames.enableIpCheck", 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 =
|
||||
newProperty(PropertyType.STRING_LIST, "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", 10);
|
||||
|
||||
@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("Wordpress prefix defined during WordPress installation")
|
||||
public static final Property<String> WORDPRESS_TABLE_PREFIX =
|
||||
newProperty("ExternalBoardOptions.wordpressTablePrefix", "wp_");
|
||||
|
||||
private HooksSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class PluginSettings implements SettingsClass {
|
||||
|
||||
@Comment("The name shown in the help messages")
|
||||
public static final Property<String> HELP_HEADER =
|
||||
newProperty("settings.helpHeader", "AuthMeReloaded");
|
||||
|
||||
@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", false);
|
||||
|
||||
@Comment({
|
||||
"After how many minutes should a session expire?",
|
||||
"0 for unlimited time (Very dangerous, use it at your own risk!)",
|
||||
"Remember that sessions will end only after the timeout, and",
|
||||
"if the player's IP has changed but the timeout hasn't expired,",
|
||||
"the player will be kicked from the server due to invalid session"
|
||||
})
|
||||
public static final Property<Integer> SESSIONS_TIMEOUT =
|
||||
newProperty("settings.sessions.timeout", 10);
|
||||
|
||||
@Comment({
|
||||
"Should the session expire if the player tries to log in with",
|
||||
"another IP address?"
|
||||
})
|
||||
public static final Property<Boolean> SESSIONS_EXPIRE_ON_IP_CHANGE =
|
||||
newProperty("settings.sessions.sessionExpireOnIpChange", true);
|
||||
|
||||
@Comment("Message language, available: en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt")
|
||||
public static final Property<String> MESSAGES_LANGUAGE =
|
||||
newProperty("settings.messagesLanguage", "en");
|
||||
|
||||
@Comment({
|
||||
"Take care with this option; if you don't want",
|
||||
"to use Vault and group switching of AuthMe",
|
||||
"for unloggedIn players, set this setting to true.",
|
||||
"Default is false."
|
||||
})
|
||||
public static final Property<Boolean> ENABLE_PERMISSION_CHECK =
|
||||
newProperty("permission.EnablePermissionCheck", false);
|
||||
|
||||
|
||||
private PluginSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.INTEGER;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
|
||||
|
||||
public class ProtectionSettings implements SettingsClass {
|
||||
|
||||
@Comment("Enable some servers protection (country based login, antibot)")
|
||||
public static final Property<Boolean> ENABLE_PROTECTION =
|
||||
newProperty(BOOLEAN, "Protection.enableProtection", false);
|
||||
|
||||
@Comment({"Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes",
|
||||
"PLEASE USE QUOTES!"})
|
||||
public static final Property<List<String>> COUNTRIES_WHITELIST =
|
||||
newProperty(STRING_LIST, "Protection.countries", "US", "GB", "A1");
|
||||
|
||||
@Comment({"Countries not allowed to join the server and register",
|
||||
"PLEASE USE QUOTES!"})
|
||||
public static final Property<List<String>> COUNTRIES_BLACKLIST =
|
||||
newProperty(STRING_LIST, "Protection.countriesBlacklist");
|
||||
|
||||
@Comment("Do we need to enable automatic antibot system?")
|
||||
public static final Property<Boolean> ENABLE_ANTIBOT =
|
||||
newProperty(BOOLEAN, "Protection.enableAntiBot", false);
|
||||
|
||||
@Comment("Max number of player allowed to login in 5 secs before enable AntiBot system automatically")
|
||||
public static final Property<Integer> ANTIBOT_SENSIBILITY =
|
||||
newProperty(INTEGER, "Protection.antiBotSensibility", 5);
|
||||
|
||||
@Comment("Duration in minutes of the antibot automatic system")
|
||||
public static final Property<Integer> ANTIBOT_DURATION =
|
||||
newProperty(INTEGER, "Protection.antiBotDuration", 10);
|
||||
|
||||
private ProtectionSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.INTEGER;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING;
|
||||
|
||||
public class PurgeSettings implements SettingsClass {
|
||||
|
||||
@Comment("If enabled, AuthMe automatically purges old, unused accounts")
|
||||
public static final Property<Boolean> USE_AUTO_PURGE =
|
||||
newProperty(BOOLEAN, "Purge.useAutoPurge", false);
|
||||
|
||||
@Comment("Number of Days an account become Unused")
|
||||
public static final Property<Integer> DAYS_BEFORE_REMOVE_PLAYER =
|
||||
newProperty(INTEGER, "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(BOOLEAN, "Purge.removePlayerDat", false);
|
||||
|
||||
@Comment("Do we need to remove the Essentials/users/player.yml file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_ESSENTIALS_FILES =
|
||||
newProperty(BOOLEAN, "Purge.removeEssentialsFile", false);
|
||||
|
||||
@Comment("World where are players.dat stores")
|
||||
public static final Property<String> DEFAULT_WORLD =
|
||||
newProperty(STRING, "Purge.defaultWorld", "world");
|
||||
|
||||
@Comment("Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ?")
|
||||
public static final Property<Boolean> REMOVE_LIMITED_CREATIVE_INVENTORIES =
|
||||
newProperty(BOOLEAN, "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(BOOLEAN, "Purge.removeAntiXRayFile", false);
|
||||
|
||||
@Comment("Do we need to remove permissions?")
|
||||
public static final Property<Boolean> REMOVE_PERMISSIONS =
|
||||
newProperty(BOOLEAN, "Purge.removePermissions", false);
|
||||
|
||||
private PurgeSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class RegistrationSettings implements SettingsClass {
|
||||
|
||||
@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("Do we replace password registration by an email registration method?")
|
||||
public static final Property<Boolean> USE_EMAIL_REGISTRATION =
|
||||
newProperty("settings.registration.enableEmailRegistrationSystem", false);
|
||||
|
||||
@Comment({
|
||||
"Enable double check of email when you register",
|
||||
"when it's true, registration requires that kind of command:",
|
||||
"/register <email> <confirmEmail>"})
|
||||
public static final Property<Boolean> ENABLE_CONFIRM_EMAIL =
|
||||
newProperty("settings.registration.doubleEmailCheck", false);
|
||||
|
||||
@Comment({
|
||||
"Do we force kicking 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("Force these commands after /login, without any '/', use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_COMMANDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceCommands");
|
||||
|
||||
@Comment("Force these commands after /login as service console, without any '/'. "
|
||||
+ "Use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_COMMANDS_AS_CONSOLE =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceCommandsAsConsole");
|
||||
|
||||
@Comment("Force these commands after /register, without any '/', use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_REGISTER_COMMANDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceRegisterCommands");
|
||||
|
||||
@Comment("Force these commands after /register as a server console, without any '/'. "
|
||||
+ "Use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_REGISTER_COMMANDS_AS_CONSOLE =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceRegisterCommandsAsConsole");
|
||||
|
||||
@Comment({
|
||||
"Enable to display the welcome message (welcome.txt) after a registration or a login",
|
||||
"You can use colors in this welcome.txt + some replaced strings:",
|
||||
"{PLAYER}: player name, {ONLINE}: display number of online players, {MAXPLAYERS}: display server slots,",
|
||||
"{IP}: player ip, {LOGINS}: number of players logged, {WORLD}: player current world, {SERVER}: server name",
|
||||
"{VERSION}: get current bukkit version, {COUNTRY}: player country"})
|
||||
public static final Property<Boolean> USE_WELCOME_MESSAGE =
|
||||
newProperty("settings.useWelcomeMessage", true);
|
||||
|
||||
@Comment("Do we need to broadcast the welcome message to all server or only to the player? set true for "
|
||||
+ "server or false for player")
|
||||
public static final Property<Boolean> BROADCAST_WELCOME_MESSAGE =
|
||||
newProperty("settings.broadcastWelcomeMessage", false);
|
||||
|
||||
@Comment("Do we need to delay the join/leave message to be displayed only when the player is authenticated?")
|
||||
public static final Property<Boolean> DELAY_JOIN_LEAVE_MESSAGES =
|
||||
newProperty("settings.delayJoinLeaveMessages", true);
|
||||
|
||||
@Comment("Do we need to add potion effect Blinding before login/reigster?")
|
||||
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", false);
|
||||
|
||||
|
||||
private RegistrationSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class RestrictionSettings implements SettingsClass {
|
||||
|
||||
@Comment({
|
||||
"Can not authenticated players chat and see the chat log?",
|
||||
"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("Allowed commands for unauthenticated players")
|
||||
public static final Property<List<String>> ALLOW_COMMANDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.restrictions.allowCommands",
|
||||
"login", "register", "l", "reg", "email", "captcha");
|
||||
|
||||
@Comment("Max number of allowed registrations per IP")
|
||||
// TODO ljacqu 20160109: If 0 == unlimited, add this fact ot the comment
|
||||
public static final Property<Integer> MAX_REGISTRATION_PER_IP =
|
||||
newProperty("settings.restrictions.maxRegPerIp", 1);
|
||||
|
||||
@Comment("Minimum allowed username length")
|
||||
public static final Property<Integer> MIN_NICKNAME_LENGTH =
|
||||
newProperty("settings.restrictions.minNicknameLength", 4);
|
||||
|
||||
@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 will be teleported to the world spawnpoint",
|
||||
"after successful authentication.",
|
||||
"The quit location of the player will be overwritten.",
|
||||
"This is different from \"teleportUnAuthedToSpawn\" that teleport player",
|
||||
"back to his quit location after the authentication."})
|
||||
public static final Property<Boolean> FORCE_SPAWN_LOCATION_AFTER_LOGIN =
|
||||
newProperty("settings.restrictions.ForceSpawnLocOnJoinEnabled", false);
|
||||
|
||||
@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 AllowedRestrctedUser field."})
|
||||
public static final Property<Boolean> ENABLE_RESTRICTED_USERS =
|
||||
newProperty("settings.restrictions.AllowRestrictedUser", false);
|
||||
|
||||
@Comment({
|
||||
"The restricted user feature will kick players listed below",
|
||||
"if they don't match the defined IP address.",
|
||||
"Example:",
|
||||
" AllowedRestrictedUser:",
|
||||
" - playername;127.0.0.1"})
|
||||
public static final Property<List<String>> ALLOWED_RESTRICTED_USERS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.restrictions.AllowedRestrictedUser");
|
||||
|
||||
@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({
|
||||
"Should not authenticated players have speed = 0?",
|
||||
"This will reset the fly/walk speed to default value after the login."})
|
||||
public static final Property<Boolean> REMOVE_SPEED =
|
||||
newProperty("settings.restrictions.removeSpeed", true);
|
||||
|
||||
@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", 30);
|
||||
|
||||
@Comment("Regex syntax 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", 100);
|
||||
|
||||
@Comment({
|
||||
"Enable double check of password when you register",
|
||||
"when it's true, registration requires that kind of command:",
|
||||
"/register <password> <confirmPassword>"})
|
||||
public static final Property<Boolean> ENABLE_PASSWORD_CONFIRMATION =
|
||||
newProperty("settings.restrictions.enablePasswordConfirmation", true);
|
||||
|
||||
@Comment("Should we protect the player inventory before logging in?")
|
||||
public static final Property<Boolean> PROTECT_INVENTORY_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.ProtectInventoryBeforeLogIn", true);
|
||||
|
||||
@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", true);
|
||||
|
||||
@Comment({
|
||||
"WorldNames where we need to force the spawn location for ForceSpawnLocOnJoinEnabled",
|
||||
"Case-sensitive!"})
|
||||
public static final Property<List<String>> FORCE_SPAWN_ON_WORLDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.restrictions.ForceSpawnOnTheseWorlds",
|
||||
"world", "world_nether", "world_the_end");
|
||||
|
||||
@Comment("Ban ip when the ip is not the ip registered in database")
|
||||
public static final Property<Boolean> BAN_UNKNOWN_IP =
|
||||
newProperty("settings.restrictions.banUnsafedIP", false);
|
||||
|
||||
@Comment("Spawn priority; values: authme, essentials, multiverse, default")
|
||||
public static final Property<String> SPAWN_PRIORITY =
|
||||
newProperty("settings.restrictions.spawnPriority", "authme,essentials,multiverse,default");
|
||||
|
||||
@Comment("Maximum Login authorized by IP")
|
||||
public static final Property<Integer> MAX_LOGIN_PER_IP =
|
||||
newProperty("settings.restrictions.maxLoginPerIp", 0);
|
||||
|
||||
@Comment("Maximum Join authorized by IP")
|
||||
public static final Property<Integer> MAX_JOIN_PER_IP =
|
||||
newProperty("settings.restrictions.maxJoinPerIp", 0);
|
||||
|
||||
@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")
|
||||
public static final Property<String> ALLOWED_PASSWORD_REGEX =
|
||||
newProperty("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
|
||||
|
||||
@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!! Remember that if you are going to add",
|
||||
"nickname with [], you have to delimit name with ' '.",
|
||||
"this option add compatibility with BuildCraft and some",
|
||||
"other mods.",
|
||||
"It is case-sensitive!"
|
||||
})
|
||||
public static final Property<List<String>> UNRESTRICTED_NAMES =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.unrestrictions.UnrestrictedName");
|
||||
|
||||
|
||||
private RestrictionSettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
|
||||
public class SecuritySettings implements SettingsClass {
|
||||
|
||||
@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("/reload support")
|
||||
public static final Property<Boolean> USE_RELOAD_COMMAND_SUPPORT =
|
||||
newProperty("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
|
||||
@Comment("Remove spam from console?")
|
||||
public static final Property<Boolean> REMOVE_SPAM_FROM_CONSOLE =
|
||||
newProperty("Security.console.noConsoleSpam", false);
|
||||
|
||||
@Comment("Remove passwords from console?")
|
||||
public static final Property<Boolean> REMOVE_PASSWORD_FROM_CONSOLE =
|
||||
newProperty("Security.console.removePassword", true);
|
||||
|
||||
@Comment("Player need to put a captcha when he fails too lot the password")
|
||||
public static final Property<Boolean> USE_CAPTCHA =
|
||||
newProperty("Security.captcha.useCaptcha", false);
|
||||
|
||||
@Comment("Max allowed tries before request a captcha")
|
||||
public static final Property<Integer> MAX_LOGIN_TRIES_BEFORE_CAPTCHA =
|
||||
newProperty("Security.captcha.maxLoginTry", 5);
|
||||
|
||||
@Comment("Captcha length")
|
||||
public static final Property<Integer> CAPTCHA_LENGTH =
|
||||
newProperty("Security.captcha.captchaLength", 5);
|
||||
|
||||
@Comment({"Kick players before stopping the server, that allow us to save position of players",
|
||||
"and all needed information correctly without any corruption."})
|
||||
public static final Property<Boolean> KICK_PLAYERS_BEFORE_STOPPING =
|
||||
newProperty("Security.stop.kickPlayersBeforeStopping", true);
|
||||
|
||||
@Comment("Minimum length of password")
|
||||
public static final Property<Integer> MIN_PASSWORD_LENGTH =
|
||||
newProperty("settings.security.minPasswordLength", 5);
|
||||
|
||||
@Comment("Maximum length of password")
|
||||
public static final Property<Integer> MAX_PASSWORD_LENGTH =
|
||||
newProperty("settings.security.passwordMaxLength", 30);
|
||||
|
||||
@Comment({
|
||||
"This is a very important option: every time a player joins the server,",
|
||||
"if they are registered, 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, a logged in 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 unLoggedinGroup: NotLogged"
|
||||
})
|
||||
public static final Property<String> UNLOGGEDIN_GROUP =
|
||||
newProperty("settings.security.unLoggedinGroup", "unLoggedinGroup");
|
||||
|
||||
@Comment({
|
||||
"Possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB,",
|
||||
"MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512,",
|
||||
"DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only)"
|
||||
})
|
||||
public static final Property<HashAlgorithm> PASSWORD_HASH =
|
||||
newProperty(HashAlgorithm.class, "settings.security.passwordHash", HashAlgorithm.SHA256);
|
||||
|
||||
@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({"If password checking return false, do we need to check with all",
|
||||
"other password algorithm to check an old password?",
|
||||
"AuthMe will update the password to the new password hash"})
|
||||
public static final Property<Boolean> SUPPORT_OLD_PASSWORD_HASH =
|
||||
newProperty("settings.security.supportOldPasswordHash", false);
|
||||
|
||||
@Comment({"Prevent unsafe passwords from being used; put them in lowercase!",
|
||||
"unsafePasswords:",
|
||||
"- '123456'",
|
||||
"- 'password'"})
|
||||
public static final Property<List<String>> UNSAFE_PASSWORDS =
|
||||
newProperty(STRING_LIST, "settings.security.unsafePasswords",
|
||||
"123456", "password", "qwerty", "12345", "54321");
|
||||
|
||||
private SecuritySettings() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class responsible for retrieving all {@link Property} fields
|
||||
* from {@link SettingsClass} implementations via reflection.
|
||||
*/
|
||||
public final class SettingsFieldRetriever {
|
||||
|
||||
/** The classes to scan for properties. */
|
||||
private static final List<Class<? extends SettingsClass>> CONFIGURATION_CLASSES = Arrays.asList(
|
||||
ConverterSettings.class, PluginSettings.class, RestrictionSettings.class,
|
||||
DatabaseSettings.class, EmailSettings.class, HooksSettings.class,
|
||||
ProtectionSettings.class, PurgeSettings.class, SecuritySettings.class,
|
||||
RegistrationSettings.class, BackupSettings.class);
|
||||
|
||||
private SettingsFieldRetriever() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan all given classes for their properties and return the generated {@link PropertyMap}.
|
||||
*
|
||||
* @return PropertyMap containing all found properties and their associated comments
|
||||
* @see #CONFIGURATION_CLASSES
|
||||
*/
|
||||
public static PropertyMap getAllPropertyFields() {
|
||||
PropertyMap properties = new PropertyMap();
|
||||
for (Class<?> clazz : CONFIGURATION_CLASSES) {
|
||||
Field[] declaredFields = clazz.getDeclaredFields();
|
||||
for (Field field : declaredFields) {
|
||||
Property property = getPropertyField(field);
|
||||
if (property != null) {
|
||||
properties.put(property, getCommentsForField(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static String[] getCommentsForField(Field field) {
|
||||
if (field.isAnnotationPresent(Comment.class)) {
|
||||
return field.getAnnotation(Comment.class).value();
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given field's value if it is a static {@link Property}.
|
||||
*
|
||||
* @param field The field's value to return
|
||||
* @return The property the field defines, or null if not applicable
|
||||
*/
|
||||
private static Property<?> getPropertyField(Field field) {
|
||||
field.setAccessible(true);
|
||||
if (field.isAccessible() && Property.class.equals(field.getType()) && Modifier.isStatic(field.getModifiers())) {
|
||||
try {
|
||||
return (Property) field.get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Could not fetch field '" + field.getName() + "' from class '"
|
||||
+ field.getDeclaringClass().getSimpleName() + "': " + StringUtils.formatException(e));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user