diff --git a/.checkstyle.xml b/.checkstyle.xml
index b92fc345c..d0f579dcc 100644
--- a/.checkstyle.xml
+++ b/.checkstyle.xml
@@ -1,7 +1,7 @@
+ "https://checkstyle.org/dtds/configuration_1_3.dtd">
diff --git a/.codeclimate.yml b/.codeclimate.yml
index 536899863..217a1b6b8 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -38,7 +38,6 @@ exclude_patterns:
- 'src/main/java/fr/xephi/authme/mail/OAuth2SaslClient.java'
- 'src/main/java/fr/xephi/authme/mail/OAuth2SaslClientFactory.java'
- 'src/main/java/fr/xephi/authme/security/crypts/PhpBB.java'
- - 'src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java'
- 'src/main/java/fr/xephi/authme/security/crypts/Wordpress.java'
# Don't check test classes
- 'src/test/java/**/*Test.java'
diff --git a/.gitignore b/.gitignore
index 9a8a9ebf9..1df043b94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ hs_err_pid*
# Include the project's code style settings file
!.idea/codeStyleSettings.xml
+!.idea/misc.xml
# File-based project format:
*.ipr
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 000000000..b9cd73845
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 863ffc7c2..c8e9e84a6 100644
--- a/README.md
+++ b/README.md
@@ -90,23 +90,28 @@ You can also create your own translation file and, if you want, you can share it
- **Dev resources:**
- JavaDocs
- Maven Repository
- ```xml
-
-
- codemc-repo
- https://repo.codemc.org/repository/maven-public/
-
-
-
-
-
- fr.xephi
- authme
- 5.6.0-SNAPSHOT
- provided
-
-
- ```
+ - Maven dependency usage:
+ ```xml
+
+ ...
+
+
+ codemc-repo
+ https://repo.codemc.org/repository/maven-public/
+
+
+ ...
+
+
+ fr.xephi
+ authme
+ 5.6.0-SNAPSHOT
+ provided
+
+
+ ...
+
+ ```
- **Statistics:**
![Graph](https://bstats.org/signatures/bukkit/AuthMe.svg)
diff --git a/pom.xml b/pom.xml
index 314ee62e1..9c2442a1b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -622,6 +622,12 @@
+
+ org.jetbrains
+ annotations
+ 17.0.0
+ provided
+ com.google.guava
diff --git a/samples/NewConfig.yml b/samples/NewConfig.yml
deleted file mode 100644
index c0b392c4b..000000000
--- a/samples/NewConfig.yml
+++ /dev/null
@@ -1,570 +0,0 @@
-# =======================================================================================================
-# _____ __ .__ _____ __________ .__ .___ .___
-# / _ \ __ ___/ |_| |__ / \ ____\______ \ ____ | | _________ __| _/____ __| _/
-# / /_\ \| | \ __| | \ / \ / \_/ __ \| __/ __ \| | / _ \__ \ / __ _/ __ \ / __ |
-# / | | | /| | | Y / Y \ ___/| | \ ___/| |_( <_> / __ \/ /_/ \ ___// /_/ |
-# \____|__ |____/ |__| |___| \____|__ /\___ |____|_ /\___ |____/\____(____ \____ |\___ \____ |
-# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
-#
-# =======================================================================================================
-#
-# Authme Main Configuration File.
-#
-# =======================================================================================================
-
-# Plugin infos (overwritten on start, just a simple way to find out your plugin version).
-authors: ${pluginAuthors}
-version: ${project.version}
-buildNumber: ${buildNumber}
-
-# Set this setting to true when you have configured the plugin,
-# when false the server will be stopped with a warning message.
-enabled: false
-
-# Database settings.
-data_source:
- # ===========================
- # Database general settings.
- # ===========================
-
- # Database backend (sqlite, mysql).
- backend: sqlite
- # Enable database queries caching, should improve performance.
- caching: true
-
- # ===========================
- # SqLite db parameters.
- # ===========================
-
- sqlite:
- # The name of the database storage file.
- filename: 'authme.db'
-
- # ===========================
- # MySql db parameters.
- # ===========================
-
- mysql:
- # Connection parameters.
- host: '127.0.0.1'
- port: 3306
- username: 'change_me'
- password: 'change_me'
- database: 'my_minecraft_server'
- tablename: 'authme'
-
- # Column names.
- column_names:
- id: id
- # Column for storing nicknames (ignore case nickname).
- name: username
- # Column for storing the realname (case sensitive nickname).
- real_name: realname
- # Column for storing passwords.
- password: password
- # Column for storing email addresses.
- email: email
- # Column for storing the authentication status (logged or not).
- login_status: isLogged
- # Column for storing player IPs.
- ip: ip
- # Column for storing lastlogins date and time.
- last_login_timestamp: lastlogin
- # Latest logout location of the players.
- last_location:
- world: world
- x: x
- y: y
- z: z
- # Enabled only if the bungeecord integration is activated.
- server: world
-
- # Support for registrations via WebInterfaces/CSM.
- # Disable some backend caching parameters.
- disableAggressiveCaching: false
-
-# Main settings
-settings:
-
- # ===========================
- # Bungeecord integration
- # ===========================
-
- bungeecord:
- # Enable bungeecord integration features
- enabled: true
-
- # Server name (must be unique, please use the name in the bungeecord configuration).
- # Use 'auto' for auto configuration (requires the bungeecord module).
- serverName: LoginLobby1
- # Keep the auth status when the player moves between servers.
- # Required if you're using the bungeecord module.
- keepAuthBetweenServers: true
-
- # Target server after login
- send_after_login:
- enabled: false
- message: ''
- delay: 5
- # Server name ("ServerName") or group ("G:GroupName")
- # Groups are avariable only when the bungeecord module is avariable.
- # If the server change fails the player will be kicked.
- target: Lobby1
- failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
- # Target server after logout
- send_after_logout:
- enabled: false
- message: ''
- delay: 5
- # Server name ("ServerName") or group ("G:GroupName")
- # Groups are avariable only when the bungeecord module is avariable.
- # If the server change fails the player will be kicked.
- target: LoginLobby1
- failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
-
- # Variables:
- # %p playername
- bungee_commands:
- player_command_after_register:
- enabled: false
- cmd: ''
- console_command_after_register:
- enabled: false
- cmd: 'alert %p joined for the first time the network!'
- player_command_after_login:
- enabled: false
- cmd: 'glist'
- console_command_after_login:
- enabled: false
- cmd: 'alert %p logged in correctly!'
- player_command_after_join:
- enabled: false
- cmd: ''
- console_command_after_join:
- enabled: false
- cmd: 'alert %p joined the network!'
- player_command_first_join:
- enabled: false
- cmd: ''
- console_command_first_join:
- enabled: false
- cmd: 'alert %p joined for the first time the network!'
-
- # ===========================
- # Sessions configuration.
- # ===========================
-
- sessions:
- # Enable sessions.
- # When a player is authenticated, his IP and his nickname is saved.
- # The next time the player will join the server, if his IP is the same
- # of the last time, and the timeout time hasn't expired, he will be
- # automatically authenticated.
- enabled: false
- # Session timeout.
- # 0 for unlimited time (Very dangerous, use it at your own risk!)
- # Consider that if player's ip has changed but the timeout hasn't
- # expired, player will be kicked out of the sever!
- timeout: 10
- # When enabled a player's session will expire if someone tries to
- # login with a different IP Address.
- expire_on_ip_change: true
-
- # ===========================
- # Registration settings.
- # ===========================
-
- registration:
- # After how many time unregistered players should be kicked?
- # Set to 0 to disable. (default: 30)
- timeout: 30
-
- nickname:
- min_length: 4
- max_lenght: 16
- # Regex syntax.
- allowed_characters: '[a-zA-Z0-9_]*'
-
- password:
- # Enable double check of password on registration:
- # /register
- double_check: true
- # Minimum password lenght.
- min_length: 5
- # Regex syntax.
- allowed_characters: '[\x21-\x7E]*'
- # Denied unsafe passwords.
- unsafePasswords:
- - '123456'
- - 'password'
- - 'qwerty'
- - '12345'
- - '54321'
-
- # ===========================
- # Login settings.
- # ===========================
-
- login:
- # After how many time unlogged players should be kicked?
- # Set to 0 to disable. (default: 30)
- timeout: 30
-
-
-
- # ===========================
- # Encryption parameters.
- # ===========================
-
- password_encryption:
- # The hashing algorithm.
- # 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 (developpers only).
- encryption_algorithm: SHA256
- # The salt length for the SALTED2MD5 and MD5(MD5(password)+salt) algorithms.
- md5_salt_length: 8
- # If password check fails try all the other hash algorithm.
- # AuthMe will update the password to the new passwordHash.
- enable_convertion: false
-
- # ===========================
- # Unlogged user restrictions.
- # ===========================
-
- unlogged_restrictions:
- # Deny chat messages send for unlogged users.
- deny_chat: true
- # Hide chat to unlogged users.
- # Only player messages, plugins will be able to send messages to the player anyway.
- hide_chat: false
-
- # Deny any command message not in the whitelist below.
- deny_commands: true
- command_whitelist:
- - /login
- - /register
- - /l
- - /reg
- - /email
- - /captcha
-
- movements:
- # Restrict player movements.
- restrict: true
- # Allowed radius.
- allowed_radius: 0
- # Should unlogged players have speed = 0?
- # After the login the walking/flying speeed will be reset to the default value.
- removeSpeed: true
-
- # End is there atm xD
-
- # This option will save the quit location of the players.
- SaveQuitLocation: false
- # Should not logged in players be teleported to the spawn?
- # After the authentication, if SaveQuitLocation is enabled,
- # they will be teleported back to their normal position.
- teleportUnAuthedToSpawn: false
-
- # If enabled, after the login, if the ForceSpawnOnTheseWorlds setting contains
- # the player's world, he will be teleported to the world spawnpoint.
- # The quit location of the player will be overwritten.
- # This is different from "teleportUnAuthedToSpawn" that teleports player
- # back to his quit location after the authentication.
- ForceSpawnLocOnJoinEnabled: false
- # WorldNames where we need to force the spawn location
- # Warning: This setting is Case Sensitive!
- ForceSpawnOnTheseWorlds:
- - world
- - world_nether
- - world_the_end
-
- # this is very important options,
- # every time player join the server,
- # if they are registered, AuthMe will switch him
- # to unLoggedInGroup, this
- # should prevent all major exploit.
- # So you can set up on your Permission Plugin
- # this special group with 0 permissions, or permissions to chat,
- # or permission to
- # send private message or all other perms that you want,
- # the better way is to set up
- # this group with few permissions,
- # so if player try to exploit some account,
- # they can
- # do anything except what you set in perm Group.
- # After a correct logged-in player will be
- # moved to his correct permissions group!
- # Pay attention group name is case sensitive,
- # so Admin is different from admin,
- # otherwise your group will be wiped,
- # and player join in default group []!
- # Example unLoggedinGroup: NotLogged
- unLoggedinGroup: unLoggedinGroup
-
- # ===========================
- # Address restrictions
- # ===========================
-
- # Max number of registrations per IP (default: 1)
- maxRegPerIp: 1
- # Maximum allowed number of Logins per IP, 0 to disable (default: 0)
- maxLoginPerIp: 0
- # Maximum allowed number of Joins per IP, 0 to disable (default: 0)
- maxJoinPerIp: 0
-
- # 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.
- ForceSingleSession: true
-
- # To activate the restricted user feature you need
- # to enable this option and configure the
- # AllowedRestrictedUser field.
- AllowRestrictedUser: false
- # The restricted user feature will kick players listed below
- # if they dont match of the defined ip address.
- # Example:
- # AllowedRestrictedUser:
- # - playername;127.0.0.1
- AllowedRestrictedUser:
- - playername;127.0.0.
- # Ban ip when the ip is not the ip registered in database
- banUnsafedIP: false
-
-
-
- # ===============================
- # Other restrictions
- # ===============================
-
- # Should we protect the player inventory before logging in?
- # Warning: Requires the latest version of ProtocolLib!
- ProtectInventoryBeforeLogIn: true
-
- # Should unregistered players be kicked immediately?
- kickNonRegistered: false
- # Should players be kicked on wrong password?
- kickOnWrongPassword: false
-
- # Should we display all other accounts of a player when he joins?
- # Required permission: authme.admin.accounts
- displayOtherAccounts: true
-
- # ===============================
- # Restrictions compatibility
- # ===============================
-
- # Spawn Priority. Avariable values : authme, essentials, multiverse, default
- spawnPriority: authme,essentials,multiverse,default
- # AuthMe will NEVER teleport players!
- noTeleport: false
-
- GameMode:
- # Do you want to set player's gamemode to survival when he joins?
- # This enables also the settings below.
- ForceSurvivalMode: false
- # Do you want to reset player's inventory if player joins with creative mode?
- ResetInventoryIfCreative: false
- # Do you want to force the survival mode ONLY after the /login process?
- ForceOnlyAfterLogin: false
-
- # sgdc3: Ok, our configuration is shit.... xD Today I will stop there
-
-
- registration:
- # enable registration on the server?
- enabled: true
- # Send every X seconds a message to a player to
- # remind him that he has to login/register
- messageInterval: 5
- # Only registered and logged in players can play.
- # See restrictions for exceptions
- force: true
- # Does we replace password registration by an Email registration method ?
- enableEmailRegistrationSystem: false
- # Enable double check of email when you register
- # when it's true, registration require that kind of command:
- # /register
- doubleEmailCheck: false
- # Do we force kicking player after a successful registration ?
- # Do not use with login feature below
- forceKickAfterRegister: false
- # Does AuthMe need to enforce a /login after a successful registration ?
- forceLoginAfterRegister: false
- unrestrictions:
- # below you can list all your account name, 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 CaseSensitive!
- UnrestrictedName: []
- # Message language, available : en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt
- messagesLanguage: en
- # Force these commands after /login, without any '/', use %p for replace with player name
- forceCommands: []
- # Force these commands after /login as a server console, without any '/', use %p for replace with player name
- forceCommandsAsConsole: []
- # Force these commands after /register, without any '/', use %p for replace with player name
- forceRegisterCommands: []
- # Force these commands after /register as a server console, without any '/', use %p for replace with player name
- forceRegisterCommandsAsConsole: []
- # Do we need to display the welcome message (welcome.txt) after a register 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
- useWelcomeMessage: true
- # Do we need to broadcast the welcome message to all server or only to the player? set true for server or false for player
- broadcastWelcomeMessage: false
- # Do we need to delay the join/leave message to be displayed only when the player is authenticated ?
- delayJoinMessage: false
- removeJoinMessage: false
- removeLeaveMessage: false
- # Do we need to add potion effect Blinding before login/register ?
- applyBlindEffect: false
-ExternalBoardOptions:
- # MySQL column for the salt , needed for some forum/cms support
- mySQLColumnSalt: ''
- # MySQL column for the group, needed for some forum/cms support
- mySQLColumnGroup: ''
- # -1 mean disabled. If u want that only
- # activated player can login in your server
- # u can put in this options the group number
- # of unactivated user, needed for some forum/cms support
- nonActivedUserGroup: -1
- # Other MySQL columns where we need to put the Username (case sensitive)
- mySQLOtherUsernameColumns: []
- # How much Log to Round needed in BCrypt(do not change it if you do not know what's your doing)
- bCryptLog2Round: 10
- # phpBB prefix defined during phpbb installation process
- phpbbTablePrefix: 'phpbb_'
- # phpBB activated group id , 2 is default registered group defined by phpbb
- phpbbActivatedGroupId: 2
- # WordPress prefix defined during WordPress installation process
- wordpressTablePrefix: 'wp_'
-permission:
- # Take care with this options, if you dont want
- # to use Vault and Group Switching of
- # AuthMe for unloggedIn players put true
- # below, default is false.
- EnablePermissionCheck: false
-BackupSystem:
- # Enable or Disable Automatic Backup
- ActivateBackup: false
- # set Backup at every start of Server
- OnServerStart: false
- # set Backup at every stop of Server
- OnServerStop: true
- # Windows only mysql installation Path
- MysqlWindowsPath: 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\'
-Security:
- SQLProblem:
- # Stop the server if we can't contact the sql database
- # Take care with this, if you set that to false,
- # AuthMe automatically disable and the server is not protected!
- stopServer: true
- ReloadCommand:
- # /reload support
- useReloadCommandSupport: true
- console:
- # Remove spam console
- noConsoleSpam: false
- captcha:
- # Player need to put a captcha when he fails too lot the password
- useCaptcha: false
- # Max allowed tries before request a captcha
- maxLoginTry: 5
- # Captcha length
- captchaLength: 5
-Converter:
- Rakamak:
- # Rakamak file name
- fileName: users.rak
- # Rakamak use ip ?
- useIP: false
- # IP file name for rakamak
- ipFileName: UsersIp.rak
- CrazyLogin:
- # CrazyLogin database file
- fileName: accounts.db
-Email:
- # Email SMTP server host
- mailSMTP: smtp.gmail.com
- # Email SMTP server port
- mailPort: 465
- # Email account that send the mail
- mailAccount: ''
- # Email account password
- mailPassword: ''
- # Custom SenderName, that replace the mailAccount name in the email
- mailSenderName: ''
- # Random password length
- RecoveryPasswordLength: 8
- # Email subject of password get
- mailSubject: 'Your new AuthMe Password'
- # Email text here
- mailText: 'Dear ,
This is your new AuthMe password for the server
:
Do not forget to change password after login! /changepassword newPassword'
- # Like maxRegPerIp but with email
- maxRegPerEmail: 1
- # Recall players to add an email ?
- recallPlayers: false
- # Delay in minute for the recall scheduler
- delayRecall: 5
- # Blacklist these domains for emails
- emailBlacklisted:
- - 10minutemail.com
- # WhiteList only these domains for emails
- emailWhitelisted: []
- # Do we need to send new password draw in an image ?
- generateImage: false
-Hooks:
- # Do we need to hook with multiverse for spawn checking?
- multiverse: true
- # Do we need to hook with BungeeCord for get the real Player ip ?
- bungeecord: false
- # Do we need to disable Essentials SocialSpy on join ?
- disableSocialSpy: true
- # Do we need to force /motd Essentials command on join ?
- useEssentialsMotd: false
- # Do we need to cache custom Attributes ?
- customAttributes: false
-Purge:
- # On Enable , does AuthMe need to purge automatically old accounts unused ?
- useAutoPurge: false
- # Number of Days an account become Unused
- daysBeforeRemovePlayer: 60
- # Do we need to remove the player.dat file during purge process ?
- removePlayerDat: false
- # Do we need to remove the Essentials/users/player.yml file during purge process ?
- removeEssentialsFile: false
- # World where are players.dat stores
- defaultWorld: 'world'
- # Do we need to remove LimitedCreative/inventories/player.yml , player_creative.yml files during purge process ?
- removeLimitedCreativesInventories: false
- # Do we need to remove the AntiXRayData/PlayerData/player file during purge process ?
- removeAntiXRayFile: false
- # Do we need to remove permissions ?
- removePermissions: false
-Protection:
- # Enable some servers protection ( country based login, antibot )
- enableProtection: false
- # Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes
- countries:
- - US
- - GB
- # Countries blacklisted automatically ( without any needed to enable protection )
- countriesBlacklist:
- - A1
- # Do we need to enable automatic antibot system?
- enableAntiBot: false
- # Max number of player allowed to login in 5 secs before enable AntiBot system automatically
- antiBotSensibility: 5
- # Duration in minutes of the antibot automatic system
- antiBotDuration: 10
-VeryGames:
- # These features are only available on VeryGames Server Provider
- enableIpCheck: false
diff --git a/samples/NewPlugin.yml b/samples/NewPlugin.yml
deleted file mode 100644
index f403da60b..000000000
--- a/samples/NewPlugin.yml
+++ /dev/null
@@ -1,199 +0,0 @@
-name: ${pluginName}
-authors: [${pluginAuthors}]
-website: ${project.url}
-description: ${project.description}
-main: ${mainClass}
-version: ${project.version}-b${buildNumber}
-softdepend:
- - Vault
- - PermissionsBukkit
- - PermissionsEX
- - EssentialsGroupManager
- - Multiverse-Core
- - Essentials
- - EssentialsSpawn
- - ProtocolLib
-commands:
- authme:
- description: AuthMe admin commands
- usage: '/authme reload|register playername password|changepassword playername password|unregister playername|version|converter datatype'
- permission: authme.admin
- register:
- description: Register an account
- usage: /register password confirmpassword
- aliases: [reg]
- permission: authme.player.register
- login:
- description: Login into a account
- usage: /login password
- aliases: [l,log]
- permission: authme.player.login
- changepassword:
- description: Change password of a account
- usage: /changepassword oldPassword newPassword
- permission: authme.player.changepassword
- logout:
- description: Logout from the server
- usage: /logout
- permission: authme.player.logout
- unregister:
- description: unregister your account
- usage: /unregister password
- permission: authme.player.unregister
- email:
- description: Add Email or recover password
- usage: '/email add your@email.com your@email.com|change oldEmail newEmail|recovery your@email.com'
- permission: authme.player.email
- captcha:
- description: Captcha command
- usage: /captcha theCaptcha
- permission: authme.player.captcha
-permissions:
- authme.canbeforced:
- description: Allow the user to be forced-logged via API
- default: true
- authme.player:
- description: Gives access to all authme player commands
- default: true
- children:
- authme.player.login: true
- authme.player.logout: true
- authme.player.register: true
- authme.player.unregister: true
- authme.player.changepassword: true
- authme.player.captcha: true
- authme.player.email: true
- authme.player.register:
- description: Register your account
- default: false
- authme.player.unregister:
- description: Unregister your account
- default: false
- authme.player.login:
- description: Login into your account
- default: false
- authme.player.logout:
- description: Logout from your account
- default: false
- authme.player.changepassword:
- description: Change password of your account
- default: false
- authme.player.email:
- description: Gives access to player's email commands
- default: false
- children:
- authme.player.email.add: true
- authme.player.email.change: true
- authme.player.email.recover: true
- authme.player.email.add:
- description: Add an email to your account
- default: false
- authme.player.email.change:
- description: Change email of your account
- default: false
- authme.player.email.recover:
- description: Recover your account
- default: false
- authme.player.captcha:
- description: Captcha command
- default: false
- authme.admin:
- description: Gives access to all authme admin commands
- default: op
- children:
- authme.admin.forcelogin: true
- authme.admin.forcelogout: true
- authme.admin.register: true
- authme.admin.unregister: true
- authme.admin.changemail: true
- authme.admin.changepassword: true
- authme.admin.lastlogin: true
- authme.admin.accounts: true
- authme.admin.getemail: true
- authme.admin.getip: true
- authme.admin.setspawn: true
- authme.admin.spawn: true
- authme.admin.setfirstspawn: true
- authme.admin.firstspawn: true
- authme.admin.purge: true
- authme.admin.purgebannedplayers: true
- authme.admin.purgelastpos: true
- authme.admin.converter: true
- authme.admin.reload: true
- authme.admin.switchantibot: true
- authme.admin.seeotheraccounts: true
- authme.admin.register:
- description: Register an account
- default: false
- authme.admin.unregister:
- description: Unregister an account
- default: false
- authme.admin.forcelogin:
- description: Force login for that player
- default: false
- authme.admin.forcelogout:
- description: Force logout for that player
- default: false
- authme.admin.changepassword:
- description: Change the password of an account
- default: false
- authme.admin.getemail:
- description: Get last email about a player
- default: false
- authme.admin.changeemail:
- description: Change a player email
- default: false
- authme.admin.accounts:
- description: Display Players Accounts
- default: false
- authme.admin.seeotheraccounts:
- description: Display other accounts about a player when he logs in
- default: false
- authme.admin.lastlogin:
- description: Get last login date about a player
- default: false
- authme.admin.getip:
- description: Get IP from a player (fake and real)
- default: false
- authme.admin.setspawn:
- description: Set the AuthMe spawn point
- default: false
- authme.admin.spawn:
- description: Teleport to AuthMe spawn point
- default: false
- authme.admin.setfirstspawn:
- description: Set the AuthMe First Spawn Point
- default: false
- authme.admin.firstspawn:
- description: Teleport to AuthMe First Spawn Point
- default: false
- authme.admin.switchantibot:
- description: Switch AntiBot mode on/off
- default: false
- authme.admin.purge:
- description: Database purge command
- default: false
- authme.admin.purgebannedplayers:
- description: Purge banned players
- default: false
- authme.admin.purgelastpos:
- description: Purge last position of a player/players
- default: false
- authme.admin.converter:
- description: Allow the /authme converter command
- default: false
- authme.admin.reload:
- description: Reload the plugin
- default: false
- authme.vip:
- description: Allow vip slot when the server is full
- default: false
- authme.bypassantibot:
- description: Bypass the AntiBot check
- default: false
- authme.allowmultipleaccounts:
- description: Allow more accounts for same ip
- default: false
- authme.bypassforcesurvival:
- description: Bypass all ForceSurvival features
- default: false
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index 045d1ee97..3984a2abf 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -2,7 +2,6 @@
import ch.jalu.injector.Injector;
import ch.jalu.injector.InjectorBuilder;
-import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.DataSource;
@@ -32,6 +31,7 @@
import fr.xephi.authme.task.CleanupTask;
import fr.xephi.authme.task.purge.PurgeService;
import fr.xephi.authme.util.ExceptionUtils;
+import fr.xephi.authme.util.FileUtils;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -40,6 +40,7 @@
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.scheduler.BukkitScheduler;
+import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.function.Consumer;
@@ -79,7 +80,6 @@ public AuthMe() {
/*
* Constructor for unit testing.
*/
- @VisibleForTesting
AuthMe(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file);
}
@@ -89,6 +89,7 @@ public AuthMe() {
*
* @return The plugin's name.
*/
+ @NotNull
public static String getPluginName() {
return PLUGIN_NAME;
}
@@ -98,6 +99,7 @@ public static String getPluginName() {
*
* @return The plugin's version.
*/
+ @NotNull
public static String getPluginVersion() {
return pluginVersion;
}
@@ -107,6 +109,7 @@ public static String getPluginVersion() {
*
* @return The plugin's build number.
*/
+ @NotNull
public static String getPluginBuildNumber() {
return pluginBuildNumber;
}
@@ -182,7 +185,7 @@ public void onEnable() {
*
* @param versionRaw the version as given by the plugin description file
*/
- private static void loadPluginInfo(String versionRaw) {
+ private static void loadPluginInfo(@NotNull String versionRaw) {
int index = versionRaw.lastIndexOf("-");
if (index != -1) {
pluginVersion = versionRaw.substring(0, index);
@@ -198,7 +201,7 @@ private static void loadPluginInfo(String versionRaw) {
*/
private void initialize() {
// Create plugin folder
- getDataFolder().mkdir();
+ FileUtils.createDirectoryOrFail(getDataFolder());
// Create injector, provide elements from the Bukkit environment and register providers
injector = new InjectorBuilder()
@@ -241,7 +244,7 @@ private void initialize() {
*
* @param injector the injector
*/
- void instantiateServices(Injector injector) {
+ void instantiateServices(@NotNull Injector injector) {
database = injector.getSingleton(DataSource.class);
bukkitService = injector.getSingleton(BukkitService.class);
commandHandler = injector.getSingleton(CommandHandler.class);
@@ -259,7 +262,7 @@ void instantiateServices(Injector injector) {
*
* @param injector the injector
*/
- void registerEventListeners(Injector injector) {
+ void registerEventListeners(@NotNull Injector injector) {
// Get the plugin manager instance
PluginManager pluginManager = getServer().getPluginManager();
@@ -332,8 +335,8 @@ public void onDisable() {
* @return True if the command was executed, false otherwise.
*/
@Override
- public boolean onCommand(CommandSender sender, Command cmd,
- String commandLabel, String[] args) {
+ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd,
+ @NotNull String commandLabel, String[] args) {
// Make sure the command handler has been initialized
if (commandHandler == null) {
getLogger().severe("AuthMe command handler is not available");
@@ -344,6 +347,7 @@ public boolean onCommand(CommandSender sender, Command cmd,
return commandHandler.processCommand(sender, commandLabel, args);
}
+ @NotNull
private String getServerNameVersionSafe() {
try {
Server server = getServer();
@@ -352,4 +356,5 @@ private String getServerNameVersionSafe() {
return "-";
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/ConsoleLogger.java b/src/main/java/fr/xephi/authme/ConsoleLogger.java
index 88798ced0..afdb8f4a1 100644
--- a/src/main/java/fr/xephi/authme/ConsoleLogger.java
+++ b/src/main/java/fr/xephi/authme/ConsoleLogger.java
@@ -1,11 +1,14 @@
package fr.xephi.authme;
-import com.google.common.base.Throwables;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.ExceptionUtils;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.ConsoleCommandSender;
+import org.jetbrains.annotations.NotNull;
import java.io.Closeable;
import java.io.File;
@@ -42,7 +45,9 @@ public final class ConsoleLogger {
private static OutputStreamWriter fileWriter;
// Individual state
+ @NotNull
private final String name;
+ @NotNull
private LogLevel logLevel = LogLevel.INFO;
/**
@@ -50,7 +55,7 @@ public final class ConsoleLogger {
*
* @param name the name of this logger (the fully qualified class name using it)
*/
- public ConsoleLogger(String name) {
+ public ConsoleLogger(@NotNull String name) {
this.name = name;
}
@@ -58,7 +63,7 @@ public ConsoleLogger(String name) {
// Configurations
// --------
- public static void initialize(Logger logger, File logFile) {
+ public static void initialize(@NotNull Logger logger, @NotNull File logFile) {
ConsoleLogger.logger = logger;
ConsoleLogger.logFile = logFile;
}
@@ -68,7 +73,7 @@ public static void initialize(Logger logger, File logFile) {
*
* @param settings the settings to read from
*/
- public static void initializeSharedSettings(Settings settings) {
+ public static void initializeSharedSettings(@NotNull Settings settings) {
boolean useLogging = settings.getProperty(SecuritySettings.USE_LOGGING);
if (useLogging) {
initializeFileWriter();
@@ -82,14 +87,16 @@ public static void initializeSharedSettings(Settings settings) {
*
* @param settings the settings to read from
*/
- public void initializeSettings(Settings settings) {
+ public void initializeSettings(@NotNull Settings settings) {
this.logLevel = settings.getProperty(PluginSettings.LOG_LEVEL);
}
+ @NotNull
public LogLevel getLogLevel() {
return logLevel;
}
+ @NotNull
public String getName() {
return name;
}
@@ -104,7 +111,7 @@ public String getName() {
*
* @param message The message to log
*/
- public void warning(String message) {
+ public void warning(@NotNull String message) {
logger.warning(message);
writeLog("[WARN] " + message);
}
@@ -116,9 +123,9 @@ public void warning(String message) {
* @param message The message to accompany the exception
* @param th The Throwable to log
*/
- public void logException(String message, Throwable th) {
+ public void logException(@NotNull String message, @NotNull Throwable th) {
warning(message + " " + ExceptionUtils.formatException(th));
- writeLog(Throwables.getStackTraceAsString(th));
+ writeLog(ExceptionUtils.getStackTraceAsString(th));
}
/**
@@ -126,7 +133,7 @@ public void logException(String message, Throwable th) {
*
* @param message The message to log
*/
- public void info(String message) {
+ public void info(@NotNull String message) {
logger.info(message);
writeLog("[INFO] " + message);
}
@@ -139,13 +146,45 @@ public void info(String message) {
*
* @param message The message to log
*/
- public void fine(String message) {
+ public void fine(@NotNull String message) {
if (logLevel.includes(LogLevel.FINE)) {
logger.info(message);
writeLog("[FINE] " + message);
}
}
+ /**
+ * Sends a message to the given sender (null safe), and logs the message to the console.
+ * This method is aware that the command sender might be the console sender and avoids
+ * displaying the message twice in this case.
+ *
+ * @param sender the sender to inform
+ * @param message the message to log and send
+ */
+ public void logAndSendMessage(CommandSender sender, @NotNull String message) {
+ info(message);
+ // Make sure sender is not console user, which will see the message from ConsoleLogger already
+ if (sender != null && !(sender instanceof ConsoleCommandSender)) {
+ sender.sendMessage(message);
+ }
+ }
+
+ /**
+ * Sends a warning to the given sender (null safe), and logs the warning to the console.
+ * This method is aware that the command sender might be the console sender and avoids
+ * displaying the message twice in this case.
+ *
+ * @param sender the sender to inform
+ * @param message the warning to log and send
+ */
+ public void logAndSendWarning(CommandSender sender, @NotNull String message) {
+ warning(message);
+ // Make sure sender is not console user, which will see the message from ConsoleLogger already
+ if (sender != null && !(sender instanceof ConsoleCommandSender)) {
+ sender.sendMessage(ChatColor.RED + message);
+ }
+ }
+
// --------
// Debug log methods
// --------
@@ -158,7 +197,7 @@ public void fine(String message) {
*
* @param message The message to log
*/
- public void debug(String message) {
+ public void debug(@NotNull String message) {
if (logLevel.includes(LogLevel.DEBUG)) {
logAndWriteWithDebugPrefix(message);
}
@@ -171,7 +210,7 @@ public void debug(String message) {
* @param param1 parameter to replace in the message
*/
// Avoids array creation if DEBUG level is disabled
- public void debug(String message, Object param1) {
+ public void debug(@NotNull String message, Object param1) {
if (logLevel.includes(LogLevel.DEBUG)) {
debug(message, new Object[]{param1});
}
@@ -185,7 +224,7 @@ public void debug(String message, Object param1) {
* @param param2 second param to replace in message
*/
// Avoids array creation if DEBUG level is disabled
- public void debug(String message, Object param1, Object param2) {
+ public void debug(@NotNull String message, Object param1, Object param2) {
if (logLevel.includes(LogLevel.DEBUG)) {
debug(message, new Object[]{param1, param2});
}
@@ -197,7 +236,7 @@ public void debug(String message, Object param1, Object param2) {
* @param message the message
* @param params the params to replace in the message
*/
- public void debug(String message, Object... params) {
+ public void debug(@NotNull String message, Object... params) {
if (logLevel.includes(LogLevel.DEBUG)) {
logAndWriteWithDebugPrefix(MessageFormat.format(message, params));
}
@@ -208,13 +247,13 @@ public void debug(String message, Object... params) {
*
* @param msgSupplier the message supplier
*/
- public void debug(Supplier msgSupplier) {
+ public void debug(@NotNull Supplier msgSupplier) {
if (logLevel.includes(LogLevel.DEBUG)) {
logAndWriteWithDebugPrefix(msgSupplier.get());
}
}
- private void logAndWriteWithDebugPrefix(String message) {
+ private void logAndWriteWithDebugPrefix(@NotNull String message) {
String debugMessage = "[DEBUG] " + message;
logger.info(debugMessage);
writeLog(debugMessage);
@@ -244,7 +283,7 @@ public static void closeFileWriter() {
*
* @param message The message to write to the log
*/
- private static void writeLog(String message) {
+ private static void writeLog(@NotNull String message) {
if (fileWriter != null) {
String dateTime = DATE_FORMAT.format(LocalDateTime.now());
try {
@@ -284,4 +323,5 @@ private static void initializeFileWriter() {
}
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java
index fcc3ce611..4429a0541 100644
--- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java
+++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java
@@ -445,7 +445,7 @@ private CommandDescription buildAuthMeBaseCommand() {
.labels("converter", "convert", "conv")
.description("Converter command")
.detailedDescription("Converter command for AuthMeReloaded.")
- .withArgument("job", "Conversion job: xauth / crazylogin / rakamak / "
+ .withArgument("job", "Conversion job: crazylogin / rakamak / "
+ "royalauth / vauth / sqliteToSql / mysqlToSqlite / loginsecurity", OPTIONAL)
.permission(AdminPermission.CONVERTER)
.executableCommand(ConverterCommand.class)
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java
index fd0a73513..1467b2ac0 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java
@@ -13,7 +13,6 @@
import fr.xephi.authme.datasource.converter.RoyalAuthConverter;
import fr.xephi.authme.datasource.converter.SqliteToSql;
import fr.xephi.authme.datasource.converter.VAuthConverter;
-import fr.xephi.authme.datasource.converter.XAuthConverter;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService;
@@ -81,7 +80,6 @@ private static Class extends Converter> getConverterClassFromArgs(List
*/
private static Map> getConverters() {
return ImmutableSortedMap.>naturalOrder()
- .put("xauth", XAuthConverter.class)
.put("crazylogin", CrazyLoginConverter.class)
.put("rakamak", RakamakConverter.class)
.put("royalauth", RoyalAuthConverter.class)
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/GetIpCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/GetIpCommand.java
index 2e00c65e9..3aedeb933 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/GetIpCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/GetIpCommand.java
@@ -25,7 +25,7 @@ public void executeCommand(CommandSender sender, List arguments) {
Player player = bukkitService.getPlayerExact(playerName);
PlayerAuth auth = dataSource.getAuth(playerName);
- if (player != null) {
+ if (player != null && player.getAddress() != null) {
sender.sendMessage("Current IP of " + player.getName() + " is " + PlayerUtils.getPlayerIp(player)
+ ":" + player.getAddress().getPort());
}
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommand.java
index 82b109cc3..fa3ae58f6 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommand.java
@@ -29,9 +29,12 @@ public void executeCommand(CommandSender sender, List arguments) {
Set bannedPlayers = bukkitService.getBannedPlayers();
Set namedBanned = new HashSet<>(bannedPlayers.size());
for (OfflinePlayer offlinePlayer : bannedPlayers) {
+ if (offlinePlayer.getName() == null) {
+ continue;
+ }
namedBanned.add(offlinePlayer.getName().toLowerCase());
}
- purgeService.purgePlayers(sender, namedBanned, bannedPlayers.toArray(new OfflinePlayer[bannedPlayers.size()]));
+ purgeService.purgePlayers(sender, namedBanned, bannedPlayers.toArray(new OfflinePlayer[0]));
}
}
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeCommand.java
index 1538061e9..d77e4fcb5 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeCommand.java
@@ -1,8 +1,8 @@
package fr.xephi.authme.command.executable.authme;
-import com.google.common.primitives.Ints;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.task.purge.PurgeService;
+import fr.xephi.authme.util.Utils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -27,7 +27,7 @@ public void executeCommand(CommandSender sender, List arguments) {
String daysStr = arguments.get(0);
// Convert the days string to an integer value, and make sure it's valid
- Integer days = Ints.tryParse(daysStr);
+ Integer days = Utils.tryInteger(daysStr);
if (days == null) {
sender.sendMessage(ChatColor.RED + "The value you've entered is invalid!");
return;
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java
index 84de195c5..9ae7fda80 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java
@@ -56,7 +56,7 @@ public void executeCommand(CommandSender sender, List arguments) {
// We do not change database type for consistency issues, but we'll output a note in the logs
if (!settings.getProperty(DatabaseSettings.BACKEND).equals(dataSource.getType())) {
- Utils.logAndSendMessage(sender, "Note: cannot change database type during /authme reload");
+ logger.logAndSendMessage(sender, "Note: cannot change database type during /authme reload");
}
performReloadOnServices();
commonService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
@@ -69,9 +69,10 @@ public void executeCommand(CommandSender sender, List arguments) {
private void performReloadOnServices() {
reloadableStore.retrieveAllOfType()
- .forEach(r -> r.reload());
+ .forEach(Reloadable::reload);
settingsDependentStore.retrieveAllOfType()
.forEach(s -> s.reload(settings));
}
+
}
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java
index e8a15b795..d2764d65e 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java
@@ -61,12 +61,8 @@ public void execute(CommandSender sender, List arguments) {
Player player = bukkitService.getPlayerExact(playerName);
if (player == null) {
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName);
- if (offlinePlayer == null) {
- sender.sendMessage(ChatColor.DARK_RED + "Player '" + playerName + "' does not exist");
- } else {
- sender.sendMessage("Player '" + playerName + "' not online; checking with offline player");
- performPermissionCheck(offlinePlayer, permissionNode, permissionsManager::hasPermissionOffline, sender);
- }
+ sender.sendMessage("Player '" + playerName + "' not online; checking with offline player");
+ performPermissionCheck(offlinePlayer, permissionNode, permissionsManager::hasPermissionOffline, sender);
} else {
performPermissionCheck(player, permissionNode, permissionsManager::hasPermission, sender);
}
diff --git a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java
index 23aa8116d..661d2ba62 100644
--- a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java
+++ b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java
@@ -73,7 +73,13 @@ public int getGroupId() {
return groupId;
}
+ /**
+ * Sets the player's auth quit location.
+ *
+ * @param location the quit location
+ */
public void setQuitLocation(Location location) {
+ Objects.requireNonNull(location.getWorld(), "world not loaded!");
x = location.getBlockX();
y = location.getBlockY();
z = location.getBlockZ();
@@ -300,6 +306,7 @@ public Builder lastIp(String lastIp) {
* @return this builder instance
*/
public Builder location(Location location) {
+ Objects.requireNonNull(location.getWorld(), "world not loaded!");
this.x = location.getX();
this.y = location.getY();
this.z = location.getZ();
diff --git a/src/main/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManager.java b/src/main/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManager.java
index 3612e6797..e9708aea9 100644
--- a/src/main/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManager.java
+++ b/src/main/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManager.java
@@ -66,6 +66,7 @@ void registerMessageTask(Player player, LimboPlayer limbo, LimboMessageType mess
*/
void registerTimeoutTask(Player player, LimboPlayer limbo) {
final int timeout = settings.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
+ //noinspection ConstantConditions Inspection error!
if (timeout > 0) {
String message = messages.retrieveSingle(player, MessageKey.LOGIN_TIMEOUT_ERROR);
BukkitTask task = bukkitService.runTaskLater(new TimeoutTask(player, message, playerCache), timeout);
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java b/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java
index 9708ce884..025dd005a 100644
--- a/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java
+++ b/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java
@@ -1,6 +1,5 @@
package fr.xephi.authme.data.limbo.persistence;
-import com.google.common.io.Files;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -19,6 +18,7 @@
import java.io.FileWriter;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -115,7 +115,7 @@ private Map readLimboPlayers(File file) {
}
try {
- return gson.fromJson(Files.asCharSource(file, StandardCharsets.UTF_8).read(), LIMBO_MAP_TYPE);
+ return gson.fromJson(new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8), LIMBO_MAP_TYPE);
} catch (Exception e) {
logger.logException("Failed reading '" + file + "':", e);
}
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java b/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java
index 9772ec064..205b887ab 100644
--- a/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java
+++ b/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java
@@ -1,6 +1,5 @@
package fr.xephi.authme.data.limbo.persistence;
-import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import fr.xephi.authme.ConsoleLogger;
@@ -15,6 +14,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
/**
* Saves LimboPlayer objects as JSON into individual files.
@@ -48,7 +48,7 @@ public LimboPlayer getLimboPlayer(Player player) {
}
try {
- String str = Files.asCharSource(file, StandardCharsets.UTF_8).read();
+ String str = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
return gson.fromJson(str, LimboPlayer.class);
} catch (IOException e) {
logger.logException("Could not read player data on disk for '" + player.getName() + "'", e);
@@ -61,9 +61,8 @@ public void saveLimboPlayer(Player player, LimboPlayer limboPlayer) {
String id = player.getUniqueId().toString();
try {
File file = new File(cacheDir, id + File.separator + "data.json");
- Files.createParentDirs(file);
- Files.touch(file);
- Files.write(gson.toJson(limboPlayer), file, StandardCharsets.UTF_8);
+ FileUtils.createDirectoryOrFail(file);
+ Files.write(file.toPath(), gson.toJson(limboPlayer).getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
logger.logException("Failed to write " + player.getName() + " data:", e);
}
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java b/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java
index 5f9b40ede..1f8bac434 100644
--- a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java
+++ b/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java
@@ -9,6 +9,7 @@
import org.bukkit.Location;
import java.lang.reflect.Type;
+import java.util.Objects;
/**
* Converts a LimboPlayer to a JsonElement.
@@ -36,7 +37,7 @@ class LimboPlayerSerializer implements JsonSerializer {
public JsonElement serialize(LimboPlayer limboPlayer, Type type, JsonSerializationContext context) {
Location loc = limboPlayer.getLocation();
JsonObject locationObject = new JsonObject();
- locationObject.addProperty(LOC_WORLD, loc.getWorld().getName());
+ locationObject.addProperty(LOC_WORLD, Objects.requireNonNull(loc.getWorld()).getName());
locationObject.addProperty(LOC_X, loc.getX());
locationObject.addProperty(LOC_Y, loc.getY());
locationObject.addProperty(LOC_Z, loc.getZ());
diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
index e1418dcaf..b40948f5f 100644
--- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
+++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
@@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executors;
@@ -65,8 +66,8 @@ public ListenableFuture> reload(final String key, Optional<
});
}
- public LoadingCache> getCachedAuths() {
- return cachedAuths;
+ public Map> getCachedAuths() {
+ return cachedAuths.asMap();
}
@Override
@@ -292,8 +293,10 @@ public void invalidateCache(String playerName) {
cachedAuths.invalidate(playerName);
}
+ @SuppressWarnings("OptionalAssignedToNull")
@Override
public void refreshCache(String playerName) {
+ // We are actually checking if the entry is cached
if (cachedAuths.getIfPresent(playerName) != null) {
cachedAuths.refresh(playerName);
}
diff --git a/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java b/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java
index b4a2a577b..d2fb50e36 100644
--- a/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java
+++ b/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java
@@ -1,6 +1,5 @@
package fr.xephi.authme.datasource;
-import com.google.common.io.Files;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
@@ -10,6 +9,8 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
@@ -72,7 +73,7 @@ private String createBackup() {
String backupName = "backup-" + databaseName + FileUtils.createCurrentTimeString() + ".db";
File backup = new File(backupDirectory, backupName);
try {
- Files.copy(sqLite, backup);
+ Files.copy(sqLite.toPath(), backup.toPath(), StandardCopyOption.REPLACE_EXISTING);
return backupName;
} catch (IOException e) {
throw new IllegalStateException("Failed to create SQLite backup before migration", e);
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java
index fdced2fa4..1e898f530 100644
--- a/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java
+++ b/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java
@@ -10,8 +10,6 @@
import java.util.ArrayList;
import java.util.List;
-import static fr.xephi.authme.util.Utils.logAndSendMessage;
-
/**
* Converts from one AuthMe data source type to another.
*
@@ -53,7 +51,7 @@ public void execute(CommandSender sender) {
try {
source = getSource();
} catch (Exception e) {
- logAndSendMessage(sender, "The data source to convert from could not be initialized");
+ logger.logAndSendMessage(sender, "The data source to convert from could not be initialized");
logger.logException("Could not initialize source:", e);
return;
}
@@ -70,10 +68,10 @@ public void execute(CommandSender sender) {
}
if (!skippedPlayers.isEmpty()) {
- logAndSendMessage(sender, "Skipped conversion for players which were already in "
+ logger.logAndSendMessage(sender, "Skipped conversion for players which were already in "
+ destinationType + ": " + String.join(", ", skippedPlayers));
}
- logAndSendMessage(sender, "Database successfully converted from " + source.getType()
+ logger.logAndSendMessage(sender, "Database successfully converted from " + source.getType()
+ " to " + destinationType);
}
@@ -82,4 +80,5 @@ public void execute(CommandSender sender) {
* @throws Exception during initialization of source
*/
protected abstract S getSource() throws Exception;
+
}
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java
index 5f74ec1e8..04789b1f7 100644
--- a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java
+++ b/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java
@@ -25,8 +25,6 @@
import java.util.Optional;
import java.util.UUID;
-import static fr.xephi.authme.util.Utils.logAndSendMessage;
-
/**
* Converts data from LoginSecurity to AuthMe.
*/
@@ -104,9 +102,9 @@ private void migrateData(CommandSender sender, ResultSet resultSet) throws SQLEx
}
}
- logAndSendMessage(sender, "Migrated " + successfulSaves + " accounts successfully from LoginSecurity");
+ logger.logAndSendMessage(sender, "Migrated " + successfulSaves + " accounts successfully from LoginSecurity");
if (!skippedPlayers.isEmpty()) {
- logAndSendMessage(sender, "Skipped conversion for players which were already in AuthMe: "
+ logger.logAndSendMessage(sender, "Skipped conversion for players which were already in AuthMe: "
+ String.join(", ", skippedPlayers));
}
}
@@ -205,4 +203,5 @@ private Connection createMySqlConnection() {
return null;
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java
index b69fe688d..38631eb19 100644
--- a/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java
+++ b/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java
@@ -88,7 +88,7 @@ public void execute(CommandSender sender) {
database.saveAuth(auth);
database.updateSession(auth);
}
- Utils.logAndSendMessage(sender, "Rakamak database has been imported successfully");
+ logger.logAndSendMessage(sender, "Rakamak database has been imported successfully");
} catch (IOException ex) {
logger.logException("Can't open the rakamak database file! Does it exist?", ex);
}
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java
index 7c45aebfa..394586a1c 100644
--- a/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java
+++ b/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java
@@ -34,6 +34,9 @@ public class RoyalAuthConverter implements Converter {
@Override
public void execute(CommandSender sender) {
for (OfflinePlayer player : plugin.getServer().getOfflinePlayers()) {
+ if (player.getName() == null) {
+ continue;
+ }
try {
String name = player.getName().toLowerCase();
File file = new File(makePath(".", "plugins", "RoyalAuth", "userdata", name + ".yml"));
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/XAuthConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/XAuthConverter.java
deleted file mode 100644
index 928566583..000000000
--- a/src/main/java/fr/xephi/authme/datasource/converter/XAuthConverter.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package fr.xephi.authme.datasource.converter;
-
-import de.luricos.bukkit.xAuth.database.DatabaseTables;
-import de.luricos.bukkit.xAuth.utils.xAuthLog;
-import de.luricos.bukkit.xAuth.xAuth;
-import fr.xephi.authme.data.auth.PlayerAuth;
-import fr.xephi.authme.datasource.DataSource;
-import fr.xephi.authme.initialization.DataFolder;
-import fr.xephi.authme.util.Utils;
-import org.bukkit.command.CommandSender;
-import org.bukkit.plugin.PluginManager;
-
-import javax.inject.Inject;
-import java.io.File;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import static fr.xephi.authme.util.FileUtils.makePath;
-
-public class XAuthConverter implements Converter {
-
- @Inject
- @DataFolder
- private File dataFolder;
- @Inject
- private DataSource database;
- @Inject
- private PluginManager pluginManager;
-
- XAuthConverter() {
- }
-
- @Override
- public void execute(CommandSender sender) {
- try {
- Class.forName("de.luricos.bukkit.xAuth.xAuth");
- convert(sender);
- } catch (ClassNotFoundException ce) {
- sender.sendMessage("xAuth has not been found, please put xAuth.jar in your plugin folder and restart!");
- }
- }
-
- private void convert(CommandSender sender) {
- if (pluginManager.getPlugin("xAuth") == null) {
- sender.sendMessage("[AuthMe] xAuth plugin not found");
- return;
- }
- //TODO ljacqu 20160702: xAuthDb is not used except for the existence check -- is this intended?
- File xAuthDb = new File(dataFolder.getParent(), makePath("xAuth", "xAuth.h2.db"));
- if (!xAuthDb.exists()) {
- sender.sendMessage("[AuthMe] xAuth H2 database not found, checking for MySQL or SQLite data...");
- }
- List players = getXAuthPlayers();
- if (Utils.isCollectionEmpty(players)) {
- sender.sendMessage("[AuthMe] Error while importing xAuthPlayers: did not find any players");
- return;
- }
- sender.sendMessage("[AuthMe] Starting import...");
-
- for (int id : players) {
- String pl = getIdPlayer(id);
- String psw = getPassword(id);
- if (psw != null && !psw.isEmpty() && pl != null) {
- PlayerAuth auth = PlayerAuth.builder()
- .name(pl.toLowerCase())
- .realName(pl)
- .password(psw, null).build();
- database.saveAuth(auth);
- }
- }
- sender.sendMessage("[AuthMe] Successfully converted from xAuth database");
- }
-
- private String getIdPlayer(int id) {
- String realPass = "";
- Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- String sql = String.format("SELECT `playername` FROM `%s` WHERE `id` = ?",
- xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
- ps = conn.prepareStatement(sql);
- ps.setInt(1, id);
- rs = ps.executeQuery();
- if (!rs.next()) {
- return null;
- }
- realPass = rs.getString("playername").toLowerCase();
- } catch (SQLException e) {
- xAuthLog.severe("Failed to retrieve name for account: " + id, e);
- return null;
- } finally {
- xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
- }
- return realPass;
- }
-
- private List getXAuthPlayers() {
- List xP = new ArrayList<>();
- Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- String sql = String.format("SELECT * FROM `%s`",
- xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
- ps = conn.prepareStatement(sql);
- rs = ps.executeQuery();
- while (rs.next()) {
- xP.add(rs.getInt("id"));
- }
- } catch (SQLException e) {
- xAuthLog.severe("Cannot import xAuthPlayers", e);
- return new ArrayList<>();
- } finally {
- xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
- }
- return xP;
- }
-
- private String getPassword(int accountId) {
- String realPass = "";
- Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- String sql = String.format("SELECT `password`, `pwtype` FROM `%s` WHERE `id` = ?",
- xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
- ps = conn.prepareStatement(sql);
- ps.setInt(1, accountId);
- rs = ps.executeQuery();
- if (!rs.next()) {
- return null;
- }
- realPass = rs.getString("password");
- } catch (SQLException e) {
- xAuthLog.severe("Failed to retrieve password hash for account: " + accountId, e);
- return null;
- } finally {
- xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
- }
- return realPass;
- }
-
-}
diff --git a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java
index dd2e21c3d..7808507ce 100644
--- a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java
+++ b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is called when a player uses the login command,
@@ -63,6 +64,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java
index af26ad518..4014c4bba 100644
--- a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java
+++ b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is called when a player uses the register command,
@@ -63,6 +64,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java b/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java
index ed8a08d35..6a226044b 100644
--- a/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java
+++ b/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java
@@ -4,6 +4,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is fired before AuthMe teleports a player for general purposes.
@@ -32,6 +33,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java b/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java
index e489c2028..252d6ccad 100644
--- a/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java
+++ b/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java
@@ -4,6 +4,7 @@
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is called when a player adds or changes his email address.
@@ -70,6 +71,7 @@ public void setCancelled(boolean cancelled) {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java b/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java
index c80ce65b8..23501213f 100644
--- a/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java
+++ b/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event fired when a player enters a wrong password.
@@ -40,6 +41,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java b/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java
index e5e6868d8..f7fdccdb0 100644
--- a/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java
+++ b/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java
@@ -4,6 +4,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event that is called if a player is teleported to the AuthMe first spawn, i.e. to the
@@ -33,6 +34,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/LoginEvent.java b/src/main/java/fr/xephi/authme/events/LoginEvent.java
index eb38d6266..35edce698 100644
--- a/src/main/java/fr/xephi/authme/events/LoginEvent.java
+++ b/src/main/java/fr/xephi/authme/events/LoginEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event fired when a player has successfully logged in or registered.
@@ -51,6 +52,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/LogoutEvent.java b/src/main/java/fr/xephi/authme/events/LogoutEvent.java
index 70fae0967..0f71d987c 100644
--- a/src/main/java/fr/xephi/authme/events/LogoutEvent.java
+++ b/src/main/java/fr/xephi/authme/events/LogoutEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is called when a player logs out through AuthMe, i.e. only when the player
@@ -42,6 +43,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java b/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java
index 2ad872262..be0b3f85a 100644
--- a/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java
+++ b/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java
@@ -2,6 +2,7 @@
import fr.xephi.authme.security.crypts.EncryptionMethod;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is called when we need to compare or hash a password for a player and allows
@@ -23,20 +24,6 @@ public PasswordEncryptionEvent(EncryptionMethod method) {
this.method = method;
}
- /**
- * Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link org.bukkit.event.Event}.
- *
- * @return The list of handlers
- */
- public static HandlerList getHandlerList() {
- return handlers;
- }
-
- @Override
- public HandlerList getHandlers() {
- return handlers;
- }
-
/**
* Return the encryption method used to hash the password.
*
@@ -54,4 +41,20 @@ public EncryptionMethod getMethod() {
public void setMethod(EncryptionMethod method) {
this.method = method;
}
+
+ /**
+ * Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link org.bukkit.event.Event}.
+ *
+ * @return The list of handlers
+ */
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ @NotNull
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
}
diff --git a/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java b/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java
index f2fba487d..6797bb0a8 100644
--- a/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java
+++ b/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java
@@ -5,6 +5,7 @@
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
/**
* This event is called before the inventory data of a player is suppressed,
@@ -78,6 +79,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/RegisterEvent.java b/src/main/java/fr/xephi/authme/events/RegisterEvent.java
index 2a98d0544..ac189df80 100644
--- a/src/main/java/fr/xephi/authme/events/RegisterEvent.java
+++ b/src/main/java/fr/xephi/authme/events/RegisterEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event fired when a player has successfully registered.
@@ -40,6 +41,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java b/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java
index eb9bf71d8..b0ce76e0d 100644
--- a/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java
+++ b/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java
@@ -4,6 +4,7 @@
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* This event is fired when the inventory of a player is restored
@@ -53,6 +54,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java b/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java
index abfffaa9c..79aaaf9d6 100644
--- a/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java
+++ b/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event fired before a session is restored.
@@ -45,7 +46,9 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java b/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java
index a1a85d846..5045bfb78 100644
--- a/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java
+++ b/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java
@@ -4,6 +4,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Called if a player is teleported to a specific spawn upon joining or logging in.
@@ -44,6 +45,7 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
diff --git a/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java b/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java
index f12e51160..cf5e5eecc 100644
--- a/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java
+++ b/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java
@@ -3,6 +3,7 @@
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event fired after a player has been unregistered from an external source (by an admin or via the API).
@@ -61,7 +62,9 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java b/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java
index cd96cd91d..cb48ed66e 100644
--- a/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java
+++ b/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java
@@ -2,6 +2,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
/**
* Event fired after a player has unregistered himself.
@@ -30,7 +31,9 @@ public static HandlerList getHandlerList() {
}
@Override
+ @NotNull
public HandlerList getHandlers() {
return handlers;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
index ce61b8f2b..249c3f4fe 100644
--- a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
+++ b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
@@ -61,7 +61,10 @@ public class OnJoinVerifier implements Reloadable {
@Override
public void reload() {
String nickRegEx = settings.getProperty(RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS);
- nicknamePattern = Utils.safePatternCompile(nickRegEx);
+ nicknamePattern = Utils.safePatternCompile(nickRegEx, patternString -> {
+ logger.warning("Failed to compile pattern '" + patternString + "' - defaulting to allowing everything");
+ return Utils.MATCH_ANYTHING_PATTERN;
+ });
}
/**
diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java
index 33d875edd..dade7498b 100644
--- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java
+++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java
@@ -100,6 +100,7 @@ public void onAsyncPlayerPreLoginEventLowest(AsyncPlayerPreLoginEvent event) {
final String name = event.getName();
// NOTE: getAddress() sometimes returning null, we don't want to handle this race condition
+ //noinspection ConstantConditions
if (event.getAddress() == null) {
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
messages.retrieveSingle(name, MessageKey.KICK_UNRESOLVED_HOSTNAME));
diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java b/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java
index a4f9767f8..82dcf75bc 100644
--- a/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java
+++ b/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java
@@ -7,7 +7,6 @@
import ch.jalu.configme.resource.PropertyReader;
import ch.jalu.configme.resource.PropertyResource;
import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Files;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
@@ -15,6 +14,8 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -30,7 +31,7 @@
*/
public class MessageUpdater {
- private ConsoleLogger logger = ConsoleLoggerFactory.get(MessageUpdater.class);
+ private final ConsoleLogger logger = ConsoleLoggerFactory.get(MessageUpdater.class);
/**
* Applies any necessary migrations to the user's messages file and saves it if it has been modified.
@@ -120,7 +121,7 @@ private static void backupMessagesFile(File messagesFile) {
String backupName = FileUtils.createBackupFilePath(messagesFile);
File backupFile = new File(backupName);
try {
- Files.copy(messagesFile, backupFile);
+ Files.copy(messagesFile.toPath(), backupFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new IllegalStateException("Could not back up '" + messagesFile + "' to '" + backupFile + "'", e);
}
@@ -166,7 +167,7 @@ public static MessageKeyConfigurationData createConfigurationData() {
// Create ConfigurationData instance
Map> commentsMap = comments.entrySet().stream()
- .collect(Collectors.toMap(e -> e.getKey(), e -> singletonList(e.getValue())));
+ .collect(Collectors.toMap(Map.Entry::getKey, e -> singletonList(e.getValue())));
return new MessageKeyConfigurationData(builder, commentsMap);
}
@@ -184,13 +185,13 @@ protected String getFromReader(PropertyReader reader) {
static final class MessageKeyPropertyListBuilder {
- private PropertyListBuilder propertyListBuilder = new PropertyListBuilder();
+ private final PropertyListBuilder propertyListBuilder = new PropertyListBuilder();
void addMessageKey(MessageKey key) {
propertyListBuilder.add(new MessageKeyProperty(key));
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "rawtypes"})
List getAllProperties() {
return (List) propertyListBuilder.create();
}
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java b/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java
index dad2fba50..31bac025f 100644
--- a/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java
+++ b/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java
@@ -42,12 +42,7 @@ Permission getVaultPermission(Server server) throws PermissionHandlerException {
throw new PermissionHandlerException("Could not load permissions provider service");
}
- // Get the Vault provider and make sure it's valid
- Permission vaultPerms = permissionProvider.getProvider();
- if (vaultPerms == null) {
- throw new PermissionHandlerException("Could not load Vault permissions provider");
- }
- return vaultPerms;
+ return permissionProvider.getProvider();
}
@Override
diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
index 3db023118..deb3691ff 100644
--- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
+++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
@@ -130,9 +130,8 @@ public void processJoin(final Player player) {
return;
}
} else if (!service.getProperty(RegistrationSettings.FORCE)) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
- welcomeMessageConfiguration.sendWelcomeMessage(player);
- });
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() ->
+ welcomeMessageConfiguration.sendWelcomeMessage(player));
// Skip if registration is optional
return;
@@ -169,6 +168,7 @@ private void processJoinSync(Player player, boolean isAuthAvailable) {
}
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
// Allow infinite blindness effect
+ //noinspection ConstantConditions Inspection error!
int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout;
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2));
}
diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
index 7a684a3da..8f75e0b75 100644
--- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
+++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
@@ -30,7 +30,6 @@ public enum HashAlgorithm {
WBB3(fr.xephi.authme.security.crypts.Wbb3.class),
WBB4(fr.xephi.authme.security.crypts.Wbb4.class),
WORDPRESS(fr.xephi.authme.security.crypts.Wordpress.class),
- XAUTH(fr.xephi.authme.security.crypts.XAuth.class),
XFBCRYPT(fr.xephi.authme.security.crypts.XfBCrypt.class),
CUSTOM(null),
@@ -38,8 +37,7 @@ public enum HashAlgorithm {
@Deprecated MD5(fr.xephi.authme.security.crypts.Md5.class),
@Deprecated PLAINTEXT(null),
@Deprecated SHA1(fr.xephi.authme.security.crypts.Sha1.class),
- @Deprecated SHA512(fr.xephi.authme.security.crypts.Sha512.class),
- @Deprecated WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class);
+ @Deprecated SHA512(fr.xephi.authme.security.crypts.Sha512.class);
private final Class extends EncryptionMethod> clazz;
diff --git a/src/main/java/fr/xephi/authme/security/HashUtils.java b/src/main/java/fr/xephi/authme/security/HashUtils.java
index e80880784..33ba11363 100644
--- a/src/main/java/fr/xephi/authme/security/HashUtils.java
+++ b/src/main/java/fr/xephi/authme/security/HashUtils.java
@@ -76,7 +76,7 @@ public static MessageDigest getDigest(MessageDigestAlgorithm algorithm) {
* @return True if the salt is valid, false otherwise
*/
public static boolean isValidBcryptHash(String hash) {
- return hash.length() == 60 && hash.substring(0, 2).equals("$2");
+ return hash.length() == 60 && hash.startsWith("$2");
}
/**
diff --git a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java
index d6cb6e71c..1fc5d1753 100644
--- a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java
+++ b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java
@@ -148,6 +148,7 @@ private EncryptionMethod initializeEncryptionMethodWithEvent(HashAlgorithm algor
*
* @return The associated encryption method, or null if CUSTOM / deprecated
*/
+ @SuppressWarnings("deprecation")
private EncryptionMethod initializeEncryptionMethod(HashAlgorithm algorithm) {
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
return null;
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
index c79647ab7..09f3db140 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
@@ -1,6 +1,5 @@
package fr.xephi.authme.security.crypts;
-import com.google.common.primitives.Ints;
import de.rtner.misc.BinTools;
import de.rtner.security.auth.spi.PBKDF2Engine;
import de.rtner.security.auth.spi.PBKDF2Parameters;
@@ -10,6 +9,7 @@
import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
+import fr.xephi.authme.util.Utils;
import javax.inject.Inject;
@@ -41,7 +41,8 @@ public boolean comparePassword(String password, HashedPassword hashedPassword, S
if (line.length != 4) {
return false;
}
- Integer iterations = Ints.tryParse(line[1]);
+
+ Integer iterations = Utils.tryInteger(line[1]);
if (iterations == null) {
logger.warning("Cannot read number of rounds for Pbkdf2: '" + line[1] + "'");
return false;
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java
index a0877cd4b..d48367e52 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java
@@ -1,11 +1,11 @@
package fr.xephi.authme.security.crypts;
-import com.google.common.primitives.Ints;
import de.rtner.security.auth.spi.PBKDF2Engine;
import de.rtner.security.auth.spi.PBKDF2Parameters;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.AsciiRestricted;
+import fr.xephi.authme.util.Utils;
import java.util.Base64;
@@ -30,7 +30,8 @@ public boolean comparePassword(String password, HashedPassword hashedPassword, S
if (line.length != 4) {
return false;
}
- Integer iterations = Ints.tryParse(line[1]);
+
+ Integer iterations = Utils.tryInteger(line[1]);
if (iterations == null) {
logger.warning("Cannot read number of rounds for Pbkdf2Django: '" + line[1] + "'");
return false;
diff --git a/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java b/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java
index c4e27e9d7..c3bc50abb 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java
@@ -8,6 +8,7 @@
import fr.xephi.authme.security.crypts.description.Usage;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import static fr.xephi.authme.security.HashUtils.isEqual;
@@ -72,14 +73,10 @@ private static final class PhpassSaltedMd5 {
private static final String itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static String md5(String data) {
- try {
- byte[] bytes = data.getBytes("ISO-8859-1");
- MessageDigest md5er = HashUtils.getDigest(MessageDigestAlgorithm.MD5);
- byte[] hash = md5er.digest(bytes);
- return bytes2hex(hash);
- } catch (UnsupportedEncodingException e) {
- throw new UnsupportedOperationException(e);
- }
+ byte[] bytes = data.getBytes(StandardCharsets.ISO_8859_1);
+ MessageDigest md5er = HashUtils.getDigest(MessageDigestAlgorithm.MD5);
+ byte[] hash = md5er.digest(bytes);
+ return bytes2hex(hash);
}
private static int hexToInt(char ch) {
@@ -136,15 +133,13 @@ private static String _hash_encode64(String input, int count) {
private static String _hash_crypt_private(String password, String setting) {
String output = "*";
- if (!setting.substring(0, 3).equals("$H$"))
+ if (!setting.startsWith("$H$"))
return output;
int count_log2 = itoa64.indexOf(setting.charAt(3));
if (count_log2 < 7 || count_log2 > 30)
return output;
int count = 1 << count_log2;
String salt = setting.substring(4, 12);
- if (salt.length() != 8)
- return output;
String m1 = md5(salt + password);
String hash = pack(m1);
do {
diff --git a/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java b/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java
index b97441171..25124421b 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java
@@ -8,7 +8,7 @@
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@@ -21,10 +21,10 @@ public String computeHash(String password, String salt, String name) {
String algo = "HmacSHA256";
String keyString = HashUtils.sha1(salt);
try {
- SecretKeySpec key = new SecretKeySpec(keyString.getBytes("UTF-8"), algo);
+ SecretKeySpec key = new SecretKeySpec(keyString.getBytes(StandardCharsets.UTF_8), algo);
Mac mac = Mac.getInstance(algo);
mac.init(key);
- byte[] bytes = mac.doFinal(password.getBytes("ASCII"));
+ byte[] bytes = mac.doFinal(password.getBytes(StandardCharsets.US_ASCII));
StringBuilder hash = new StringBuilder();
for (byte aByte : bytes) {
String hex = Integer.toHexString(0xFF & aByte);
@@ -34,7 +34,7 @@ public String computeHash(String password, String salt, String name) {
hash.append(hex);
}
return hash.toString();
- } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
+ } catch (InvalidKeyException | NoSuchAlgorithmException e) {
throw new UnsupportedOperationException("Cannot create PHPFUSION hash for " + name, e);
}
}
diff --git a/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java b/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java
index 67b22c780..03dfc5fde 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java
@@ -1,18 +1,19 @@
package fr.xephi.authme.security.crypts;
-import com.google.common.escape.Escaper;
import com.google.common.io.BaseEncoding;
-import com.google.common.net.UrlEscapers;
-import com.google.common.primitives.Ints;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType;
import fr.xephi.authme.security.crypts.description.Usage;
+import fr.xephi.authme.util.Utils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@@ -50,8 +51,15 @@ public static String getQrBarcodeUrl(String user, String host, String secret) {
String format = "https://www.google.com/chart?chs=130x130&chld=M%%7C0&cht=qr&chl="
+ "otpauth://totp/"
+ "%s@%s%%3Fsecret%%3D%s";
- Escaper urlEscaper = UrlEscapers.urlFragmentEscaper();
- return String.format(format, urlEscaper.escape(user), urlEscaper.escape(host), secret);
+
+ try {
+ user = URLEncoder.encode(user, StandardCharsets.UTF_8.toString());
+ host = URLEncoder.encode(host, StandardCharsets.UTF_8.toString());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ return String.format(format, user, host, secret);
}
@Override
@@ -81,7 +89,7 @@ public boolean comparePassword(String password, HashedPassword hashedPassword, S
private boolean checkPassword(String secretKey, String userInput)
throws NoSuchAlgorithmException, InvalidKeyException {
- Integer code = Ints.tryParse(userInput);
+ Integer code = Utils.tryInteger(userInput);
if (code == null) {
//code is not an integer
return false;
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java b/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java
deleted file mode 100644
index 7c62b2619..000000000
--- a/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java
+++ /dev/null
@@ -1,399 +0,0 @@
-package fr.xephi.authme.security.crypts;
-
-/**
- * The Whirlpool hashing function.
- *
- *
- * References
- *
- *
- * The Whirlpool algorithm was developed by Paulo S. L. M. Barreto and Vincent Rijmen.
- *
- * See P.S.L.M. Barreto, V. Rijmen, ``The Whirlpool hashing function,'' First
- * NESSIE workshop, 2000 (tweaked version, 2003),
- *
- *
- * @author Paulo S.L.M. Barreto
- * @author Vincent Rijmen.
- * @version 3.0 (2003.03.12)
- *
- * ====================================================================
- * =========
- *
- * Differences from version 2.1:
- *
- * - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2,
- * 9).
- *
- * ====================================================================
- * =========
- *
- * Differences from version 2.0:
- *
- * - Generation of ISO/IEC 10118-3 test vectors. - Bug fix: nonzero
- * carry was ignored when tallying the data length (this bug apparently
- * only manifested itself when feeding data in pieces rather than in a
- * single chunk at once).
- *
- * Differences from version 1.0:
- *
- * - Original S-box replaced by the tweaked, hardware-efficient
- * version.
- *
- * ====================================================================
- * =========
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import fr.xephi.authme.security.crypts.description.Recommendation;
-import fr.xephi.authme.security.crypts.description.Usage;
-
-import java.util.Arrays;
-
-@Deprecated
-@Recommendation(Usage.DEPRECATED)
-public class Whirlpool extends UnsaltedMethod {
-
- /**
- * The message digest size (in bits)
- */
- public static final int DIGESTBITS = 512;
-
- /**
- * The message digest size (in bytes)
- */
- public static final int DIGESTBYTES = DIGESTBITS >>> 3;
-
- /**
- * The number of rounds of the internal dedicated block cipher.
- */
- protected static final int R = 10;
-
- /**
- * The substitution box.
- */
- private static final String sbox = "\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152" + "\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57" + "\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85" + "\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8" + "\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333" + "\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0" + "\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE" + "\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d" + "\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF" + "\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A" + "\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c" + "\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04" + "\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB" + "\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9" + "\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1" + "\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886";
-
- private static final long[][] C = new long[8][256];
- private static final long[] rc = new long[R + 1];
-
- static {
- for (int x = 0; x < 256; x++) {
- char c = sbox.charAt(x / 2);
- long v1 = ((x & 1) == 0) ? c >>> 8 : c & 0xff;
- long v2 = v1 << 1;
- if (v2 >= 0x100L) {
- v2 ^= 0x11dL;
- }
- long v4 = v2 << 1;
- if (v4 >= 0x100L) {
- v4 ^= 0x11dL;
- }
- long v5 = v4 ^ v1;
- long v8 = v4 << 1;
- if (v8 >= 0x100L) {
- v8 ^= 0x11dL;
- }
- long v9 = v8 ^ v1;
- /*
- * build the circulant table C[0][x] = S[x].[1, 1, 4, 1, 8, 5, 2,
- * 9]:
- */
- C[0][x] = (v1 << 56) | (v1 << 48) | (v4 << 40) | (v1 << 32) | (v8 << 24) | (v5 << 16) | (v2 << 8) | (v9);
- /*
- * build the remaining circulant tables C[t][x] = C[0][x] rotr t
- */
- for (int t = 1; t < 8; t++) {
- C[t][x] = (C[t - 1][x] >>> 8) | ((C[t - 1][x] << 56));
- }
- }
- /*
- * build the round constants:
- */
- rc[0] = 0L; /*
- * not used (assigment kept only to properly initialize all
- * variables)
- */
- for (int r = 1; r <= R; r++) {
- int i = 8 * (r - 1);
- rc[r] = (C[0][i] & 0xff00000000000000L) ^ (C[1][i + 1] & 0x00ff000000000000L) ^ (C[2][i + 2] & 0x0000ff0000000000L) ^ (C[3][i + 3] & 0x000000ff00000000L) ^ (C[4][i + 4] & 0x00000000ff000000L) ^ (C[5][i + 5] & 0x0000000000ff0000L) ^ (C[6][i + 6] & 0x000000000000ff00L) ^ (C[7][i + 7] & 0x00000000000000ffL);
- }
- }
-
- /**
- * Global number of hashed bits (256-bit counter).
- */
- protected final byte[] bitLength = new byte[32];
-
- /**
- * Buffer of data to hash.
- */
- protected final byte[] buffer = new byte[64];
-
- /**
- * Current number of bits on the buffer.
- */
- protected int bufferBits = 0;
-
- /**
- * Current (possibly incomplete) byte slot on the buffer.
- */
- protected int bufferPos = 0;
-
- /**
- * The hashing state.
- */
- protected final long[] hash = new long[8];
- protected final long[] K = new long[8];
- protected final long[] L = new long[8];
- protected final long[] block = new long[8];
- protected final long[] state = new long[8];
-
- public Whirlpool() {
- }
-
- protected static String display(byte[] array) {
- char[] val = new char[2 * array.length];
- String hex = "0123456789ABCDEF";
- for (int i = 0; i < array.length; i++) {
- int b = array[i] & 0xff;
- val[2 * i] = hex.charAt(b >>> 4);
- val[2 * i + 1] = hex.charAt(b & 15);
- }
- return String.valueOf(val);
- }
-
- /**
- * The core Whirlpool transform.
- */
- protected void processBuffer() {
- /*
- * map the buffer to a block:
- */
- for (int i = 0, j = 0; i < 8; i++, j += 8) {
- block[i] = (((long) buffer[j]) << 56) ^ (((long) buffer[j + 1] & 0xffL) << 48) ^ (((long) buffer[j + 2] & 0xffL) << 40) ^ (((long) buffer[j + 3] & 0xffL) << 32) ^ (((long) buffer[j + 4] & 0xffL) << 24) ^ (((long) buffer[j + 5] & 0xffL) << 16) ^ (((long) buffer[j + 6] & 0xffL) << 8) ^ (((long) buffer[j + 7] & 0xffL));
- }
- /*
- * compute and apply K^0 to the cipher state:
- */
- for (int i = 0; i < 8; i++) {
- state[i] = block[i] ^ (K[i] = hash[i]);
- }
- /*
- * iterate over all rounds:
- */
- for (int r = 1; r <= R; r++) {
- /*
- * compute K^r from K^{r-1}:
- */
- for (int i = 0; i < 8; i++) {
- L[i] = 0L;
- for (int t = 0, s = 56; t < 8; t++, s -= 8) {
- L[i] ^= C[t][(int) (K[(i - t) & 7] >>> s) & 0xff];
- }
- }
- for (int i = 0; i < 8; i++) {
- K[i] = L[i];
- }
- K[0] ^= rc[r];
- /*
- * apply the r-th round transformation:
- */
- for (int i = 0; i < 8; i++) {
- L[i] = K[i];
- for (int t = 0, s = 56; t < 8; t++, s -= 8) {
- L[i] ^= C[t][(int) (state[(i - t) & 7] >>> s) & 0xff];
- }
- }
- for (int i = 0; i < 8; i++) {
- state[i] = L[i];
- }
- }
- /*
- * apply the Miyaguchi-Preneel compression function:
- */
- for (int i = 0; i < 8; i++) {
- hash[i] ^= state[i] ^ block[i];
- }
- }
-
- /**
- * Initialize the hashing state.
- */
- public void NESSIEinit() {
- Arrays.fill(bitLength, (byte) 0);
- bufferBits = bufferPos = 0;
- buffer[0] = 0;
- Arrays.fill(hash, 0L);
- }
-
- /**
- * Delivers input data to the hashing algorithm.
- *
- * @param source plaintext data to hash.
- * @param sourceBits how many bits of plaintext to process.
- *
- * This method maintains the invariant: bufferBits < 512
- *
- */
- public void NESSIEadd(byte[] source, long sourceBits) {
- /*
- * sourcePos | +-------+-------+------- ||||||||||||||||||||| source
- * +-------+-------+-------
- * +-------+-------+-------+-------+-------+-------
- * |||||||||||||||||||||| buffer
- * +-------+-------+-------+-------+-------+------- | bufferPos
- */
- int sourcePos = 0; // index of leftmost source byte containing data (1
- // to 8 bits).
- int sourceGap = (8 - ((int) sourceBits & 7)) & 7; // space on
- // source[sourcePos].
- int bufferRem = bufferBits & 7; // occupied bits on buffer[bufferPos].
- int b;
- // tally the length of the added data:
- long value = sourceBits;
- for (int i = 31, carry = 0; i >= 0; i--) {
- carry += (bitLength[i] & 0xff) + ((int) value & 0xff);
- bitLength[i] = (byte) carry;
- carry >>>= 8;
- value >>>= 8;
- }
- // process data in chunks of 8 bits:
- while (sourceBits > 8) { // at least source[sourcePos] and
- // source[sourcePos+1] contain data.
- // take a byte from the source:
- b = ((source[sourcePos] << sourceGap) & 0xff) | ((source[sourcePos + 1] & 0xff) >>> (8 - sourceGap));
- if (b < 0 || b >= 256) {
- throw new RuntimeException("LOGIC ERROR");
- }
- // process this byte:
- buffer[bufferPos++] |= b >>> bufferRem;
- bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos;
- if (bufferBits == 512) {
- // process data block:
- processBuffer();
- // reset buffer:
- bufferBits = bufferPos = 0;
- }
- buffer[bufferPos] = (byte) ((b << (8 - bufferRem)) & 0xff);
- bufferBits += bufferRem;
- // proceed to remaining data:
- sourceBits -= 8;
- sourcePos++;
- }
- // now 0 <= sourceBits <= 8;
- // furthermore, all data (if any is left) is in source[sourcePos].
- if (sourceBits > 0) {
- b = (source[sourcePos] << sourceGap) & 0xff; // bits are
- // left-justified on b.
- // process the remaining bits:
- buffer[bufferPos] |= b >>> bufferRem;
- } else {
- b = 0;
- }
- if (bufferRem + sourceBits < 8) {
- // all remaining data fits on buffer[bufferPos], and there still
- // remains some space.
- bufferBits += sourceBits;
- } else {
- // buffer[bufferPos] is full:
- bufferPos++;
- bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos;
- sourceBits -= 8 - bufferRem;
- // now 0 <= sourceBits < 8; furthermore, all data is in
- // source[sourcePos].
- if (bufferBits == 512) {
- // process data block:
- processBuffer();
- // reset buffer:
- bufferBits = bufferPos = 0;
- }
- buffer[bufferPos] = (byte) ((b << (8 - bufferRem)) & 0xff);
- bufferBits += (int) sourceBits;
- }
- }
-
- /**
- *
- * Get the hash value from the hashing state.
- *
- *
- * This method uses the invariant: bufferBits < 512
- *
- * @param digest byte[]
- */
- public void NESSIEfinalize(byte[] digest) {
- // append a '1'-bit:
- buffer[bufferPos] |= 0x80 >>> (bufferBits & 7);
- bufferPos++; // all remaining bits on the current byte are set to zero.
- // pad with zero bits to complete 512N + 256 bits:
- if (bufferPos > 32) {
- while (bufferPos < 64) {
- buffer[bufferPos++] = 0;
- }
- // process data block:
- processBuffer();
- // reset buffer:
- bufferPos = 0;
- }
- while (bufferPos < 32) {
- buffer[bufferPos++] = 0;
- }
- // append bit length of hashed data:
- System.arraycopy(bitLength, 0, buffer, 32, 32);
- // process data block:
- processBuffer();
- // return the completed message digest:
- for (int i = 0, j = 0; i < 8; i++, j += 8) {
- long h = hash[i];
- digest[j] = (byte) (h >>> 56);
- digest[j + 1] = (byte) (h >>> 48);
- digest[j + 2] = (byte) (h >>> 40);
- digest[j + 3] = (byte) (h >>> 32);
- digest[j + 4] = (byte) (h >>> 24);
- digest[j + 5] = (byte) (h >>> 16);
- digest[j + 6] = (byte) (h >>> 8);
- digest[j + 7] = (byte) (h);
- }
- }
-
- /**
- * Delivers string input data to the hashing algorithm.
- *
- * @param source plaintext data to hash (ASCII text string).
- * This method maintains the invariant: bufferBits < 512
- */
- public void NESSIEadd(String source) {
- if (source.length() > 0) {
- byte[] data = new byte[source.length()];
- for (int i = 0; i < source.length(); i++) {
- data[i] = (byte) source.charAt(i);
- }
- NESSIEadd(data, 8 * data.length);
- }
- }
-
- @Override
- public String computeHash(String password) {
- byte[] digest = new byte[DIGESTBYTES];
- NESSIEinit();
- NESSIEadd(password);
- NESSIEfinalize(digest);
- return display(digest);
- }
-
-}
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java b/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java
index f70c09496..a9ac88a6e 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java
@@ -8,6 +8,7 @@
import fr.xephi.authme.security.crypts.description.Usage;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
@@ -73,9 +74,6 @@ private String crypt(String password, String setting) {
}
int count = 1 << countLog2;
String salt = setting.substring(4, 4 + 8);
- if (salt.length() != 8) {
- return output;
- }
MessageDigest md = HashUtils.getDigest(MessageDigestAlgorithm.MD5);
byte[] pass = stringToUtf8(password);
byte[] hash = md.digest(stringToUtf8(salt + password));
@@ -99,16 +97,12 @@ private String gensaltPrivate(byte[] input) {
}
private byte[] stringToUtf8(String string) {
- try {
- return string.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new UnsupportedOperationException("This system doesn't support UTF-8!", e);
- }
+ return string.getBytes(StandardCharsets.UTF_8);
}
@Override
public String computeHash(String password) {
- byte random[] = new byte[6];
+ byte[] random = new byte[6];
randomGen.nextBytes(random);
return crypt(password, gensaltPrivate(stringToUtf8(new String(random))));
}
diff --git a/src/main/java/fr/xephi/authme/security/crypts/XAuth.java b/src/main/java/fr/xephi/authme/security/crypts/XAuth.java
deleted file mode 100644
index 62f2e0d71..000000000
--- a/src/main/java/fr/xephi/authme/security/crypts/XAuth.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package fr.xephi.authme.security.crypts;
-
-import fr.xephi.authme.security.crypts.description.Recommendation;
-import fr.xephi.authme.security.crypts.description.Usage;
-
-import static fr.xephi.authme.security.HashUtils.isEqual;
-
-@Recommendation(Usage.RECOMMENDED)
-public class XAuth extends HexSaltedMethod {
-
- private static String getWhirlpool(String message) {
- Whirlpool w = new Whirlpool();
- byte[] digest = new byte[Whirlpool.DIGESTBYTES];
- w.NESSIEinit();
- w.NESSIEadd(message);
- w.NESSIEfinalize(digest);
- return Whirlpool.display(digest);
- }
-
- @Override
- public String computeHash(String password, String salt, String name) {
- String hash = getWhirlpool(salt + password).toLowerCase();
- int saltPos = password.length() >= hash.length() ? hash.length() - 1 : password.length();
- return hash.substring(0, saltPos) + salt + hash.substring(saltPos);
- }
-
- @Override
- public boolean comparePassword(String password, HashedPassword hashedPassword, String name) {
- String hash = hashedPassword.getHash();
- int saltPos = password.length() >= hash.length() ? hash.length() - 1 : password.length();
- if (saltPos + 12 > hash.length()) {
- return false;
- }
- String salt = hash.substring(saltPos, saltPos + 12);
- return isEqual(hash, computeHash(password, salt, name));
- }
-
- @Override
- public int getSaltLength() {
- return 12;
- }
-
-}
diff --git a/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java b/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java
index e26b136f4..bdafdf6c4 100644
--- a/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java
+++ b/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java
@@ -2,7 +2,6 @@
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
-import com.google.common.primitives.Ints;
import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
@@ -11,6 +10,7 @@
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
+import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player;
import javax.inject.Inject;
@@ -55,7 +55,7 @@ public boolean checkCode(PlayerAuth auth, String totpCode) {
*/
public boolean checkCode(String playerName, String totpKey, String inputCode) {
String nameLower = playerName.toLowerCase();
- Integer totpCode = Ints.tryParse(inputCode);
+ Integer totpCode = Utils.tryInteger(inputCode);
if (totpCode != null && !usedCodes.contains(nameLower, totpCode)
&& authenticator.authorize(totpKey, totpCode)) {
usedCodes.put(nameLower, totpCode, System.currentTimeMillis());
diff --git a/src/main/java/fr/xephi/authme/service/BackupService.java b/src/main/java/fr/xephi/authme/service/BackupService.java
index 2e72a7b0c..e7ecca408 100644
--- a/src/main/java/fr/xephi/authme/service/BackupService.java
+++ b/src/main/java/fr/xephi/authme/service/BackupService.java
@@ -19,9 +19,6 @@
import java.io.InputStream;
import java.io.OutputStream;
-import static fr.xephi.authme.util.Utils.logAndSendMessage;
-import static fr.xephi.authme.util.Utils.logAndSendWarning;
-
/**
* Performs a backup of the data source.
*/
@@ -66,7 +63,7 @@ public void doBackup(BackupCause cause, CommandSender sender) {
if (!settings.getProperty(BackupSettings.ENABLED)) {
// Print a warning if the backup was requested via command or by another plugin
if (cause == BackupCause.COMMAND || cause == BackupCause.OTHER) {
- logAndSendWarning(sender,
+ logger.logAndSendWarning(sender,
"Can't perform a backup: disabled in configuration. Cause of the backup: " + cause.name());
}
return;
@@ -78,10 +75,10 @@ public void doBackup(BackupCause cause, CommandSender sender) {
// Do backup and check return value!
if (doBackup()) {
- logAndSendMessage(sender,
+ logger.logAndSendMessage(sender,
"A backup has been performed successfully. Cause of the backup: " + cause.name());
} else {
- logAndSendWarning(sender, "Error while performing a backup! Cause of the backup: " + cause.name());
+ logger.logAndSendWarning(sender, "Error while performing a backup! Cause of the backup: " + cause.name());
}
}
diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java
index a6af581ab..97b48cfac 100644
--- a/src/main/java/fr/xephi/authme/service/BukkitService.java
+++ b/src/main/java/fr/xephi/authme/service/BukkitService.java
@@ -328,17 +328,16 @@ public BanEntry banIp(String ip, String reason, Date expires, String source) {
}
/**
- * Returns an optional with a boolean indicating whether bungeecord is enabled or not if the
- * server implementation is Spigot. Otherwise returns an empty optional.
+ * Returns a boolean indicating whether bungeecord support is enabled or not.
*
- * @return Optional with configuration value for Spigot, empty optional otherwise
+ * @return boolean with configuration value for Spigot
*/
- public Optional isBungeeCordConfiguredForSpigot() {
+ public boolean isBungeeCordConfiguredForSpigot() {
try {
YamlConfiguration spigotConfig = Bukkit.spigot().getConfig();
- return Optional.of(spigotConfig.getBoolean("settings.bungeecord"));
+ return spigotConfig.getBoolean("settings.bungeecord");
} catch (NoSuchMethodError e) {
- return Optional.empty();
+ return false;
}
}
diff --git a/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java b/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java
index e1c8c5ba7..4f1c8fb07 100644
--- a/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java
+++ b/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java
@@ -18,6 +18,7 @@
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.LinkedHashMap;
@@ -54,7 +55,8 @@ public File updateHelpFile() throws IOException {
Map helpEntries = generateHelpMessageEntries();
String helpEntriesYaml = exportToYaml(helpEntries);
- Files.write(helpFile.toPath(), helpEntriesYaml.getBytes(), StandardOpenOption.TRUNCATE_EXISTING);
+ Files.write(helpFile.toPath(), helpEntriesYaml.getBytes(StandardCharsets.UTF_8),
+ StandardOpenOption.TRUNCATE_EXISTING);
return helpFile;
}
diff --git a/src/main/java/fr/xephi/authme/service/MigrationService.java b/src/main/java/fr/xephi/authme/service/MigrationService.java
index de8d88a78..b46b5bbf9 100644
--- a/src/main/java/fr/xephi/authme/service/MigrationService.java
+++ b/src/main/java/fr/xephi/authme/service/MigrationService.java
@@ -29,6 +29,7 @@ private MigrationService() {
* @param dataSource The data source
* @param authmeSha256 Instance to the AuthMe Sha256 encryption method implementation
*/
+ @SuppressWarnings("deprecation")
public static void changePlainTextToSha256(Settings settings, DataSource dataSource,
Sha256 authmeSha256) {
if (HashAlgorithm.PLAINTEXT == settings.getProperty(SecuritySettings.PASSWORD_HASH)) {
diff --git a/src/main/java/fr/xephi/authme/service/TeleportationService.java b/src/main/java/fr/xephi/authme/service/TeleportationService.java
index f0eb7f851..39a1907ef 100644
--- a/src/main/java/fr/xephi/authme/service/TeleportationService.java
+++ b/src/main/java/fr/xephi/authme/service/TeleportationService.java
@@ -131,7 +131,7 @@ public void teleportOnLogin(final Player player, PlayerAuth auth, LimboPlayer li
}
// #856: If LimboPlayer comes from a persisted file, the Location might be null
- String worldName = (limbo != null && limbo.getLocation() != null)
+ String worldName = (limbo != null && limbo.getLocation() != null && limbo.getLocation().getWorld() != null)
? limbo.getLocation().getWorld().getName()
: null;
diff --git a/src/main/java/fr/xephi/authme/service/ValidationService.java b/src/main/java/fr/xephi/authme/service/ValidationService.java
index 183a3b4a6..e6be431bd 100644
--- a/src/main/java/fr/xephi/authme/service/ValidationService.java
+++ b/src/main/java/fr/xephi/authme/service/ValidationService.java
@@ -25,6 +25,7 @@
import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
@@ -55,7 +56,11 @@ public class ValidationService implements Reloadable {
@PostConstruct
@Override
public void reload() {
- passwordRegex = Utils.safePatternCompile(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX));
+ passwordRegex = Utils.safePatternCompile(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX),
+ patternString -> {
+ logger.warning("Failed to compile pattern '" + patternString + "' - defaulting to allowing everything");
+ return Utils.MATCH_ANYTHING_PATTERN;
+ });
restrictedNames = settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)
? loadNameRestrictions(settings.getProperty(RestrictionSettings.RESTRICTED_USERS))
: HashMultimap.create();
@@ -155,7 +160,7 @@ public boolean fulfillsNameRestrictions(Player player) {
}
String ip = PlayerUtils.getPlayerIp(player);
- String domain = player.getAddress().getHostName();
+ String domain = Objects.requireNonNull(player.getAddress()).getHostName();
for (String restriction : restrictions) {
if (restriction.startsWith("regex:")) {
restriction = restriction.replace("regex:", "");
diff --git a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java b/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java
index ae1b79cd9..ccf49b644 100644
--- a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java
+++ b/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java
@@ -14,6 +14,7 @@
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.plugin.messaging.PluginMessageListener;
+import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.util.Optional;
@@ -40,7 +41,7 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
}
@Override
- public void reload(final Settings settings) {
+ public void reload(Settings settings) {
this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD);
if (this.isEnabled) {
@@ -56,7 +57,7 @@ public void reload(final Settings settings) {
*
* @param in the input to handle
*/
- private void handleBroadcast(final ByteArrayDataInput in) {
+ private void handleBroadcast(ByteArrayDataInput in) {
// Read data byte array
final short dataLength = in.readShort();
final byte[] dataBytes = new byte[dataLength];
@@ -130,7 +131,7 @@ private void handle(ByteArrayDataInput in) {
}
@Override
- public void onPluginMessageReceived(final String channel, final Player player, final byte[] data) {
+ public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] data) {
if (!isEnabled) {
return;
}
@@ -146,7 +147,7 @@ public void onPluginMessageReceived(final String channel, final Player player, f
}
}
- private void performLogin(final String name) {
+ private void performLogin(String name) {
Player player = bukkitService.getPlayerExact(name);
if (player != null && player.isOnline()) {
management.forceLogin(player);
diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java
index ab33a7e8d..78d540734 100644
--- a/src/main/java/fr/xephi/authme/settings/Settings.java
+++ b/src/main/java/fr/xephi/authme/settings/Settings.java
@@ -4,13 +4,13 @@
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 java.nio.file.Files;
import static fr.xephi.authme.util.FileUtils.copyFileFromResource;
@@ -89,7 +89,7 @@ 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();
+ return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
} catch (IOException e) {
logger.logException("Failed to read file '" + filename + "':", e);
}
@@ -98,4 +98,5 @@ private String readFile(String filename) {
}
return "";
}
+
}
diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
index 23168d530..46a45552e 100644
--- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
+++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
@@ -309,6 +309,7 @@ private static boolean mergeAndMovePermissionGroupSettings(PropertyReader reader
* @param configData Configuration data
* @return True if the configuration has changed, false otherwise
*/
+ @SuppressWarnings("deprecation")
private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyReader reader,
ConfigurationData configData) {
HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.determineValue(reader);
diff --git a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java b/src/main/java/fr/xephi/authme/settings/SettingsWarner.java
index c51bdf6b3..c7cabd57f 100644
--- a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java
+++ b/src/main/java/fr/xephi/authme/settings/SettingsWarner.java
@@ -13,7 +13,6 @@
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.
@@ -60,7 +59,7 @@ public void logWarningsForMisconfigurations() {
}
// Warn if spigot.yml has settings.bungeecord set to true but config.yml has Hooks.bungeecord set to false
- if (isTrue(bukkitService.isBungeeCordConfiguredForSpigot())
+ if (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"
@@ -76,7 +75,4 @@ public void logWarningsForMisconfigurations() {
}
}
- private static boolean isTrue(Optional value) {
- return value.isPresent() && value.get();
- }
}
diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
index 7b3fc1385..b9dcf1669 100644
--- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
+++ b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
@@ -15,10 +15,12 @@
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
+import java.util.Objects;
/**
* Manager for spawn points. It loads spawn definitions from AuthMe and third-party plugins
@@ -170,8 +172,10 @@ public void unloadCmiSpawn() {
* @see RestrictionSettings#SPAWN_PRIORITY
*/
public Location getSpawnLocation(Player player) {
- if (player == null || player.getWorld() == null) {
+ if (player == null) {
return null;
+ } else {
+ player.getWorld();
}
World world = player.getWorld();
@@ -179,19 +183,18 @@ public Location getSpawnLocation(Player player) {
for (String priority : spawnPriority) {
switch (priority.toLowerCase().trim()) {
case "default":
- if (world.getSpawnLocation() != null) {
- if (!isValidSpawnPoint(world.getSpawnLocation())) {
- for (World spawnWorld : Bukkit.getWorlds()) {
- if (isValidSpawnPoint(spawnWorld.getSpawnLocation())) {
- world = spawnWorld;
- break;
- }
+ world.getSpawnLocation();
+ 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();
+ 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)) {
@@ -227,11 +230,8 @@ public Location getSpawnLocation(Player player) {
*
* @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;
+ private boolean isValidSpawnPoint(@NotNull Location location) {
+ return location.getX() != 0 || location.getY() != 0 || location.getZ() != 0;
}
/**
@@ -242,7 +242,7 @@ private boolean isValidSpawnPoint(Location location) {
*
* @return True upon success, false otherwise
*/
- private boolean setLocation(String prefix, Location location) {
+ private boolean setLocation(@NotNull String prefix, Location location) {
if (location != null && location.getWorld() != null) {
authMeConfiguration.set(prefix + ".world", location.getWorld().getName());
authMeConfiguration.set(prefix + ".x", location.getX());
@@ -272,7 +272,7 @@ private boolean saveAuthMeConfig() {
*
* @return location of the given player if alive, spawn location if dead.
*/
- public Location getPlayerLocationOrSpawn(Player player) {
+ public Location getPlayerLocationOrSpawn(@NotNull Player player) {
if (player.isOnline() && player.isDead()) {
return getSpawnLocation(player);
}
@@ -287,10 +287,11 @@ public Location getPlayerLocationOrSpawn(Player player) {
*
* @return Location corresponding to the values in the path
*/
- private static Location getLocationFromConfiguration(FileConfiguration configuration, String pathPrefix) {
+ private static Location getLocationFromConfiguration(@NotNull FileConfiguration configuration,
+ @NotNull String pathPrefix) {
if (containsAllSpawnFields(configuration, pathPrefix)) {
String prefix = pathPrefix + ".";
- String worldName = configuration.getString(prefix + "world");
+ String worldName = Objects.requireNonNull(configuration.getString(prefix + "world"));
World world = Bukkit.getWorld(worldName);
if (!StringUtils.isEmpty(worldName) && world != null) {
return new Location(world, configuration.getDouble(prefix + "x"),
@@ -308,11 +309,11 @@ private static Location getLocationFromConfiguration(FileConfiguration configura
*
* @return Location corresponding to the values in the path
*/
- private static Location getLocationFromCmiConfiguration(FileConfiguration configuration) {
+ private static Location getLocationFromCmiConfiguration(@NotNull FileConfiguration configuration) {
final String pathPrefix = "Spawn.Main";
if (isLocationCompleteInCmiConfig(configuration, pathPrefix)) {
String prefix = pathPrefix + ".";
- String worldName = configuration.getString(prefix + "World");
+ String worldName = Objects.requireNonNull(configuration.getString(prefix + "World"));
World world = Bukkit.getWorld(worldName);
if (!StringUtils.isEmpty(worldName) && world != null) {
return new Location(world, configuration.getDouble(prefix + "X"),
@@ -332,7 +333,8 @@ private static Location getLocationFromCmiConfiguration(FileConfiguration config
*
* @return True if all spawn fields are present, false otherwise
*/
- private static boolean containsAllSpawnFields(FileConfiguration configuration, String pathPrefix) {
+ private static boolean containsAllSpawnFields(@NotNull FileConfiguration configuration,
+ @NotNull String pathPrefix) {
String[] fields = {"world", "x", "y", "z", "yaw", "pitch"};
for (String field : fields) {
if (!configuration.contains(pathPrefix + "." + field)) {
@@ -350,7 +352,8 @@ private static boolean containsAllSpawnFields(FileConfiguration configuration, S
*
* @return True if all spawn fields are present, false otherwise
*/
- private static boolean isLocationCompleteInCmiConfig(FileConfiguration cmiConfiguration, String pathPrefix) {
+ private static boolean isLocationCompleteInCmiConfig(@NotNull FileConfiguration cmiConfiguration,
+ @NotNull String pathPrefix) {
String[] fields = {"World", "X", "Y", "Z", "Yaw", "Pitch"};
for (String field : fields) {
if (!cmiConfiguration.contains(pathPrefix + "." + field)) {
@@ -368,7 +371,7 @@ private static boolean isLocationCompleteInCmiConfig(FileConfiguration cmiConfig
*
* @return The float
*/
- private static float getFloat(FileConfiguration configuration, String path) {
+ private static float getFloat(@NotNull FileConfiguration configuration, @NotNull String path) {
Object value = configuration.get(path);
// This behavior is consistent with FileConfiguration#getDouble
return (value instanceof Number) ? ((Number) value).floatValue() : 0;
diff --git a/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java b/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java
index 36cdff015..7cb46dd20 100644
--- a/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java
+++ b/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java
@@ -17,6 +17,7 @@
import org.bukkit.Server;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
@@ -95,6 +96,7 @@ public void reload() {
* @param player the player for whom the welcome message should be prepared
* @return the welcome message
*/
+ @NotNull
public List getWelcomeMessage(Player player) {
return messageSupplier.getAdaptedMessages(player);
}
@@ -104,7 +106,7 @@ public List getWelcomeMessage(Player player) {
*
* @param player the player for whom the welcome message should be prepared
*/
- public void sendWelcomeMessage(Player player) {
+ public void sendWelcomeMessage(@NotNull Player player) {
if (service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
List welcomeMessage = getWelcomeMessage(player);
if (service.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) {
@@ -118,6 +120,7 @@ public void sendWelcomeMessage(Player player) {
/**
* @return the lines of the welcome message file
*/
+ @NotNull
private List readWelcomeFile() {
if (!(service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE))) {
return Collections.emptyList();
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java b/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java
index 13cc30fca..77aa50ffa 100644
--- a/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java
+++ b/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java
@@ -17,7 +17,7 @@ public OnLoginCommand() {
}
/**
- * Creates a copy of this object, using the given command as new {@link Command#command command}.
+ * Creates a copy of this object, using the given command.
*
* @param command the command text to use in the copy
* @return copy of the source with the new command
diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
index 0cffd2804..b69f06253 100644
--- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
+++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
@@ -53,7 +53,7 @@ public final class SecuritySettings implements SettingsHolder {
@Comment({
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
- "MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
+ "MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, 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"
diff --git a/src/main/java/fr/xephi/authme/task/MessageTask.java b/src/main/java/fr/xephi/authme/task/MessageTask.java
index cf4366d9d..9607cdbe2 100644
--- a/src/main/java/fr/xephi/authme/task/MessageTask.java
+++ b/src/main/java/fr/xephi/authme/task/MessageTask.java
@@ -2,20 +2,23 @@
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
/**
* Message shown to a player in a regular interval as long as he is not logged in.
*/
public class MessageTask extends BukkitRunnable {
+ @NotNull
private final Player player;
+ @NotNull
private final String[] message;
private boolean isMuted;
/*
* Constructor.
*/
- public MessageTask(Player player, String[] lines) {
+ public MessageTask(@NotNull Player player, @NotNull String[] lines) {
this.player = player;
this.message = lines;
isMuted = false;
diff --git a/src/main/java/fr/xephi/authme/task/TimeoutTask.java b/src/main/java/fr/xephi/authme/task/TimeoutTask.java
index 60aac7414..f71a64d4b 100644
--- a/src/main/java/fr/xephi/authme/task/TimeoutTask.java
+++ b/src/main/java/fr/xephi/authme/task/TimeoutTask.java
@@ -2,14 +2,18 @@
import fr.xephi.authme.data.auth.PlayerCache;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
/**
* Kicks a player if he hasn't logged in (scheduled to run after a configured delay).
*/
public class TimeoutTask implements Runnable {
+ @NotNull
private final Player player;
+ @NotNull
private final String message;
+ @NotNull
private final PlayerCache playerCache;
/**
@@ -19,7 +23,7 @@ public class TimeoutTask implements Runnable {
* @param message the kick message
* @param playerCache player cache instance
*/
- public TimeoutTask(Player player, String message, PlayerCache playerCache) {
+ public TimeoutTask(@NotNull Player player, @NotNull String message, @NotNull PlayerCache playerCache) {
this.message = message;
this.player = player;
this.playerCache = playerCache;
@@ -31,4 +35,5 @@ public void run() {
player.kickPlayer(message);
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java b/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java
index 399ff3985..247b433d4 100644
--- a/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java
+++ b/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java
@@ -11,6 +11,7 @@
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
+import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.io.File;
@@ -53,7 +54,7 @@ public class PurgeExecutor {
* @param players the players to purge
* @param names names to purge
*/
- public void executePurge(Collection players, Collection names) {
+ public void executePurge(@NotNull Collection players, @NotNull Collection names) {
// Purge other data
purgeFromAuthMe(names);
purgeEssentials(players);
@@ -68,7 +69,7 @@ public void executePurge(Collection players, Collection n
*
* @param cleared the players whose data should be cleared
*/
- synchronized void purgeAntiXray(Collection cleared) {
+ synchronized void purgeAntiXray(@NotNull Collection cleared) {
if (!settings.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE)) {
return;
}
@@ -96,7 +97,7 @@ synchronized void purgeAntiXray(Collection cleared) {
*
* @param names the name of the accounts to delete
*/
- synchronized void purgeFromAuthMe(Collection names) {
+ synchronized void purgeFromAuthMe(@NotNull Collection names) {
dataSource.purgeRecords(names);
//TODO ljacqu 20160717: We shouldn't output namedBanned.size() but the actual total that was deleted
logger.info(ChatColor.GOLD + "Deleted " + names.size() + " user accounts");
@@ -107,7 +108,7 @@ synchronized void purgeFromAuthMe(Collection names) {
*
* @param cleared the players whose data should be cleared
*/
- synchronized void purgeLimitedCreative(Collection cleared) {
+ synchronized void purgeLimitedCreative(@NotNull Collection cleared) {
if (!settings.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES)) {
return;
}
@@ -152,7 +153,7 @@ synchronized void purgeLimitedCreative(Collection cleared) {
*
* @param cleared list of players to clear
*/
- synchronized void purgeDat(Collection cleared) {
+ synchronized void purgeDat(@NotNull Collection cleared) {
if (!settings.getProperty(PurgeSettings.REMOVE_PLAYER_DAT)) {
return;
}
@@ -176,7 +177,7 @@ synchronized void purgeDat(Collection cleared) {
*
* @param cleared list of players to clear
*/
- synchronized void purgeEssentials(Collection cleared) {
+ synchronized void purgeEssentials(@NotNull Collection cleared) {
if (!settings.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)) {
return;
}
@@ -208,7 +209,7 @@ synchronized void purgeEssentials(Collection cleared) {
*
* @param cleared the players to remove data for
*/
- synchronized void purgePermissions(Collection cleared) {
+ synchronized void purgePermissions(@NotNull Collection cleared) {
if (!settings.getProperty(PurgeSettings.REMOVE_PERMISSIONS)) {
return;
}
@@ -223,4 +224,5 @@ synchronized void purgePermissions(Collection cleared) {
logger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s).");
}
+
}
diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeService.java b/src/main/java/fr/xephi/authme/task/purge/PurgeService.java
index 880d51185..4a12733e8 100644
--- a/src/main/java/fr/xephi/authme/task/purge/PurgeService.java
+++ b/src/main/java/fr/xephi/authme/task/purge/PurgeService.java
@@ -10,14 +10,13 @@
import fr.xephi.authme.util.Utils;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
+import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.util.Calendar;
import java.util.Collection;
import java.util.Set;
-import static fr.xephi.authme.util.Utils.logAndSendMessage;
-
/**
* Initiates purge tasks.
*/
@@ -77,7 +76,7 @@ public void runPurge(CommandSender sender, long until) {
//todo: note this should may run async because it may executes a SQL-Query
Set toPurge = dataSource.getRecordsToPurge(until);
if (Utils.isCollectionEmpty(toPurge)) {
- logAndSendMessage(sender, "No players to purge");
+ logger.logAndSendMessage(sender, "No players to purge");
return;
}
@@ -91,9 +90,9 @@ public void runPurge(CommandSender sender, long until) {
* @param names The names to remove
* @param players Collection of OfflinePlayers (including those with the given names)
*/
- public void purgePlayers(CommandSender sender, Set names, OfflinePlayer[] players) {
+ public void purgePlayers(CommandSender sender, @NotNull Set names, @NotNull OfflinePlayer[] players) {
if (isPurging) {
- logAndSendMessage(sender, "Purge is already in progress! Aborting purge request");
+ logger.logAndSendMessage(sender, "Purge is already in progress! Aborting purge request");
return;
}
@@ -117,7 +116,8 @@ void setPurging(boolean purging) {
* @param players the players (associated with the names)
* @param names the lowercase names
*/
- void executePurge(Collection players, Collection names) {
+ void executePurge(@NotNull Collection players, @NotNull Collection names) {
purgeExecutor.executePurge(players, names);
}
+
}
diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java b/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java
index f29d6f71d..4aabfad9c 100644
--- a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java
+++ b/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java
@@ -10,6 +10,7 @@
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
@@ -21,11 +22,16 @@ class PurgeTask extends BukkitRunnable {
private static final int INTERVAL_CHECK = 5;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PurgeTask.class);
+
+ @NotNull
private final PurgeService purgeService;
+ @NotNull
private final PermissionsManager permissionsManager;
private final UUID sender;
+ @NotNull
private final Set toPurge;
+ @NotNull
private final OfflinePlayer[] offlinePlayers;
private final int totalPurgeCount;
@@ -40,8 +46,8 @@ class PurgeTask extends BukkitRunnable {
* @param toPurge lowercase names to purge
* @param offlinePlayers offline players to map to the names
*/
- PurgeTask(PurgeService service, PermissionsManager permissionsManager, CommandSender sender,
- Set toPurge, OfflinePlayer[] offlinePlayers) {
+ PurgeTask(@NotNull PurgeService service, @NotNull PermissionsManager permissionsManager, CommandSender sender,
+ @NotNull Set toPurge, OfflinePlayer[] offlinePlayers) {
this.purgeService = service;
this.permissionsManager = permissionsManager;
@@ -116,7 +122,7 @@ private void finish() {
purgeService.setPurging(false);
}
- private void sendMessage(String message) {
+ private void sendMessage(@NotNull String message) {
if (sender == null) {
Bukkit.getConsoleSender().sendMessage(message);
} else {
@@ -126,4 +132,5 @@ private void sendMessage(String message) {
}
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java b/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java
index 2a50e660a..b0ff14fa7 100644
--- a/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java
+++ b/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java
@@ -5,6 +5,7 @@
* in the given 'interval'.
*/
public class AtomicIntervalCounter {
+
private final int threshold;
private final int interval;
private int count;
@@ -50,4 +51,5 @@ public synchronized boolean handle() {
lastInsert = now;
return false;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/ExceptionUtils.java b/src/main/java/fr/xephi/authme/util/ExceptionUtils.java
index fd5ae8852..daca03780 100644
--- a/src/main/java/fr/xephi/authme/util/ExceptionUtils.java
+++ b/src/main/java/fr/xephi/authme/util/ExceptionUtils.java
@@ -1,7 +1,11 @@
package fr.xephi.authme.util;
-import com.google.common.collect.Sets;
+import org.jetbrains.annotations.NotNull;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.IdentityHashMap;
import java.util.Set;
/**
@@ -21,8 +25,9 @@ private ExceptionUtils() {
* @param the desired throwable subtype
* @return the first throwable found of the given type, or null if none found
*/
- public static T findThrowableInCause(Class wantedThrowableType, Throwable throwable) {
- Set visitedObjects = Sets.newIdentityHashSet();
+ public static T findThrowableInCause(@NotNull Class wantedThrowableType,
+ @NotNull Throwable throwable) {
+ Set visitedObjects = Collections.newSetFromMap(new IdentityHashMap<>());
Throwable currentThrowable = throwable;
while (currentThrowable != null && !visitedObjects.contains(currentThrowable)) {
if (wantedThrowableType.isInstance(currentThrowable)) {
@@ -40,7 +45,22 @@ public static T findThrowableInCause(Class wantedThrowa
* @param th the throwable to process
* @return string with the type of the Throwable and its message, e.g. "[IOException]: Could not open stream"
*/
- public static String formatException(Throwable th) {
+ @NotNull
+ public static String formatException(@NotNull Throwable th) {
return "[" + th.getClass().getSimpleName() + "]: " + th.getMessage();
}
+
+ /**
+ * Returns a string containing the result of {@link Throwable#toString()}, followed by the full, recursive
+ * stack trace of {@code throwable}.
+ *
+ * @param throwable the throwable to precess
+ * @return string containing the stacktrace
+ */
+ public static String getStackTraceAsString(Throwable throwable) {
+ StringWriter stringWriter = new StringWriter();
+ throwable.printStackTrace(new PrintWriter(stringWriter));
+ return stringWriter.toString();
+ }
+
}
diff --git a/src/main/java/fr/xephi/authme/util/FileUtils.java b/src/main/java/fr/xephi/authme/util/FileUtils.java
index 7f7ee4aaa..0fae165c5 100644
--- a/src/main/java/fr/xephi/authme/util/FileUtils.java
+++ b/src/main/java/fr/xephi/authme/util/FileUtils.java
@@ -1,13 +1,14 @@
package fr.xephi.authme.util;
-import com.google.common.io.Files;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
+import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -21,7 +22,7 @@ public final class FileUtils {
private static final DateTimeFormatter CURRENT_DATE_STRING_FORMATTER =
DateTimeFormatter.ofPattern("yyyyMMdd_HHmm");
- private static ConsoleLogger logger = ConsoleLoggerFactory.get(FileUtils.class);
+ private static final ConsoleLogger logger = ConsoleLoggerFactory.get(FileUtils.class);
// Utility class
private FileUtils() {
@@ -35,7 +36,7 @@ private FileUtils() {
*
* @return False if the file does not exist and could not be copied, true otherwise
*/
- public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
+ public static boolean copyFileFromResource(@NotNull File destinationFile, @NotNull String resourcePath) {
if (destinationFile.exists()) {
return true;
} else if (!createDirectory(destinationFile.getParentFile())) {
@@ -48,7 +49,7 @@ public static boolean copyFileFromResource(File destinationFile, String resource
logger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource",
resourcePath, destinationFile.getPath()));
} else {
- java.nio.file.Files.copy(is, destinationFile.toPath());
+ Files.copy(is, destinationFile.toPath());
return true;
}
} catch (IOException e) {
@@ -64,7 +65,7 @@ public static boolean copyFileFromResource(File destinationFile, String resource
* @param dir the directory to create
* @return true upon success, false otherwise
*/
- public static boolean createDirectory(File dir) {
+ public static boolean createDirectory(@NotNull File dir) {
if (!dir.exists() && !dir.mkdirs()) {
logger.warning("Could not create directory '" + dir + "'");
return false;
@@ -72,6 +73,34 @@ public static boolean createDirectory(File dir) {
return dir.isDirectory();
}
+ /**
+ * Creates the given directory, throws a runtime exception on fail.
+ *
+ * @param dir the directory to create
+ * @throws IllegalStateException when unable to create the directory
+ */
+ public static void createDirectoryOrFail(@NotNull File dir) {
+ if (!dir.exists() && !dir.mkdirs() || !dir.isDirectory()) {
+ throw new IllegalStateException("Could not create directory '" + dir + "'");
+ }
+ }
+
+ /**
+ * Creates the given file, throws a runtime exception on fail.
+ *
+ * @param file the file to create
+ * @throws IllegalStateException when unable to create the file
+ */
+ public static void createFileOrFail(@NotNull File file) {
+ try {
+ if (!file.exists() && !file.createNewFile() || !file.isFile()) {
+ throw new IllegalStateException("Could not create file '" + file + "'");
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException("Could not create file '" + file + "'", e);
+ }
+ }
+
/**
* Returns a JAR file as stream. Returns null if it doesn't exist.
*
@@ -165,9 +194,10 @@ public static String createCurrentTimeString() {
* @return path to a file suitably named for storing a backup
*/
public static String createBackupFilePath(File file) {
- String filename = "backup_" + Files.getNameWithoutExtension(file.getName())
+ String filename = "backup_" + com.google.common.io.Files.getNameWithoutExtension(file.getName())
+ "_" + createCurrentTimeString()
- + "." + Files.getFileExtension(file.getName());
+ + "." + com.google.common.io.Files.getFileExtension(file.getName());
return makePath(file.getParent(), filename);
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java b/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java
index 039421548..34203f3e8 100644
--- a/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java
+++ b/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util;
+import org.jetbrains.annotations.NotNull;
+
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -18,7 +20,7 @@ private InternetProtocolUtils() {
* @param address address to check
* @return true if the address is a local (site and link) or loopback address, false otherwise
*/
- public static boolean isLocalAddress(String address) {
+ public static boolean isLocalAddress(@NotNull String address) {
try {
InetAddress inetAddress = InetAddress.getByName(address);
@@ -48,7 +50,7 @@ public static boolean isLocalAddress(String address) {
* @param address address to check
* @return true if the address is a loopback one
*/
- public static boolean isLoopbackAddress(String address) {
+ public static boolean isLoopbackAddress(@NotNull String address) {
try {
InetAddress inetAddress = InetAddress.getByName(address);
return inetAddress.isLoopbackAddress();
@@ -57,11 +59,7 @@ public static boolean isLoopbackAddress(String address) {
}
}
- private static boolean isLoopbackAddress(InetAddress address) {
- return address.isLoopbackAddress();
- }
-
- private static boolean isIPv6UniqueSiteLocal(InetAddress address) {
+ private static boolean isIPv6UniqueSiteLocal(@NotNull InetAddress address) {
// ref: https://en.wikipedia.org/wiki/Unique_local_address
// currently undefined but could be used in the near future fc00::/8
@@ -69,4 +67,5 @@ private static boolean isIPv6UniqueSiteLocal(InetAddress address) {
// in use for unique site-local fd00::/8
|| (address.getAddress()[0] & 0xFF) == 0xFD;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/PlayerUtils.java b/src/main/java/fr/xephi/authme/util/PlayerUtils.java
index 04216933c..ffed6469d 100644
--- a/src/main/java/fr/xephi/authme/util/PlayerUtils.java
+++ b/src/main/java/fr/xephi/authme/util/PlayerUtils.java
@@ -1,6 +1,9 @@
package fr.xephi.authme.util;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
/**
* Player utilities.
@@ -15,9 +18,12 @@ private PlayerUtils() {
* Returns the IP of the given player.
*
* @param player The player to return the IP address for
+ *
* @return The player's IP address
*/
- public static String getPlayerIp(Player player) {
+ @NotNull
+ public static String getPlayerIp(@NotNull Player player) {
+ Objects.requireNonNull(player.getAddress(), "address");
return player.getAddress().getAddress().getHostAddress();
}
@@ -25,9 +31,10 @@ public static String getPlayerIp(Player player) {
* Returns if the player is an NPC or not.
*
* @param player The player to check
+ *
* @return True if the player is an NPC, false otherwise
*/
- public static boolean isNpc(Player player) {
+ public static boolean isNpc(@NotNull Player player) {
return player.hasMetadata("NPC");
}
diff --git a/src/main/java/fr/xephi/authme/util/StringUtils.java b/src/main/java/fr/xephi/authme/util/StringUtils.java
index 5c8613005..49ae5c85c 100644
--- a/src/main/java/fr/xephi/authme/util/StringUtils.java
+++ b/src/main/java/fr/xephi/authme/util/StringUtils.java
@@ -3,6 +3,7 @@
import net.ricecode.similarity.LevenshteinDistanceStrategy;
import net.ricecode.similarity.StringSimilarityService;
import net.ricecode.similarity.StringSimilarityServiceImpl;
+import org.jetbrains.annotations.NotNull;
/**
* Utility class for String operations.
@@ -42,7 +43,7 @@ public static double getDifference(String first, String second) {
*
* @return True if the string contains at least one of the items
*/
- public static boolean containsAny(String str, Iterable pieces) {
+ public static boolean containsAny(String str, @NotNull Iterable pieces) {
if (str == null) {
return false;
}
@@ -77,8 +78,9 @@ public static boolean isEmpty(String str) {
*/
// Note ljacqu 20170314: `needle` is restricted to char type intentionally because something like
// isInsideString("11", "2211") would unexpectedly return true...
- public static boolean isInsideString(char needle, String haystack) {
+ public static boolean isInsideString(char needle, @NotNull String haystack) {
int index = haystack.indexOf(needle);
return index > 0 && index < haystack.length() - 1;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java
index 74c3088e3..fc58e42a8 100644
--- a/src/main/java/fr/xephi/authme/util/Utils.java
+++ b/src/main/java/fr/xephi/authme/util/Utils.java
@@ -5,8 +5,11 @@
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
+import org.jetbrains.annotations.NotNull;
import java.util.Collection;
+import java.util.function.Function;
+import java.util.function.Supplier;
import java.util.regex.Pattern;
/**
@@ -17,7 +20,8 @@ public final class Utils {
/** Number of milliseconds in a minute. */
public static final long MILLIS_PER_MINUTE = 60_000L;
- private static ConsoleLogger logger = ConsoleLoggerFactory.get(Utils.class);
+ /** A pattern that matches anything. */
+ public static final Pattern MATCH_ANYTHING_PATTERN = Pattern.compile(".*?");
// Utility class
private Utils() {
@@ -26,16 +30,16 @@ private Utils() {
/**
* Compile Pattern sneaky without throwing Exception.
*
- * @param pattern pattern string to compile
+ * @param pattern pattern string to compile
+ * @param fallback the fallback pattern supplier
*
* @return the given regex compiled into Pattern object.
*/
- public static Pattern safePatternCompile(String pattern) {
+ public static Pattern safePatternCompile(@NotNull String pattern, @NotNull Function fallback) {
try {
return Pattern.compile(pattern);
} catch (Exception e) {
- logger.warning("Failed to compile pattern '" + pattern + "' - defaulting to allowing everything");
- return Pattern.compile(".*?");
+ return fallback.apply(pattern);
}
}
@@ -46,7 +50,7 @@ public static Pattern safePatternCompile(String pattern) {
*
* @return true if the class is loaded, false otherwise
*/
- public static boolean isClassLoaded(String className) {
+ public static boolean isClassLoaded(@NotNull String className) {
try {
Class.forName(className);
return true;
@@ -55,38 +59,6 @@ public static boolean isClassLoaded(String className) {
}
}
- /**
- * Sends a message to the given sender (null safe), and logs the message to the console.
- * This method is aware that the command sender might be the console sender and avoids
- * displaying the message twice in this case.
- *
- * @param sender the sender to inform
- * @param message the message to log and send
- */
- public static void logAndSendMessage(CommandSender sender, String message) {
- logger.info(message);
- // Make sure sender is not console user, which will see the message from ConsoleLogger already
- if (sender != null && !(sender instanceof ConsoleCommandSender)) {
- sender.sendMessage(message);
- }
- }
-
- /**
- * Sends a warning to the given sender (null safe), and logs the warning to the console.
- * This method is aware that the command sender might be the console sender and avoids
- * displaying the message twice in this case.
- *
- * @param sender the sender to inform
- * @param message the warning to log and send
- */
- public static void logAndSendWarning(CommandSender sender, String message) {
- logger.warning(message);
- // Make sure sender is not console user, which will see the message from ConsoleLogger already
- if (sender != null && !(sender instanceof ConsoleCommandSender)) {
- sender.sendMessage(ChatColor.RED + message);
- }
- }
-
/**
* Null-safe way to check whether a collection is empty or not.
*
@@ -107,4 +79,18 @@ public static boolean isCollectionEmpty(Collection> coll) {
public static boolean isEmailEmpty(String email) {
return StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email);
}
+
+ /**
+ * Tries to parse a String as an Integer, returns null on fail.
+ *
+ * @return the parsed Integer value
+ */
+ public static Integer tryInteger(@NotNull String string) {
+ try {
+ return Integer.parseInt(string);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
}
diff --git a/src/main/java/fr/xephi/authme/util/UuidUtils.java b/src/main/java/fr/xephi/authme/util/UuidUtils.java
index be35a9351..ec91703b4 100644
--- a/src/main/java/fr/xephi/authme/util/UuidUtils.java
+++ b/src/main/java/fr/xephi/authme/util/UuidUtils.java
@@ -24,4 +24,5 @@ public static UUID parseUuidSafely(String string) {
return null;
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/expiring/Duration.java b/src/main/java/fr/xephi/authme/util/expiring/Duration.java
index ecc86299e..e216d8cb6 100644
--- a/src/main/java/fr/xephi/authme/util/expiring/Duration.java
+++ b/src/main/java/fr/xephi/authme/util/expiring/Duration.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.expiring;
+import org.jetbrains.annotations.NotNull;
+
import java.util.concurrent.TimeUnit;
/**
@@ -8,6 +10,7 @@
public class Duration {
private final long duration;
+ @NotNull
private final TimeUnit unit;
/**
@@ -16,7 +19,7 @@ public class Duration {
* @param duration the duration
* @param unit the time unit in which {@code duration} is expressed
*/
- public Duration(long duration, TimeUnit unit) {
+ public Duration(long duration, @NotNull TimeUnit unit) {
this.duration = duration;
this.unit = unit;
}
@@ -38,7 +41,8 @@ public Duration(long duration, TimeUnit unit) {
* @param sourceUnit the time unit the duration is expressed in
* @return Duration object using the most suitable time unit
*/
- public static Duration createWithSuitableUnit(long sourceDuration, TimeUnit sourceUnit) {
+ @NotNull
+ public static Duration createWithSuitableUnit(long sourceDuration, @NotNull TimeUnit sourceUnit) {
long durationMillis = Math.abs(TimeUnit.MILLISECONDS.convert(sourceDuration, sourceUnit));
TimeUnit targetUnit;
@@ -66,7 +70,9 @@ public long getDuration() {
/**
* @return the time unit in which the duration is expressed
*/
+ @NotNull
public TimeUnit getTimeUnit() {
return unit;
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java b/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java
index 3bf19351b..a21075383 100644
--- a/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java
+++ b/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.expiring;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@@ -24,6 +26,7 @@
*/
public class ExpiringMap {
+ @NotNull
private final Map> entries = new ConcurrentHashMap<>();
private long expirationMillis;
@@ -33,7 +36,7 @@ public class ExpiringMap {
* @param duration the duration of time after which entries expire
* @param unit the time unit in which {@code duration} is expressed
*/
- public ExpiringMap(long duration, TimeUnit unit) {
+ public ExpiringMap(long duration, @NotNull TimeUnit unit) {
setExpiration(duration, unit);
}
@@ -44,7 +47,7 @@ public ExpiringMap(long duration, TimeUnit unit) {
* @param key the key to look up
* @return the associated value, or {@code null} if not available
*/
- public V get(K key) {
+ public V get(@NotNull K key) {
ExpiringEntry value = entries.get(key);
if (value == null) {
return null;
@@ -62,7 +65,7 @@ public V get(K key) {
* @param key the key to insert a value for
* @param value the value to insert
*/
- public void put(K key, V value) {
+ public void put(@NotNull K key, @NotNull V value) {
long expiration = System.currentTimeMillis() + expirationMillis;
entries.put(key, new ExpiringEntry<>(value, expiration));
}
@@ -72,7 +75,7 @@ public void put(K key, V value) {
*
* @param key the key to remove the value for
*/
- public void remove(K key) {
+ public void remove(@NotNull K key) {
entries.remove(key);
}
@@ -90,7 +93,7 @@ public void removeExpiredEntries() {
* @param duration the duration of time after which entries expire
* @param unit the time unit in which {@code duration} is expressed
*/
- public void setExpiration(long duration, TimeUnit unit) {
+ public void setExpiration(long duration, @NotNull TimeUnit unit) {
this.expirationMillis = unit.toMillis(duration);
}
@@ -108,6 +111,7 @@ public boolean isEmpty() {
/**
* @return the internal map
*/
+ @NotNull
protected Map> getEntries() {
return entries;
}
@@ -119,15 +123,16 @@ protected Map> getEntries() {
*/
protected static final class ExpiringEntry {
+ @NotNull
private final V value;
private final long expiration;
- ExpiringEntry(V value, long expiration) {
+ ExpiringEntry(@NotNull V value, long expiration) {
this.value = value;
this.expiration = expiration;
}
- V getValue() {
+ @NotNull V getValue() {
return value;
}
@@ -135,4 +140,5 @@ long getExpiration() {
return expiration;
}
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java b/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java
index fea8fb313..e547fd5be 100644
--- a/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java
+++ b/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.expiring;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@@ -18,7 +20,8 @@
*/
public class ExpiringSet {
- private Map entries = new ConcurrentHashMap<>();
+ @NotNull
+ private final Map entries = new ConcurrentHashMap<>();
private long expirationMillis;
/**
@@ -27,7 +30,7 @@ public class ExpiringSet {
* @param duration the duration of time after which entries expire
* @param unit the time unit in which {@code duration} is expressed
*/
- public ExpiringSet(long duration, TimeUnit unit) {
+ public ExpiringSet(long duration, @NotNull TimeUnit unit) {
setExpiration(duration, unit);
}
@@ -36,7 +39,7 @@ public ExpiringSet(long duration, TimeUnit unit) {
*
* @param entry the entry to add
*/
- public void add(E entry) {
+ public void add(@NotNull E entry) {
entries.put(entry, System.currentTimeMillis() + expirationMillis);
}
@@ -46,7 +49,7 @@ public void add(E entry) {
* @param entry the entry to check
* @return true if the entry is present and not expired, false otherwise
*/
- public boolean contains(E entry) {
+ public boolean contains(@NotNull E entry) {
Long expiration = entries.get(entry);
if (expiration == null) {
return false;
@@ -63,7 +66,7 @@ public boolean contains(E entry) {
*
* @param entry the entry to remove
*/
- public void remove(E entry) {
+ public void remove(@NotNull E entry) {
entries.remove(entry);
}
@@ -88,7 +91,8 @@ public void removeExpiredEntries() {
* @param entry the entry whose duration before it expires should be returned
* @return duration the entry will remain in the set (if there are not modifications)
*/
- public Duration getExpiration(E entry) {
+ @NotNull
+ public Duration getExpiration(@NotNull E entry) {
Long expiration = entries.get(entry);
if (expiration == null) {
return new Duration(-1, TimeUnit.SECONDS);
@@ -108,7 +112,7 @@ public Duration getExpiration(E entry) {
* @param duration the duration of time after which entries expire
* @param unit the time unit in which {@code duration} is expressed
*/
- public void setExpiration(long duration, TimeUnit unit) {
+ public void setExpiration(long duration, @NotNull TimeUnit unit) {
this.expirationMillis = unit.toMillis(duration);
}
diff --git a/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java b/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java
index d6d8bba1d..84e332b9d 100644
--- a/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java
+++ b/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.expiring;
+import org.jetbrains.annotations.NotNull;
+
import java.util.concurrent.TimeUnit;
/**
@@ -18,12 +20,13 @@ public class TimedCounter extends ExpiringMap {
* @param duration the duration of time after which entries expire
* @param unit the time unit in which {@code duration} is expressed
*/
- public TimedCounter(long duration, TimeUnit unit) {
+ public TimedCounter(long duration, @NotNull TimeUnit unit) {
super(duration, unit);
}
@Override
- public Integer get(K key) {
+ @NotNull
+ public Integer get(@NotNull K key) {
Integer value = super.get(key);
return value == null ? 0 : value;
}
@@ -33,7 +36,7 @@ public Integer get(K key) {
*
* @param key the key to increment the counter for
*/
- public void increment(K key) {
+ public void increment(@NotNull K key) {
put(key, get(key) + 1);
}
@@ -43,7 +46,7 @@ public void increment(K key) {
*
* @param key the key to increment the counter for
*/
- public void decrement(K key) {
+ public void decrement(@NotNull K key) {
ExpiringEntry e = getEntries().get(key);
if (e != null) {
@@ -67,4 +70,5 @@ public int total() {
.map(ExpiringEntry::getValue)
.reduce(0, Integer::sum);
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java b/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java
index 5fb0cd3d3..f9fc8bce2 100644
--- a/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java
+++ b/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.lazytags;
+import org.jetbrains.annotations.NotNull;
+
import java.util.function.Function;
/**
@@ -9,7 +11,9 @@
*/
public class DependentTag implements Tag {
+ @NotNull
private final String name;
+ @NotNull
private final Function replacementFunction;
/**
@@ -18,18 +22,21 @@ public class DependentTag implements Tag {
* @param name the tag (placeholder) that will be replaced
* @param replacementFunction the function producing the replacement
*/
- public DependentTag(String name, Function replacementFunction) {
+ public DependentTag(@NotNull String name, @NotNull Function replacementFunction) {
this.name = name;
this.replacementFunction = replacementFunction;
}
@Override
+ @NotNull
public String getName() {
return name;
}
@Override
- public String getValue(A argument) {
+ @NotNull
+ public String getValue(@NotNull A argument) {
return replacementFunction.apply(argument);
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java b/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java
index a5bb58a26..b6c86e556 100644
--- a/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java
+++ b/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.lazytags;
+import org.jetbrains.annotations.NotNull;
+
import java.util.function.Supplier;
/**
@@ -9,21 +11,26 @@
*/
public class SimpleTag implements Tag {
+ @NotNull
private final String name;
+ @NotNull
private final Supplier replacementFunction;
- public SimpleTag(String name, Supplier replacementFunction) {
+ public SimpleTag(@NotNull String name, @NotNull Supplier replacementFunction) {
this.name = name;
this.replacementFunction = replacementFunction;
}
@Override
+ @NotNull
public String getName() {
return name;
}
@Override
+ @NotNull
public String getValue(A argument) {
return replacementFunction.get();
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/Tag.java b/src/main/java/fr/xephi/authme/util/lazytags/Tag.java
index 2c7c6ba53..4722133b3 100644
--- a/src/main/java/fr/xephi/authme/util/lazytags/Tag.java
+++ b/src/main/java/fr/xephi/authme/util/lazytags/Tag.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.lazytags;
+import org.jetbrains.annotations.NotNull;
+
/**
* Represents a tag in a text to be replaced with a value (which may depend on some argument).
*
@@ -10,6 +12,7 @@ public interface Tag {
/**
* @return the tag to replace
*/
+ @NotNull
String getName();
/**
@@ -18,5 +21,7 @@ public interface Tag {
* @param argument the argument to evaluate the replacement for
* @return the replacement
*/
+ @NotNull
String getValue(A argument);
+
}
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java b/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java
index 677b30e2f..84d330b80 100644
--- a/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java
+++ b/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.lazytags;
+import org.jetbrains.annotations.NotNull;
+
import java.util.function.Function;
import java.util.function.Supplier;
@@ -11,11 +13,14 @@ public final class TagBuilder {
private TagBuilder() {
}
- public static Tag createTag(String name, Function replacementFunction) {
+ @NotNull
+ public static Tag createTag(@NotNull String name, @NotNull Function replacementFunction) {
return new DependentTag<>(name, replacementFunction);
}
- public static Tag createTag(String name, Supplier replacementFunction) {
+ @NotNull
+ public static Tag createTag(@NotNull String name, @NotNull Supplier replacementFunction) {
return new SimpleTag<>(name, replacementFunction);
}
+
}
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java b/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java
index a9d193199..5812754b7 100644
--- a/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java
+++ b/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.lazytags;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -13,7 +15,9 @@
*/
public final class TagReplacer {
+ @NotNull
private final List> tags;
+ @NotNull
private final Collection messages;
/**
@@ -22,7 +26,7 @@ public final class TagReplacer {
* @param tags the tags that are being used in the messages
* @param messages the messages
*/
- private TagReplacer(List> tags, Collection messages) {
+ private TagReplacer(@NotNull List> tags, @NotNull Collection messages) {
this.tags = tags;
this.messages = messages;
}
@@ -36,7 +40,9 @@ private TagReplacer(List> tags, Collection messages) {
* @param the argument type
* @return new tag replacer instance
*/
- public static TagReplacer newReplacer(Collection> allTags, Collection messages) {
+ @NotNull
+ public static TagReplacer newReplacer(@NotNull Collection> allTags,
+ @NotNull Collection messages) {
List> usedTags = determineUsedTags(allTags, messages);
return new TagReplacer<>(usedTags, messages);
}
@@ -47,7 +53,8 @@ public static TagReplacer newReplacer(Collection> allTags, Collect
* @param argument the argument to get the messages for
* @return the adapted messages
*/
- public List getAdaptedMessages(A argument) {
+ @NotNull
+ public List getAdaptedMessages(@NotNull A argument) {
// Note ljacqu 20170121: Using a Map might seem more natural here but we avoid doing so for performance
// Although the performance gain here is probably minimal...
List tagValues = new LinkedList<>();
@@ -74,7 +81,9 @@ public List getAdaptedMessages(A argument) {
* @param argument type
* @return tags used at least once
*/
- private static List> determineUsedTags(Collection> allTags, Collection messages) {
+ @NotNull
+ private static List> determineUsedTags(@NotNull Collection> allTags,
+ @NotNull Collection messages) {
return allTags.stream()
.filter(tag -> messages.stream().anyMatch(msg -> msg.contains(tag.getName())))
.collect(Collectors.toList());
@@ -84,11 +93,13 @@ private static List> determineUsedTags(Collection> allTags, Co
private static final class TagValue {
/** The tag to replace. */
+ @NotNull
private final String tag;
/** The value to replace with. */
+ @NotNull
private final String value;
- TagValue(String tag, String value) {
+ TagValue(@NotNull String tag, @NotNull String value) {
this.tag = tag;
this.value = value;
}
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java b/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java
index ce9487e21..4003cacf9 100644
--- a/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java
+++ b/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java
@@ -1,5 +1,7 @@
package fr.xephi.authme.util.lazytags;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
@@ -18,8 +20,11 @@
*/
public class WrappedTagReplacer {
+ @NotNull
private final Collection items;
+ @NotNull
private final BiFunction itemCreator;
+ @NotNull
private final TagReplacer tagReplacer;
/**
@@ -30,10 +35,10 @@ public class WrappedTagReplacer {
* @param stringGetter getter of the String property to adapt on the items
* @param itemCreator a function taking (T, String): the original item and the adapted String, returning a new item
*/
- public WrappedTagReplacer(Collection> allTags,
- Collection items,
- Function super T, String> stringGetter,
- BiFunction itemCreator) {
+ public WrappedTagReplacer(@NotNull Collection> allTags,
+ @NotNull Collection items,
+ @NotNull Function super T, String> stringGetter,
+ @NotNull BiFunction itemCreator) {
this.items = items;
this.itemCreator = itemCreator;
@@ -47,7 +52,8 @@ public WrappedTagReplacer(Collection> allTags,
* @param argument the argument to adapt the items for
* @return the adapted items
*/
- public List getAdaptedItems(A argument) {
+ @NotNull
+ public List getAdaptedItems(@NotNull A argument) {
List adaptedStrings = tagReplacer.getAdaptedMessages(argument);
List adaptedItems = new LinkedList<>();
@@ -58,4 +64,5 @@ public List getAdaptedItems(A argument) {
}
return adaptedItems;
}
+
}
diff --git a/src/main/resources/email.html b/src/main/resources/email.html
index a2a7ed060..fd60c2ff2 100644
--- a/src/main/resources/email.html
+++ b/src/main/resources/email.html
@@ -1,3 +1,4 @@
+
\ No newline at end of file
+
diff --git a/src/main/resources/recovery_code_email.html b/src/main/resources/recovery_code_email.html
index fc7327a1e..e08439572 100644
--- a/src/main/resources/recovery_code_email.html
+++ b/src/main/resources/recovery_code_email.html
@@ -1,3 +1,4 @@
+