Merge branch 'master' into sensitive-commands

This commit is contained in:
Gabriele C 2019-08-08 17:36:29 +02:00 committed by GitHub
commit 07fa186086
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
170 changed files with 2339 additions and 932 deletions

View File

@ -90,6 +90,23 @@ You can also create your own translation file and, if you want, you can share it
- **Dev resources:** - **Dev resources:**
- <a href="https://ci.codemc.org/job/AuthMe/job/AuthMeReloaded/javadoc/">JavaDocs</a> - <a href="https://ci.codemc.org/job/AuthMe/job/AuthMeReloaded/javadoc/">JavaDocs</a>
- <a href="http://repo.codemc.org/repository/maven-public/">Maven Repository</a> - <a href="http://repo.codemc.org/repository/maven-public/">Maven Repository</a>
```xml
<repositories>
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>fr.xephi</groupId>
<artifactId>authme</artifactId>
<version>5.6.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
- **Statistics:** - **Statistics:**
![Graph](https://bstats.org/signatures/bukkit/AuthMe.svg) ![Graph](https://bstats.org/signatures/bukkit/AuthMe.svg)
@ -114,9 +131,6 @@ You can also create your own translation file and, if you want, you can share it
## Credits ## Credits
##### Sponsor:
[FastVM.io](https://fastvm.io) is leader in VPS hosting solutions. With its own DataCenter offers Anti-DDoS solutions at affordable prices.
##### Contributors: ##### Contributors:
Team members: <a href="https://github.com/AuthMe/AuthMeReloaded/wiki/Development-team">developers</a>, <a href="https://github.com/AuthMe/AuthMeReloaded/wiki/Translators">translators</a> Team members: <a href="https://github.com/AuthMe/AuthMeReloaded/wiki/Development-team">developers</a>, <a href="https://github.com/AuthMe/AuthMeReloaded/wiki/Translators">translators</a>

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Sun Apr 22 11:00:10 CEST 2018. See docs/commands/commands.tpl.md --> <!-- File auto-generated on Fri Aug 02 16:25:51 CEST 2019. See docs/commands/commands.tpl.md -->
## AuthMe Commands ## AuthMe Commands
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >`
@ -24,6 +24,10 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
<br />Requires `authme.admin.changemail` <br />Requires `authme.admin.changemail`
- **/authme getip** &lt;player>: Get the IP address of the specified online player. - **/authme getip** &lt;player>: Get the IP address of the specified online player.
<br />Requires `authme.admin.getip` <br />Requires `authme.admin.getip`
- **/authme totp** &lt;player>: Returns whether the specified player has enabled two-factor authentication
<br />Requires `authme.admin.totpviewstatus`
- **/authme disabletotp** &lt;player>: Disable two-factor authentication for a player
<br />Requires `authme.admin.totpdisable`
- **/authme spawn**: Teleport to the spawn. - **/authme spawn**: Teleport to the spawn.
<br />Requires `authme.admin.spawn` <br />Requires `authme.admin.spawn`
- **/authme setspawn**: Change the player's spawn to your current position. - **/authme setspawn**: Change the player's spawn to your current position.
@ -104,4 +108,4 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
--- ---
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Apr 22 11:00:10 CEST 2018 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Aug 02 16:25:51 CEST 2019

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Mon May 21 09:08:25 CEST 2018. See docs/config/config.tpl.md --> <!-- File auto-generated on Tue Apr 23 17:17:02 CEST 2019. See docs/config/config.tpl.md -->
## AuthMe Configuration ## AuthMe Configuration
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
@ -7,66 +7,69 @@ with which you can configure various settings. This following is the initial con
the generated config.yml file. the generated config.yml file.
```yml ```yml
DataSource: DataSource:
# What type of database do you want to use? # What type of database do you want to use?
# Valid values: SQLITE, MYSQL # Valid values: SQLITE, MYSQL, POSTGRESQL
backend: 'SQLITE' backend: SQLITE
# Enable the database caching system, should be disabled on bungeecord environments # Enable the database caching system, should be disabled on bungeecord environments
# or when a website integration is being used. # or when a website integration is being used.
caching: true caching: true
# Database host address # Database host address
mySQLHost: '127.0.0.1' mySQLHost: 127.0.0.1
# Database port # Database port
mySQLPort: '3306' mySQLPort: '3306'
# Connect to MySQL database over SSL # Connect to MySQL database over SSL
mySQLUseSSL: true mySQLUseSSL: true
# Verification of server's certificate.
# We would not recommend to set this option to false.
# Set this option to false at your own risk if and only if you know what you're doing
mySQLCheckServerCertificate: true
# Username to connect to the MySQL database # Username to connect to the MySQL database
mySQLUsername: 'authme' mySQLUsername: authme
# Password to connect to the MySQL database # Password to connect to the MySQL database
mySQLPassword: '12345' mySQLPassword: '12345'
# Database Name, use with converters or as SQLITE database name # Database Name, use with converters or as SQLITE database name
mySQLDatabase: 'authme' mySQLDatabase: authme
# Table of the database # Table of the database
mySQLTablename: 'authme' mySQLTablename: authme
# Column of IDs to sort data # Column of IDs to sort data
mySQLColumnId: 'id' mySQLColumnId: id
# Column for storing or checking players nickname # Column for storing or checking players nickname
mySQLColumnName: 'username' mySQLColumnName: username
# Column for storing or checking players RealName # Column for storing or checking players RealName
mySQLRealName: 'realname' mySQLRealName: realname
# Column for storing players passwords # Column for storing players passwords
mySQLColumnPassword: 'password' mySQLColumnPassword: password
# Column for storing players passwords salts # Column for storing players passwords salts
mySQLColumnSalt: '' mySQLColumnSalt: ''
# Column for storing players emails # Column for storing players emails
mySQLColumnEmail: 'email' mySQLColumnEmail: email
# Column for storing if a player is logged in or not # Column for storing if a player is logged in or not
mySQLColumnLogged: 'isLogged' mySQLColumnLogged: isLogged
# Column for storing if a player has a valid session or not # Column for storing if a player has a valid session or not
mySQLColumnHasSession: 'hasSession' mySQLColumnHasSession: hasSession
# Column for storing a player's TOTP key (for two-factor authentication) # Column for storing a player's TOTP key (for two-factor authentication)
mySQLtotpKey: 'totp' mySQLtotpKey: totp
# Column for storing the player's last IP # Column for storing the player's last IP
mySQLColumnIp: 'ip' mySQLColumnIp: ip
# Column for storing players lastlogins # Column for storing players lastlogins
mySQLColumnLastLogin: 'lastlogin' mySQLColumnLastLogin: lastlogin
# Column storing the registration date # Column storing the registration date
mySQLColumnRegisterDate: 'regdate' mySQLColumnRegisterDate: regdate
# Column for storing the IP address at the time of registration # Column for storing the IP address at the time of registration
mySQLColumnRegisterIp: 'regip' mySQLColumnRegisterIp: regip
# Column for storing player LastLocation - X # Column for storing player LastLocation - X
mySQLlastlocX: 'x' mySQLlastlocX: x
# Column for storing player LastLocation - Y # Column for storing player LastLocation - Y
mySQLlastlocY: 'y' mySQLlastlocY: y
# Column for storing player LastLocation - Z # Column for storing player LastLocation - Z
mySQLlastlocZ: 'z' mySQLlastlocZ: z
# Column for storing player LastLocation - World Name # Column for storing player LastLocation - World Name
mySQLlastlocWorld: 'world' mySQLlastlocWorld: world
# Column for storing player LastLocation - Yaw # Column for storing player LastLocation - Yaw
mySQLlastlocYaw: 'yaw' mySQLlastlocYaw: yaw
# Column for storing player LastLocation - Pitch # Column for storing player LastLocation - Pitch
mySQLlastlocPitch: 'pitch' mySQLlastlocPitch: pitch
# Overrides the size of the DB Connection Pool, default = 10 # Overrides the size of the DB Connection Pool, default = 10
poolSize: 10 poolSize: 10
# The maximum lifetime of a connection in the pool, default = 1800 seconds # The maximum lifetime of a connection in the pool, default = 1800 seconds
@ -84,19 +87,19 @@ ExternalBoardOptions:
# How much log2 rounds needed in BCrypt (do not change if you do not know what it does) # How much log2 rounds needed in BCrypt (do not change if you do not know what it does)
bCryptLog2Round: 10 bCryptLog2Round: 10
# phpBB table prefix defined during the phpBB installation process # phpBB table prefix defined during the phpBB installation process
phpbbTablePrefix: 'phpbb_' phpbbTablePrefix: phpbb_
# phpBB activated group ID; 2 is the default registered group defined by phpBB # phpBB activated group ID; 2 is the default registered group defined by phpBB
phpbbActivatedGroupId: 2 phpbbActivatedGroupId: 2
# IP Board table prefix defined during the IP Board installation process # IP Board table prefix defined during the IP Board installation process
IPBTablePrefix: 'ipb_' IPBTablePrefix: ipb_
# IP Board default group ID; 3 is the default registered group defined by IP Board # IP Board default group ID; 3 is the default registered group defined by IP Board
IPBActivatedGroupId: 3 IPBActivatedGroupId: 3
# Xenforo table prefix defined during the Xenforo installation process # Xenforo table prefix defined during the Xenforo installation process
XFTablePrefix: 'xf_' XFTablePrefix: xf_
# XenForo default group ID; 2 is the default registered group defined by Xenforo # XenForo default group ID; 2 is the default registered group defined by Xenforo
XFActivatedGroupId: 2 XFActivatedGroupId: 2
# Wordpress prefix defined during WordPress installation # Wordpress prefix defined during WordPress installation
wordpressTablePrefix: 'wp_' wordpressTablePrefix: wp_
settings: settings:
sessions: sessions:
# Do you want to enable the session feature? # Do you want to enable the session feature?
@ -111,13 +114,13 @@ settings:
timeout: 10 timeout: 10
# Message language, available languages: # Message language, available languages:
# https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md # https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md
messagesLanguage: 'en' messagesLanguage: en
# Forces authme to hook into Vault instead of a specific permission handler system. # Forces authme to hook into Vault instead of a specific permission handler system.
forceVaultHook: false forceVaultHook: false
# Log level: INFO, FINE, DEBUG. Use INFO for general messages, # Log level: INFO, FINE, DEBUG. Use INFO for general messages,
# FINE for some additional detailed ones (like password failed), # FINE for some additional detailed ones (like password failed),
# and DEBUG for debugging # and DEBUG for debugging
logLevel: 'FINE' logLevel: FINE
# By default we schedule async tasks when talking to the database. If you want # By default we schedule async tasks when talking to the database. If you want
# typical communication with the database to happen synchronously, set this to false # typical communication with the database to happen synchronously, set this to false
useAsyncTasks: true useAsyncTasks: true
@ -125,6 +128,8 @@ settings:
# but it is incompatible with any permission plugin not included in our compatibility list. # but it is incompatible with any permission plugin not included in our compatibility list.
# If you have issues with permission checks on player join please disable this option. # If you have issues with permission checks on player join please disable this option.
useAsyncPreLoginEvent: true useAsyncPreLoginEvent: true
# The name of the server, used in some placeholders.
serverName: Your Minecraft Server
restrictions: restrictions:
# Can not authenticated players chat? # Can not authenticated players chat?
# Keep in mind that this feature also blocks all commands not # Keep in mind that this feature also blocks all commands not
@ -134,14 +139,14 @@ settings:
hideChat: false hideChat: false
# Allowed commands for unauthenticated players # Allowed commands for unauthenticated players
allowCommands: allowCommands:
- '/login' - /login
- '/register' - /register
- '/l' - /l
- '/reg' - /reg
- '/email' - /email
- '/captcha' - /captcha
- '/2fa' - /2fa
- '/totp' - /totp
# Max number of allowed registrations per IP # Max number of allowed registrations per IP
# The value 0 means an unlimited number of registrations! # The value 0 means an unlimited number of registrations!
maxRegPerIp: 1 maxRegPerIp: 1
@ -163,9 +168,9 @@ settings:
# WorldNames where we need to force the spawn location # WorldNames where we need to force the spawn location
# Case-sensitive! # Case-sensitive!
worlds: worlds:
- 'world' - world
- 'world_nether' - world_nether
- 'world_the_end' - world_the_end
# This option will save the quit location of the players. # This option will save the quit location of the players.
SaveQuitLocation: false SaveQuitLocation: false
# To activate the restricted user feature you need # To activate the restricted user feature you need
@ -207,7 +212,7 @@ settings:
# permission: /authme.admin.accounts # permission: /authme.admin.accounts
displayOtherAccounts: true displayOtherAccounts: true
# Spawn priority; values: authme, essentials, cmi, multiverse, default # Spawn priority; values: authme, essentials, cmi, multiverse, default
spawnPriority: 'authme,essentials,cmi,multiverse,default' spawnPriority: authme,essentials,cmi,multiverse,default
# Maximum Login authorized by IP # Maximum Login authorized by IP
maxLoginPerIp: 0 maxLoginPerIp: 0
# Maximum Join authorized by IP # Maximum Join authorized by IP
@ -230,6 +235,14 @@ settings:
# - 'npcPlayer' # - 'npcPlayer'
# - 'npcPlayer2' # - 'npcPlayer2'
UnrestrictedName: [] UnrestrictedName: []
# Below you can list all inventories names that AuthMe will ignore
# for registration or login. Configure it at your own risk!!
# This option adds compatibility with some mods.
# It is case-insensitive! Example:
# UnrestrictedInventories:
# - 'myCustomInventory1'
# - 'myCustomInventory2'
UnrestrictedInventories: []
security: security:
# Minimum length of password # Minimum length of password
minPasswordLength: 5 minPasswordLength: 5
@ -240,7 +253,7 @@ settings:
# PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, CUSTOM (for developers only). See full list at # PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, CUSTOM (for developers only). See full list at
# https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md # 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 # If you use ARGON2, check that you have the argon2 c library on your system
passwordHash: 'SHA256' passwordHash: SHA256
# If a password check fails, AuthMe will also try to check with the following hash methods. # If a password check fails, AuthMe will also try to check with the following hash methods.
# Use this setting when you change from one hash method to another. # Use this setting when you change from one hash method to another.
# AuthMe will update the password to the new hash. Example: # AuthMe will update the password to the new hash. Example:
@ -259,12 +272,12 @@ settings:
# - 'help' # - 'help'
unsafePasswords: unsafePasswords:
- '123456' - '123456'
- 'password' - password
- 'qwerty' - qwerty
- '12345' - '12345'
- '54321' - '54321'
- '123456789' - '123456789'
- 'help' - help
registration: registration:
# Enable registration on the server? # Enable registration on the server?
enabled: true enabled: true
@ -278,12 +291,12 @@ settings:
# PASSWORD = account is registered with a password supplied by the user; # PASSWORD = account is registered with a password supplied by the user;
# EMAIL = password is generated and sent to the email provided by the user. # EMAIL = password is generated and sent to the email provided by the user.
# More info at https://github.com/AuthMe/AuthMeReloaded/wiki/Registration # More info at https://github.com/AuthMe/AuthMeReloaded/wiki/Registration
type: 'PASSWORD' type: PASSWORD
# Second argument the /register command should take: NONE = no 2nd argument # Second argument the /register command should take: NONE = no 2nd argument
# CONFIRMATION = must repeat first argument (pass or email) # CONFIRMATION = must repeat first argument (pass or email)
# EMAIL_OPTIONAL = for password register: 2nd argument can be empty or have email address # EMAIL_OPTIONAL = for password register: 2nd argument can be empty or have email address
# EMAIL_MANDATORY = for password register: 2nd argument MUST be an email address # EMAIL_MANDATORY = for password register: 2nd argument MUST be an email address
secondArg: 'CONFIRMATION' secondArg: CONFIRMATION
# Do we force kick a player after a successful registration? # Do we force kick a player after a successful registration?
# Do not use with login feature below # Do not use with login feature below
forceKickAfterRegister: false forceKickAfterRegister: false
@ -339,7 +352,7 @@ GroupOptions:
unregisteredPlayerGroup: '' unregisteredPlayerGroup: ''
Email: Email:
# Email SMTP server host # Email SMTP server host
mailSMTP: 'smtp.gmail.com' mailSMTP: smtp.gmail.com
# Email SMTP server port # Email SMTP server port
mailPort: 465 mailPort: 465
# Only affects port 25: enable TLS/STARTTLS? # Only affects port 25: enable TLS/STARTTLS?
@ -355,7 +368,7 @@ Email:
# Recovery password length # Recovery password length
RecoveryPasswordLength: 8 RecoveryPasswordLength: 8
# Mail Subject # Mail Subject
mailSubject: 'Your new AuthMe password' mailSubject: Your new AuthMe password
# Like maxRegPerIP but with email # Like maxRegPerIP but with email
maxRegPerEmail: 1 maxRegPerEmail: 1
# Recall players to add an email? # Recall players to add an email?
@ -364,7 +377,7 @@ Email:
delayRecall: 5 delayRecall: 5
# Blacklist these domains for emails # Blacklist these domains for emails
emailBlacklisted: emailBlacklisted:
- '10minutemail.com' - 10minutemail.com
# Whitelist ONLY these domains for emails # Whitelist ONLY these domains for emails
emailWhitelisted: [] emailWhitelisted: []
# Send the new password drawn in an image? # Send the new password drawn in an image?
@ -389,14 +402,16 @@ Protection:
enableProtectionRegistered: true enableProtectionRegistered: true
# Countries allowed to join the server and register. For country codes, see # Countries allowed to join the server and register. For country codes, see
# https://dev.maxmind.com/geoip/legacy/codes/iso3166/ # https://dev.maxmind.com/geoip/legacy/codes/iso3166/
# Use "LOCALHOST" for local addresses.
# PLEASE USE QUOTES! # PLEASE USE QUOTES!
countries: countries:
- 'US' - US
- 'GB' - GB
- LOCALHOST
# Countries not allowed to join the server and register # Countries not allowed to join the server and register
# PLEASE USE QUOTES! # PLEASE USE QUOTES!
countriesBlacklist: countriesBlacklist:
- 'A1' - A1
# Do we need to enable automatic antibot system? # Do we need to enable automatic antibot system?
enableAntiBot: true enableAntiBot: true
# The interval in seconds # The interval in seconds
@ -421,7 +436,7 @@ Purge:
# Do we need to remove the Essentials/userdata/player.yml file during purge process? # Do we need to remove the Essentials/userdata/player.yml file during purge process?
removeEssentialsFile: false removeEssentialsFile: false
# World in which the players.dat are stored # World in which the players.dat are stored
defaultWorld: 'world' defaultWorld: world
# Remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge? # Remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge?
removeLimitedCreativesInventories: false removeLimitedCreativesInventories: false
# Do we need to remove the AntiXRayData/PlayerData/player file during purge process? # Do we need to remove the AntiXRayData/PlayerData/player file during purge process?
@ -498,7 +513,7 @@ limbo:
# DISABLED: no disk storage, # DISABLED: no disk storage,
# INDIVIDUAL_FILES: each player data in its own file, # INDIVIDUAL_FILES: each player data in its own file,
# DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below # DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below
type: 'INDIVIDUAL_FILES' type: INDIVIDUAL_FILES
# This setting only affects DISTRIBUTED_FILES persistence. The distributed file # This setting only affects DISTRIBUTED_FILES persistence. The distributed file
# persistence attempts to reduce the number of files by distributing players into various # persistence attempts to reduce the number of files by distributing players into various
# buckets based on their UUID. This setting defines into how many files the players should # buckets based on their UUID. This setting defines into how many files the players should
@ -508,20 +523,20 @@ limbo:
# 6.25 players per file (100 / 16). # 6.25 players per file (100 / 16).
# Note: if you change this setting all data will be migrated. If you have a lot of data, # Note: if you change this setting all data will be migrated. If you have a lot of data,
# change this setting only on server restart, not with /authme reload. # change this setting only on server restart, not with /authme reload.
distributionSize: 'SIXTEEN' distributionSize: SIXTEEN
# Whether the player is allowed to fly: RESTORE, ENABLE, DISABLE, NOTHING. # Whether the player is allowed to fly: RESTORE, ENABLE, DISABLE, NOTHING.
# RESTORE sets back the old property from the player. NOTHING will prevent AuthMe # RESTORE sets back the old property from the player. NOTHING will prevent AuthMe
# from modifying the 'allow flight' property on the player. # from modifying the 'allow flight' property on the player.
restoreAllowFlight: 'RESTORE' restoreAllowFlight: RESTORE
# Restore fly speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO. # Restore fly speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.
# RESTORE: restore the speed the player had; # RESTORE: restore the speed the player had;
# DEFAULT: always set to default speed; # DEFAULT: always set to default speed;
# MAX_RESTORE: take the maximum of the player's current speed and the previous one # MAX_RESTORE: take the maximum of the player's current speed and the previous one
# RESTORE_NO_ZERO: Like 'restore' but sets speed to default if the player's speed was 0 # RESTORE_NO_ZERO: Like 'restore' but sets speed to default if the player's speed was 0
restoreFlySpeed: 'RESTORE_NO_ZERO' restoreFlySpeed: RESTORE_NO_ZERO
# Restore walk speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO. # Restore walk speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.
# See above for a description of the values. # See above for a description of the values.
restoreWalkSpeed: 'RESTORE_NO_ZERO' restoreWalkSpeed: RESTORE_NO_ZERO
BackupSystem: BackupSystem:
# General configuration for backups: if false, no backups are possible # General configuration for backups: if false, no backups are possible
ActivateBackup: false ActivateBackup: false
@ -530,19 +545,19 @@ BackupSystem:
# Create backup at every stop of server # Create backup at every stop of server
OnServerStop: true OnServerStop: true
# Windows only: MySQL installation path # Windows only: MySQL installation path
MysqlWindowsPath: 'C:\Program Files\MySQL\MySQL Server 5.1\' MysqlWindowsPath: C:\Program Files\MySQL\MySQL Server 5.1\
# Converter settings: see https://github.com/AuthMe/AuthMeReloaded/wiki/Converters # Converter settings: see https://github.com/AuthMe/AuthMeReloaded/wiki/Converters
Converter: Converter:
Rakamak: Rakamak:
# Rakamak file name # Rakamak file name
fileName: 'users.rak' fileName: users.rak
# Rakamak use IP? # Rakamak use IP?
useIP: false useIP: false
# Rakamak IP file name # Rakamak IP file name
ipFileName: 'UsersIp.rak' ipFileName: UsersIp.rak
CrazyLogin: CrazyLogin:
# CrazyLogin database file name # CrazyLogin database file name
fileName: 'accounts.db' fileName: accounts.db
loginSecurity: loginSecurity:
# LoginSecurity: convert from SQLite; if false we use MySQL # LoginSecurity: convert from SQLite; if false we use MySQL
useSqlite: true useSqlite: true
@ -555,6 +570,7 @@ Converter:
user: '' user: ''
# LoginSecurity MySQL: password for database user # LoginSecurity MySQL: password for database user
password: '' password: ''
``` ```
To change settings on a running server, save your changes to config.yml and use To change settings on a running server, save your changes to config.yml and use
@ -562,4 +578,4 @@ To change settings on a running server, save your changes to config.yml and use
--- ---
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Mon May 21 09:08:25 CEST 2018 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Tue Apr 23 17:17:02 CEST 2019

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Sun Sep 02 20:38:48 CEST 2018. See docs/hashmethods/hash_algorithms.tpl.md --> <!-- File auto-generated on Fri Apr 19 17:16:06 CEST 2019. See docs/hashmethods/hash_algorithms.tpl.md -->
## Hash Algorithms ## Hash Algorithms
AuthMe supports the following hash algorithms for storing your passwords safely. AuthMe supports the following hash algorithms for storing your passwords safely.
@ -80,4 +80,4 @@ or bad.
--- ---
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Sep 02 20:38:48 CEST 2018 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Apr 19 17:16:06 CEST 2019

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Mon May 21 08:43:08 CEST 2018. See docs/permissions/permission_nodes.tpl.md --> <!-- File auto-generated on Fri Aug 02 16:25:54 CEST 2019. See docs/permissions/permission_nodes.tpl.md -->
## AuthMe Permission Nodes ## AuthMe Permission Nodes
The following are the permission nodes that are currently supported by the latest dev builds. The following are the permission nodes that are currently supported by the latest dev builds.
@ -28,12 +28,14 @@ The following are the permission nodes that are currently supported by the lates
- **authme.admin.setspawn** Administrator command to set the AuthMe spawn. - **authme.admin.setspawn** Administrator command to set the AuthMe spawn.
- **authme.admin.spawn** Administrator command to teleport to the AuthMe spawn. - **authme.admin.spawn** Administrator command to teleport to the AuthMe spawn.
- **authme.admin.switchantibot** Administrator command to toggle the AntiBot protection status. - **authme.admin.switchantibot** Administrator command to toggle the AntiBot protection status.
- **authme.admin.totpdisable** Administrator command to disable the two-factor auth of a user.
- **authme.admin.totpviewstatus** Administrator command to see whether a player has enabled two-factor authentication.
- **authme.admin.unregister** Administrator command to unregister an existing user. - **authme.admin.unregister** Administrator command to unregister an existing user.
- **authme.admin.updatemessages** Permission to use the update messages command. - **authme.admin.updatemessages** Permission to use the update messages command.
- **authme.allowchatbeforelogin** Permission to send chat messages before being logged in. - **authme.allowchatbeforelogin** Permission to send chat messages before being logged in.
- **authme.allowmultipleaccounts** Permission to be able to register multiple accounts. - **authme.allowmultipleaccounts** Permission to be able to register multiple accounts.
- **authme.bypassbungeesend** Permission node to bypass BungeeCord server teleportation.
- **authme.bypassantibot** Permission node to bypass AntiBot protection. - **authme.bypassantibot** Permission node to bypass AntiBot protection.
- **authme.bypassbungeesend** Permission node to bypass BungeeCord server teleportation.
- **authme.bypasscountrycheck** Permission to bypass the GeoIp country code check. - **authme.bypasscountrycheck** Permission to bypass the GeoIp country code check.
- **authme.bypassforcesurvival** Permission for users to bypass force-survival mode. - **authme.bypassforcesurvival** Permission for users to bypass force-survival mode.
- **authme.bypasspurge** Permission to bypass the purging process. - **authme.bypasspurge** Permission to bypass the purging process.
@ -71,4 +73,4 @@ The following are the permission nodes that are currently supported by the lates
--- ---
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Mon May 21 08:43:08 CEST 2018 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Aug 02 16:25:54 CEST 2019

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Thu Aug 02 21:12:10 CEST 2018. See docs/translations/translations.tpl.md --> <!-- File auto-generated on Fri Apr 19 17:16:06 CEST 2019. See docs/translations/translations.tpl.md -->
# AuthMe Translations # AuthMe Translations
The following translations are available in AuthMe. Set `messagesLanguage` to the language code The following translations are available in AuthMe. Set `messagesLanguage` to the language code
@ -7,38 +7,39 @@ in your config.yml to use the language, or use another language code to start a
Code | Language | Translated | &nbsp; Code | Language | Translated | &nbsp;
---- | -------- | ---------: | ------ ---- | -------- | ---------: | ------
[en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=66ff66&w=100&h=5&txtpad=1" alt="bar" /> [en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 76% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=bb9900&w=76&h=5&txtpad=1" alt="bar" /> [bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 97% | <img src="https://via.placeholder.com/97x7/66ee55?text=%20" alt="97" />
[cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 80% | <img src="https://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 80% | <img src="https://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[eo](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eo.yml) | Esperanto | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [eo](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eo.yml) | Esperanto | 80% | <img src="https://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 100% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=66ff66&w=100&h=5&txtpad=1" alt="bar" /> [es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[et](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_et.yml) | Estonian | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [et](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_et.yml) | Estonian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 42% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aa5500&w=42&h=5&txtpad=1" alt="bar" /> [eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 42% | <img src="https://via.placeholder.com/42x7/aa5500?text=%20" alt="42" />
[fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 45% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aa5500&w=45&h=5&txtpad=1" alt="bar" /> [fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 45% | <img src="https://via.placeholder.com/45x7/aa5500?text=%20" alt="45" />
[fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 89% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=88cc33&w=89&h=5&txtpad=1" alt="bar" /> [fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 48% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aa5500&w=48&h=5&txtpad=1" alt="bar" /> [gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 48% | <img src="https://via.placeholder.com/48x7/aa5500?text=%20" alt="48" />
[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 87% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=99bb22&w=87&h=5&txtpad=1" alt="bar" /> [hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 47% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aa5500&w=47&h=5&txtpad=1" alt="bar" /> [id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 93% | <img src="https://via.placeholder.com/93x7/77dd44?text=%20" alt="93" />
[it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=66ff66&w=100&h=5&txtpad=1" alt="bar" /> [it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 89% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=88cc33&w=89&h=5&txtpad=1" alt="bar" /> [ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 36% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aa4400&w=36&h=5&txtpad=1" alt="bar" /> [lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 36% | <img src="https://via.placeholder.com/36x7/aa4400?text=%20" alt="36" />
[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 80% | <img src="https://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=66ff66&w=100&h=5&txtpad=1" alt="bar" /> [pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 100% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=66ff66&w=100&h=5&txtpad=1" alt="bar" /> [pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 80% | <img src="https://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 93% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=77dd44&w=93&h=5&txtpad=1" alt="bar" /> [ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 80% | <img src="https://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 100% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=66ff66&w=100&h=5&txtpad=1" alt="bar" /> [sr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sr.yml) | Serbian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 63% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=bb7700&w=63&h=5&txtpad=1" alt="bar" /> [tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 77% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=bb9900&w=77&h=5&txtpad=1" alt="bar" /> [uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 63% | <img src="https://via.placeholder.com/63x7/bb7700?text=%20" alt="63" />
[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 89% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=88cc33&w=89&h=5&txtpad=1" alt="bar" /> [vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 77% | <img src="https://via.placeholder.com/77x7/bb9900?text=%20" alt="77" />
[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 80% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=aaaa11&w=80&h=5&txtpad=1" alt="bar" /> [zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 98% | <img src="https://via.placeholder.com/98x7/66ee55?text=%20" alt="98" />
[zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 65% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=bb7700&w=65&h=5&txtpad=1" alt="bar" /> [zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 87% | <img src="https://placeholdit.imgix.net/~text?txtsize=5&bg=99bb22&w=87&h=5&txtpad=1" alt="bar" /> [zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 65% | <img src="https://via.placeholder.com/65x7/bb7700?text=%20" alt="65" />
[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 87% | <img src="https://via.placeholder.com/87x7/99bb22?text=%20" alt="87" />
--- ---
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Thu Aug 02 21:12:10 CEST 2018 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Apr 19 17:16:06 CEST 2019

290
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>fr.xephi</groupId> <groupId>fr.xephi</groupId>
<artifactId>authme</artifactId> <artifactId>authme</artifactId>
<version>5.5.1-SNAPSHOT</version> <version>5.6.0-SNAPSHOT</version>
<name>AuthMeReloaded</name> <name>AuthMeReloaded</name>
<description>The first authentication plugin for the Bukkit API!</description> <description>The first authentication plugin for the Bukkit API!</description>
@ -64,7 +64,7 @@
<maven.minimumVersion>3.3.9</maven.minimumVersion> <maven.minimumVersion>3.3.9</maven.minimumVersion>
<!-- Dependencies versions --> <!-- Dependencies versions -->
<spigot.version>1.13.2-R0.1-SNAPSHOT</spigot.version> <spigot.version>1.14.2-R0.1-SNAPSHOT</spigot.version>
<!-- Versioning properties --> <!-- Versioning properties -->
<project.outputName>AuthMe</project.outputName> <project.outputName>AuthMe</project.outputName>
@ -105,6 +105,21 @@
<project.skipExtendedHashTests>true</project.skipExtendedHashTests> <project.skipExtendedHashTests>true</project.skipExtendedHashTests>
</properties> </properties>
</profile> </profile>
<!-- Skip javadoc generation for faster local build -->
<profile>
<id>skipJavadocGeneration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles> </profiles>
<build> <build>
@ -131,6 +146,16 @@
</resource> </resource>
</resources> </resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins> <plugins>
<!-- Enforce build environment --> <!-- Enforce build environment -->
<plugin> <plugin>
@ -170,7 +195,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version> <version>3.8.1</version>
<configuration> <configuration>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
@ -180,7 +205,7 @@
<plugin> <plugin>
<groupId>org.jacoco</groupId> <groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</version> <version>0.8.4</version>
<executions> <executions>
<execution> <execution>
<id>pre-unit-test</id> <id>pre-unit-test</id>
@ -200,7 +225,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version> <version>2.22.2</version>
<configuration> <configuration>
<!-- Force the right file encoding during unit testing --> <!-- Force the right file encoding during unit testing -->
<!-- Set language to English in order to get consistent results for localized time formatting --> <!-- Set language to English in order to get consistent results for localized time formatting -->
@ -216,15 +241,16 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version> <version>3.1.2</version>
</plugin> </plugin>
<!-- Generate a jar containing the source javadoc --> <!-- Generate a jar containing the source javadoc -->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration> <configuration>
<finalName>${project.finalNameBase}</finalName> <finalName>${project.finalNameBase}</finalName>
<!-- In sync with the source/target properties of the maven-compiler-plugin -->
<source>8</source>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>
@ -239,7 +265,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId> <artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version> <version>3.1.0</version>
<configuration> <configuration>
<finalName>${project.finalNameBase}</finalName> <finalName>${project.finalNameBase}</finalName>
</configuration> </configuration>
@ -362,7 +388,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId> <artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version> <version>3.8.2</version>
</plugin> </plugin>
<!-- Publish coveralls test coverage reports, not included in the build cycle by default --> <!-- Publish coveralls test coverage reports, not included in the build cycle by default -->
<plugin> <plugin>
@ -382,36 +408,102 @@
<repository> <repository>
<id>spigotmc-repo</id> <id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
<!-- CodeMC Repo (Contains many required libraries) --> <!-- CodeMC Repo (Contains many required libraries) -->
<repository> <repository>
<id>codemc-repo</id> <id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url> <url>https://repo.codemc.org/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
<!-- EssentialsX Repo --> <!-- EssentialsX Repo -->
<repository> <repository>
<id>enderzone-repo</id> <id>enderzone-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything</url> <url>https://ci.ender.zone/plugin/repository/everything/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
<!-- ProtocolLib Repo --> <!-- ProtocolLib Repo -->
<repository> <repository>
<id>dmulloy2-repo</id> <id>dmulloy2-repo-releases</id>
<url>http://repo.dmulloy2.net/content/groups/public/</url> <url>http://repo.dmulloy2.net/nexus/repository/releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>dmulloy2-repo-snapshots</id>
<url>http://repo.dmulloy2.net/nexus/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
<!-- Multiverse Repo --> <!-- Multiverse Repo -->
<repository> <repository>
<id>onarandombox-repo</id> <id>onarandombox-repo-releases</id>
<url>http://repo.onarandombox.com/content/groups/public</url> <url>http://repo.onarandombox.com/content/repositories/multiverse/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>onarandombox-repo-snapshots</id>
<url>http://repo.onarandombox.com/content/repositories/multiverse-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
<!-- Vault Repo --> <!-- Vault Repo -->
<repository> <repository>
<id>vault-repo</id> <id>vault-repo-releases</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url> <url>http://nexus.hc.to/content/repositories/pub_releases</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>vault-repo-snapshots</id>
<url>http://nexus.hc.to/content/repositories/pub_snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
</repositories> </repositories>
@ -477,7 +569,7 @@
<dependency> <dependency>
<groupId>com.zaxxer</groupId> <groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId> <artifactId>HikariCP</artifactId>
<version>3.2.0</version> <version>3.3.1</version>
<optional>true</optional> <optional>true</optional>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -490,7 +582,7 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<version>1.7.25</version> <version>1.7.27</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
@ -498,7 +590,7 @@
<dependency> <dependency>
<groupId>de.rtner</groupId> <groupId>de.rtner</groupId>
<artifactId>PBKDF2</artifactId> <artifactId>PBKDF2</artifactId>
<version>1.1.2</version> <version>1.1.4</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
@ -560,7 +652,7 @@
<dependency> <dependency>
<groupId>ch.jalu</groupId> <groupId>ch.jalu</groupId>
<artifactId>configme</artifactId> <artifactId>configme</artifactId>
<version>1.0.1</version> <version>1.1.0</version>
<optional>true</optional> <optional>true</optional>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -600,7 +692,7 @@
<dependency> <dependency>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId> <artifactId>luckperms-api</artifactId>
<version>4.3</version> <version>4.4</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -611,93 +703,27 @@
<version>1.23.5-SNAPSHOT</version> <version>1.23.5-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>net.gravitydevelopment.updater</groupId>
<artifactId>updater</artifactId>
</exclusion>
<exclusion> <exclusion>
<artifactId>commons-dbcp</artifactId> <artifactId>commons-dbcp</artifactId>
<groupId>commons-dbcp</groupId> <groupId>commons-dbcp</groupId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<artifactId>AccountsClient</artifactId> <artifactId>accounts-client</artifactId>
<groupId>com.mojang</groupId> <groupId>com.mojang</groupId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!-- bPermissions plugin -->
<dependency>
<groupId>de.bananaco</groupId>
<artifactId>bPermissions</artifactId>
<version>2.12-DEV</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- zPermissions plugin --> <!-- zPermissions plugin -->
<dependency> <dependency>
<groupId>org.tyrannyofheaven.bukkit</groupId> <groupId>org.tyrannyofheaven.bukkit</groupId>
<artifactId>zPermissions</artifactId> <artifactId>zPermissions</artifactId>
<version>1.4-SNAPSHOT</version> <version>1.4.3-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
</exclusion>
<exclusion>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
</exclusion>
<exclusion>
<artifactId>VaultAPI</artifactId>
<groupId>net.milkbowl.vault</groupId>
</exclusion>
<exclusion>
<artifactId>uuidprovider</artifactId>
<groupId>net.kaikk.mc</groupId>
</exclusion>
<exclusion>
<artifactId>ToHPluginUtils</artifactId>
<groupId>org.tyrannyofheaven.bukkit</groupId>
</exclusion>
<exclusion>
<artifactId>Residence</artifactId>
<groupId>com.bekvon.bukkit</groupId>
</exclusion>
<exclusion>
<artifactId>Factions</artifactId>
<groupId>com.massivecraft</groupId>
</exclusion>
<exclusion>
<artifactId>mcore</artifactId>
<groupId>com.massivecraft</groupId>
</exclusion>
<exclusion>
<artifactId>Factoid</artifactId>
<groupId>me.tabinol.factoid</groupId>
</exclusion>
<exclusion>
<artifactId>ebean</artifactId>
<groupId>org.avaje</groupId> <groupId>org.avaje</groupId>
</exclusion> <artifactId>ebean</artifactId>
<exclusion>
<artifactId>persistence-api</artifactId>
<groupId>javax.persistence</groupId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
@ -724,7 +750,7 @@
<dependency> <dependency>
<groupId>com.onarandombox.multiversecore</groupId> <groupId>com.onarandombox.multiversecore</groupId>
<artifactId>Multiverse-Core</artifactId> <artifactId>Multiverse-Core</artifactId>
<version>2.6.0</version> <version>4.0.1</version>
<type>jar</type> <type>jar</type>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
@ -787,15 +813,49 @@
<dependency> <dependency>
<groupId>net.ess3</groupId> <groupId>net.ess3</groupId>
<artifactId>EssentialsX</artifactId> <artifactId>EssentialsX</artifactId>
<version>2.15.0</version> <version>2.16.1</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions>
<exclusion>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>NMSProvider</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>UpdatedMetaProvider</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>1_8_R1Provider</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>1_8_R2Provider</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>LegacyProvider</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>ReflectionProvider</artifactId>
</exclusion>
<exclusion>
<groupId>net.ess3</groupId>
<artifactId>FlattenedProvider</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- BCrypt implementation --> <!-- BCrypt implementation -->
<dependency> <dependency>
<groupId>at.favre.lib</groupId> <groupId>at.favre.lib</groupId>
<artifactId>bcrypt</artifactId> <artifactId>bcrypt</artifactId>
<version>0.6.0</version> <version>0.8.0</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
@ -803,42 +863,8 @@
<dependency> <dependency>
<groupId>de.luricos.bukkit</groupId> <groupId>de.luricos.bukkit</groupId>
<artifactId>xAuth</artifactId> <artifactId>xAuth</artifactId>
<version>2.6</version> <version>2.6.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
</exclusion>
<exclusion>
<artifactId>updater</artifactId>
<groupId>net.gravitydevelopment.updater</groupId>
</exclusion>
<exclusion>
<artifactId>lombok</artifactId>
<groupId>org.projectlombok</groupId>
</exclusion>
<exclusion>
<artifactId>EssentialsGroupManager</artifactId>
<groupId>net.ess3</groupId>
</exclusion>
<exclusion>
<artifactId>PermissionsEx</artifactId>
<groupId>ru.tehkode</groupId>
</exclusion>
<exclusion>
<artifactId>AccountsClient</artifactId>
<groupId>com.mojang</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-core</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
@ -851,7 +877,7 @@
<dependency> <dependency>
<groupId>org.postgresql</groupId> <groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId> <artifactId>postgresql</artifactId>
<version>42.2.5</version> <version>42.2.6</version>
</dependency> </dependency>
<!-- Unit Testing Libraries --> <!-- Unit Testing Libraries -->
@ -874,7 +900,7 @@
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<scope>test</scope> <scope>test</scope>
<version>2.23.4</version> <version>3.0.0</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<artifactId>hamcrest-core</artifactId> <artifactId>hamcrest-core</artifactId>
@ -887,7 +913,7 @@
<dependency> <dependency>
<groupId>org.checkerframework</groupId> <groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId> <artifactId>checker-qual</artifactId>
<version>2.5.8</version> <version>2.10.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@ -895,13 +921,13 @@
<dependency> <dependency>
<groupId>org.xerial</groupId> <groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId> <artifactId>sqlite-jdbc</artifactId>
<version>3.25.2</version> <version>3.28.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<version>1.4.197</version> <version>1.4.199</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>

View File

@ -6,8 +6,20 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.api.v3.AuthMeApi; import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.command.CommandHandler; import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.*; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.listener.*; import fr.xephi.authme.initialization.DataSourceProvider;
import fr.xephi.authme.initialization.OnShutdownPlayerSaver;
import fr.xephi.authme.initialization.OnStartupTasks;
import fr.xephi.authme.initialization.SettingsProvider;
import fr.xephi.authme.initialization.TaskCloser;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.listener.EntityListener;
import fr.xephi.authme.listener.PlayerListener;
import fr.xephi.authme.listener.PlayerListener111;
import fr.xephi.authme.listener.PlayerListener19;
import fr.xephi.authme.listener.PlayerListener19Spigot;
import fr.xephi.authme.listener.ServerListener;
import fr.xephi.authme.security.crypts.Sha256; import fr.xephi.authme.security.crypts.Sha256;
import fr.xephi.authme.service.BackupService; import fr.xephi.authme.service.BackupService;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -45,7 +57,7 @@ public class AuthMe extends JavaPlugin {
private static final String LOG_FILENAME = "authme.log"; private static final String LOG_FILENAME = "authme.log";
private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE; private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE;
// Default version and build number values // Version and build number values
private static String pluginVersion = "N/D"; private static String pluginVersion = "N/D";
private static String pluginBuildNumber = "Unknown"; private static String pluginBuildNumber = "Unknown";
@ -56,6 +68,7 @@ public class AuthMe extends JavaPlugin {
private BukkitService bukkitService; private BukkitService bukkitService;
private Injector injector; private Injector injector;
private BackupService backupService; private BackupService backupService;
private ConsoleLogger logger;
/** /**
* Constructor. * Constructor.
@ -67,8 +80,7 @@ public class AuthMe extends JavaPlugin {
* Constructor for unit testing. * Constructor for unit testing.
*/ */
@VisibleForTesting @VisibleForTesting
@SuppressWarnings("deprecation") // the super constructor is deprecated to mark it for unit testing only AuthMe(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
protected AuthMe(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file); super(loader, description, dataFolder, file);
} }
@ -109,14 +121,14 @@ public class AuthMe extends JavaPlugin {
// Check server version // Check server version
if (!isClassLoaded("org.bukkit.event.player.PlayerInteractAtEntityEvent")) { if (!isClassLoaded("org.bukkit.event.player.PlayerInteractAtEntityEvent")) {
ConsoleLogger.warning("You are running an unsupported server version! AuthMe requires MC 1.8.X or later!"); getLogger().warning("You are running an unsupported server version! AuthMe requires MC 1.8.X or later!");
stopOrUnload(); stopOrUnload();
return; return;
} }
// Prevent running AuthMeBridge due to major exploit issues // Prevent running AuthMeBridge due to major exploit issues
if (getServer().getPluginManager().isPluginEnabled("AuthMeBridge")) { if (getServer().getPluginManager().isPluginEnabled("AuthMeBridge")) {
ConsoleLogger.warning("Detected AuthMeBridge, support for it has been dropped as it was " getLogger().warning("Detected AuthMeBridge, support for it has been dropped as it was "
+ "causing exploit issues, please use AuthMeBungee instead! Aborting!"); + "causing exploit issues, please use AuthMeBungee instead! Aborting!");
stopOrUnload(); stopOrUnload();
return; return;
@ -128,9 +140,10 @@ public class AuthMe extends JavaPlugin {
} catch (Throwable th) { } catch (Throwable th) {
YamlParseException yamlParseException = ExceptionUtils.findThrowableInCause(YamlParseException.class, th); YamlParseException yamlParseException = ExceptionUtils.findThrowableInCause(YamlParseException.class, th);
if (yamlParseException == null) { if (yamlParseException == null) {
ConsoleLogger.logException("Aborting initialization of AuthMe:", th); logger.logException("Aborting initialization of AuthMe:", th);
th.printStackTrace();
} else { } else {
ConsoleLogger.logException("File '" + yamlParseException.getFile() + "' contains invalid YAML. " logger.logException("File '" + yamlParseException.getFile() + "' contains invalid YAML. "
+ "Please run its contents through http://yamllint.com", yamlParseException); + "Please run its contents through http://yamllint.com", yamlParseException);
} }
stopOrUnload(); stopOrUnload();
@ -146,14 +159,8 @@ public class AuthMe extends JavaPlugin {
// Set up Metrics // Set up Metrics
OnStartupTasks.sendMetrics(this, settings); OnStartupTasks.sendMetrics(this, settings);
// Sponsor messages
ConsoleLogger.info("Development builds are available on our jenkins, thanks to FastVM.io");
ConsoleLogger.info("Do you want a good vps for your game server? Look at our sponsor FastVM.io leader "
+ "as virtual server provider!");
// Successful message // Successful message
ConsoleLogger.info("AuthMe " + getPluginVersion() + " build n." + getPluginBuildNumber() logger.info("AuthMe " + getPluginVersion() + " build n." + getPluginBuildNumber() + " successfully enabled!");
+ " correctly enabled!");
// Purge on start if enabled // Purge on start if enabled
PurgeService purgeService = injector.getSingleton(PurgeService.class); PurgeService purgeService = injector.getSingleton(PurgeService.class);
@ -185,8 +192,7 @@ public class AuthMe extends JavaPlugin {
*/ */
private void initialize() { private void initialize() {
// Set the Logger instance and log file path // Set the Logger instance and log file path
ConsoleLogger.setLogger(getLogger()); ConsoleLogger.initialize(getLogger(), new File(getDataFolder(), LOG_FILENAME));
ConsoleLogger.setLogFile(new File(getDataFolder(), LOG_FILENAME));
// Check java version // Check java version
if (!SystemUtils.isJavaVersionAtLeast(1.8f)) { if (!SystemUtils.isJavaVersionAtLeast(1.8f)) {
@ -210,7 +216,8 @@ public class AuthMe extends JavaPlugin {
// Get settings and set up logger // Get settings and set up logger
settings = injector.getSingleton(Settings.class); settings = injector.getSingleton(Settings.class);
ConsoleLogger.setLoggingOptions(settings); ConsoleLoggerFactory.reloadSettings(settings);
logger = ConsoleLoggerFactory.get(AuthMe.class);
OnStartupTasks onStartupTasks = injector.newInstance(OnStartupTasks.class); OnStartupTasks onStartupTasks = injector.newInstance(OnStartupTasks.class);
onStartupTasks.setupConsoleFilter(settings, getLogger()); onStartupTasks.setupConsoleFilter(settings, getLogger());
@ -287,7 +294,7 @@ public class AuthMe extends JavaPlugin {
*/ */
public void stopOrUnload() { public void stopOrUnload() {
if (settings == null || settings.getProperty(SecuritySettings.STOP_SERVER_ON_PROBLEM)) { if (settings == null || settings.getProperty(SecuritySettings.STOP_SERVER_ON_PROBLEM)) {
ConsoleLogger.warning("THE SERVER IS GOING TO SHUT DOWN AS DEFINED IN THE CONFIGURATION!"); getLogger().warning("THE SERVER IS GOING TO SHUT DOWN AS DEFINED IN THE CONFIGURATION!");
setEnabled(false); setEnabled(false);
getServer().shutdown(); getServer().shutdown();
} else { } else {
@ -314,8 +321,8 @@ public class AuthMe extends JavaPlugin {
new TaskCloser(this, database).run(); new TaskCloser(this, database).run();
// Disabled correctly // Disabled correctly
ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!"); logger.info("AuthMe " + this.getDescription().getVersion() + " disabled!");
ConsoleLogger.close(); ConsoleLogger.closeFileWriter();
} }
/** /**

View File

@ -1,15 +1,19 @@
package fr.xephi.authme; package fr.xephi.authme;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.ExceptionUtils; import fr.xephi.authme.util.ExceptionUtils;
import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
@ -20,64 +24,73 @@ import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* The plugin's static logger. * AuthMe logger.
*/ */
public final class ConsoleLogger { public final class ConsoleLogger {
private static final String NEW_LINE = System.getProperty("line.separator"); private static final String NEW_LINE = System.getProperty("line.separator");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("[MM-dd HH:mm:ss]"); private static final DateFormat DATE_FORMAT = new SimpleDateFormat("[MM-dd HH:mm:ss]");
private static Logger logger;
private static LogLevel logLevel = LogLevel.INFO;
private static boolean useLogging = false;
private static File logFile;
private static FileWriter fileWriter;
private ConsoleLogger() { // Outside references
private static File logFile;
private static Logger logger;
// Shared state
private static OutputStreamWriter fileWriter;
// Individual state
private final String name;
private LogLevel logLevel = LogLevel.INFO;
/**
* Constructor.
*
* @param name the name of this logger (the fully qualified class name using it)
*/
public ConsoleLogger(String name) {
this.name = name;
} }
// -------- // --------
// Configurations // Configurations
// -------- // --------
/** public static void initialize(Logger logger, File logFile) {
* Set the logger to use.
*
* @param logger The logger
*/
public static void setLogger(Logger logger) {
ConsoleLogger.logger = logger; ConsoleLogger.logger = logger;
}
/**
* Set the file to log to if enabled.
*
* @param logFile The log file
*/
public static void setLogFile(File logFile) {
ConsoleLogger.logFile = logFile; ConsoleLogger.logFile = logFile;
} }
/** /**
* Load the required settings. * Sets logging settings which are shared by all logger instances.
* *
* @param settings The settings instance * @param settings the settings to read from
*/ */
public static void setLoggingOptions(Settings settings) { public static void initializeSharedSettings(Settings settings) {
ConsoleLogger.logLevel = settings.getProperty(PluginSettings.LOG_LEVEL); boolean useLogging = settings.getProperty(SecuritySettings.USE_LOGGING);
ConsoleLogger.useLogging = settings.getProperty(SecuritySettings.USE_LOGGING);
if (useLogging) { if (useLogging) {
if (fileWriter == null) { initializeFileWriter();
try {
fileWriter = new FileWriter(logFile, true);
} catch (IOException e) {
ConsoleLogger.logException("Failed to create the log file:", e);
}
}
} else { } else {
close(); closeFileWriter();
} }
} }
/**
* Sets logging settings which are individual to all loggers.
*
* @param settings the settings to read from
*/
public void initializeSettings(Settings settings) {
this.logLevel = settings.getProperty(PluginSettings.LOG_LEVEL);
}
public LogLevel getLogLevel() {
return logLevel;
}
public String getName() {
return name;
}
// -------- // --------
// Logging methods // Logging methods
@ -88,7 +101,7 @@ public final class ConsoleLogger {
* *
* @param message The message to log * @param message The message to log
*/ */
public static void warning(String message) { public void warning(String message) {
logger.warning(message); logger.warning(message);
writeLog("[WARN] " + message); writeLog("[WARN] " + message);
} }
@ -100,7 +113,7 @@ public final class ConsoleLogger {
* @param message The message to accompany the exception * @param message The message to accompany the exception
* @param th The Throwable to log * @param th The Throwable to log
*/ */
public static void logException(String message, Throwable th) { public void logException(String message, Throwable th) {
warning(message + " " + ExceptionUtils.formatException(th)); warning(message + " " + ExceptionUtils.formatException(th));
writeLog(Throwables.getStackTraceAsString(th)); writeLog(Throwables.getStackTraceAsString(th));
} }
@ -110,7 +123,7 @@ public final class ConsoleLogger {
* *
* @param message The message to log * @param message The message to log
*/ */
public static void info(String message) { public void info(String message) {
logger.info(message); logger.info(message);
writeLog("[INFO] " + message); writeLog("[INFO] " + message);
} }
@ -123,7 +136,7 @@ public final class ConsoleLogger {
* *
* @param message The message to log * @param message The message to log
*/ */
public static void fine(String message) { public void fine(String message) {
if (logLevel.includes(LogLevel.FINE)) { if (logLevel.includes(LogLevel.FINE)) {
logger.info(message); logger.info(message);
writeLog("[FINE] " + message); writeLog("[FINE] " + message);
@ -142,7 +155,7 @@ public final class ConsoleLogger {
* *
* @param message The message to log * @param message The message to log
*/ */
public static void debug(String message) { public void debug(String message) {
if (logLevel.includes(LogLevel.DEBUG)) { if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + message; String debugMessage = "[DEBUG] " + message;
logger.info(debugMessage); logger.info(debugMessage);
@ -155,7 +168,7 @@ public final class ConsoleLogger {
* *
* @param msgSupplier the message supplier * @param msgSupplier the message supplier
*/ */
public static void debug(Supplier<String> msgSupplier) { public void debug(Supplier<String> msgSupplier) {
if (logLevel.includes(LogLevel.DEBUG)) { if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + msgSupplier.get(); String debugMessage = "[DEBUG] " + msgSupplier.get();
logger.info(debugMessage); logger.info(debugMessage);
@ -169,7 +182,7 @@ public final class ConsoleLogger {
* @param message the message * @param message the message
* @param param1 parameter to replace in the message * @param param1 parameter to replace in the message
*/ */
public static void debug(String message, Object param1) { public void debug(String message, Object param1) {
if (logLevel.includes(LogLevel.DEBUG)) { if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + message; String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, param1); logger.log(Level.INFO, debugMessage, param1);
@ -185,7 +198,7 @@ public final class ConsoleLogger {
* @param param2 second param to replace in message * @param param2 second param to replace in message
*/ */
// Avoids array creation if DEBUG level is disabled // Avoids array creation if DEBUG level is disabled
public static void debug(String message, Object param1, Object param2) { public void debug(String message, Object param1, Object param2) {
if (logLevel.includes(LogLevel.DEBUG)) { if (logLevel.includes(LogLevel.DEBUG)) {
debug(message, new Object[]{param1, param2}); debug(message, new Object[]{param1, param2});
} }
@ -197,7 +210,7 @@ public final class ConsoleLogger {
* @param message the message * @param message the message
* @param params the params to replace in the message * @param params the params to replace in the message
*/ */
public static void debug(String message, Object... params) { public void debug(String message, Object... params) {
if (logLevel.includes(LogLevel.DEBUG)) { if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + message; String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, params); logger.log(Level.INFO, debugMessage, params);
@ -206,21 +219,21 @@ public final class ConsoleLogger {
} }
} }
// -------- // --------
// Helpers // Helpers
// -------- // --------
/** /**
* Close all file handles. * Closes the file writer.
*/ */
public static void close() { public static void closeFileWriter() {
if (fileWriter != null) { if (fileWriter != null) {
try { try {
fileWriter.flush(); fileWriter.flush();
fileWriter.close();
fileWriter = null;
} catch (IOException ignored) { } catch (IOException ignored) {
} finally {
closeSilently(fileWriter);
fileWriter = null;
} }
} }
} }
@ -231,7 +244,7 @@ public final class ConsoleLogger {
* @param message The message to write to the log * @param message The message to write to the log
*/ */
private static void writeLog(String message) { private static void writeLog(String message) {
if (useLogging) { if (fileWriter != null) {
String dateTime; String dateTime;
synchronized (DATE_FORMAT) { synchronized (DATE_FORMAT) {
dateTime = DATE_FORMAT.format(new Date()); dateTime = DATE_FORMAT.format(new Date());
@ -246,4 +259,31 @@ public final class ConsoleLogger {
} }
} }
} }
private static void closeSilently(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignored) {
}
}
}
/**
* Populates the {@link #fileWriter} field if it is null, handling any exceptions that might
* arise during its creation.
*/
private static void initializeFileWriter() {
if (fileWriter == null) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(logFile, true);
fileWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
} catch (Exception e) {
closeSilently(fos);
ConsoleLoggerFactory.get(ConsoleLogger.class)
.logException("Failed to create the log file:", e);
}
}
}
} }

View File

@ -24,6 +24,8 @@ import fr.xephi.authme.command.executable.authme.SetFirstSpawnCommand;
import fr.xephi.authme.command.executable.authme.SetSpawnCommand; import fr.xephi.authme.command.executable.authme.SetSpawnCommand;
import fr.xephi.authme.command.executable.authme.SpawnCommand; import fr.xephi.authme.command.executable.authme.SpawnCommand;
import fr.xephi.authme.command.executable.authme.SwitchAntiBotCommand; import fr.xephi.authme.command.executable.authme.SwitchAntiBotCommand;
import fr.xephi.authme.command.executable.authme.TotpDisableAdminCommand;
import fr.xephi.authme.command.executable.authme.TotpViewStatusCommand;
import fr.xephi.authme.command.executable.authme.UnregisterAdminCommand; import fr.xephi.authme.command.executable.authme.UnregisterAdminCommand;
import fr.xephi.authme.command.executable.authme.UpdateHelpMessagesCommand; import fr.xephi.authme.command.executable.authme.UpdateHelpMessagesCommand;
import fr.xephi.authme.command.executable.authme.VersionCommand; import fr.xephi.authme.command.executable.authme.VersionCommand;
@ -295,6 +297,28 @@ public class CommandInitializer {
.executableCommand(GetIpCommand.class) .executableCommand(GetIpCommand.class)
.register(); .register();
// Register totp command
CommandDescription.builder()
.parent(authmeBase)
.labels("totp", "2fa")
.description("See if a player has enabled TOTP")
.detailedDescription("Returns whether the specified player has enabled two-factor authentication.")
.withArgument("player", "Player name", MANDATORY)
.permission(AdminPermission.VIEW_TOTP_STATUS)
.executableCommand(TotpViewStatusCommand.class)
.register();
// Register disable totp command
CommandDescription.builder()
.parent(authmeBase)
.labels("disabletotp", "disable2fa", "deletetotp", "delete2fa")
.description("Delete TOTP token of a player")
.detailedDescription("Disable two-factor authentication for a player.")
.withArgument("player", "Player name", MANDATORY)
.permission(AdminPermission.DISABLE_TOTP)
.executableCommand(TotpDisableAdminCommand.class)
.register();
// Register the spawn command // Register the spawn command
CommandDescription.builder() CommandDescription.builder()
.parent(authmeBase) .parent(authmeBase)

View File

@ -14,6 +14,7 @@ import fr.xephi.authme.datasource.converter.RoyalAuthConverter;
import fr.xephi.authme.datasource.converter.SqliteToSql; import fr.xephi.authme.datasource.converter.SqliteToSql;
import fr.xephi.authme.datasource.converter.VAuthConverter; import fr.xephi.authme.datasource.converter.VAuthConverter;
import fr.xephi.authme.datasource.converter.XAuthConverter; import fr.xephi.authme.datasource.converter.XAuthConverter;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
@ -31,6 +32,8 @@ public class ConverterCommand implements ExecutableCommand {
@VisibleForTesting @VisibleForTesting
static final Map<String, Class<? extends Converter>> CONVERTERS = getConverters(); static final Map<String, Class<? extends Converter>> CONVERTERS = getConverters();
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ConverterCommand.class);
@Inject @Inject
private CommonService commonService; private CommonService commonService;
@ -59,7 +62,7 @@ public class ConverterCommand implements ExecutableCommand {
converter.execute(sender); converter.execute(sender);
} catch (Exception e) { } catch (Exception e) {
commonService.send(sender, MessageKey.ERROR); commonService.send(sender, MessageKey.ERROR);
ConsoleLogger.logException("Error during conversion:", e); logger.logException("Error during conversion:", e);
} }
} }
}); });

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
@ -22,6 +23,8 @@ import java.util.List;
*/ */
public class RegisterAdminCommand implements ExecutableCommand { public class RegisterAdminCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RegisterAdminCommand.class);
@Inject @Inject
private PasswordSecurity passwordSecurity; private PasswordSecurity passwordSecurity;
@ -70,7 +73,7 @@ public class RegisterAdminCommand implements ExecutableCommand {
} }
commonService.send(sender, MessageKey.REGISTER_SUCCESS); commonService.send(sender, MessageKey.REGISTER_SUCCESS);
ConsoleLogger.info(sender.getName() + " registered " + playerName); logger.info(sender.getName() + " registered " + playerName);
final Player player = bukkitService.getPlayerExact(playerName); final Player player = bukkitService.getPlayerExact(playerName);
if (player != null) { if (player != null) {
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() ->

View File

@ -7,6 +7,7 @@ import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
@ -23,6 +24,8 @@ import java.util.List;
*/ */
public class ReloadCommand implements ExecutableCommand { public class ReloadCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ReloadCommand.class);
@Inject @Inject
private AuthMe plugin; private AuthMe plugin;
@ -48,7 +51,7 @@ public class ReloadCommand implements ExecutableCommand {
public void executeCommand(CommandSender sender, List<String> arguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
try { try {
settings.reload(); settings.reload();
ConsoleLogger.setLoggingOptions(settings); ConsoleLoggerFactory.reloadSettings(settings);
settingsWarner.logWarningsForMisconfigurations(); settingsWarner.logWarningsForMisconfigurations();
// We do not change database type for consistency issues, but we'll output a note in the logs // We do not change database type for consistency issues, but we'll output a note in the logs
@ -59,7 +62,7 @@ public class ReloadCommand implements ExecutableCommand {
commonService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS); commonService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
} catch (Exception e) { } catch (Exception e) {
sender.sendMessage("Error occurred during reload of AuthMe: aborting"); sender.sendMessage("Error occurred during reload of AuthMe: aborting");
ConsoleLogger.logException("Aborting! Encountered exception during reload of AuthMe:", e); logger.logException("Aborting! Encountered exception during reload of AuthMe:", e);
plugin.stopOrUnload(); plugin.stopOrUnload();
} }
} }

View File

@ -0,0 +1,61 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.List;
/**
* Command to disable two-factor authentication for a user.
*/
public class TotpDisableAdminCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TotpDisableAdminCommand.class);
@Inject
private DataSource dataSource;
@Inject
private Messages messages;
@Inject
private BukkitService bukkitService;
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
String player = arguments.get(0);
PlayerAuth auth = dataSource.getAuth(player);
if (auth == null) {
messages.send(sender, MessageKey.UNKNOWN_USER);
} else if (auth.getTotpKey() == null) {
sender.sendMessage(ChatColor.RED + "Player '" + player + "' does not have two-factor auth enabled");
} else {
removeTotpKey(sender, player);
}
}
private void removeTotpKey(CommandSender sender, String player) {
if (dataSource.removeTotpKey(player)) {
sender.sendMessage("Disabled two-factor authentication successfully for '" + player + "'");
logger.info(sender.getName() + " disable two-factor authentication for '" + player + "'");
Player onlinePlayer = bukkitService.getPlayerExact(player);
if (onlinePlayer != null) {
messages.send(onlinePlayer, MessageKey.TWO_FACTOR_REMOVED_SUCCESS);
}
} else {
messages.send(sender, MessageKey.ERROR);
}
}
}

View File

@ -0,0 +1,38 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
* Command to see whether a user has enabled two-factor authentication.
*/
public class TotpViewStatusCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Inject
private Messages messages;
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
String player = arguments.get(0);
PlayerAuth auth = dataSource.getAuth(player);
if (auth == null) {
messages.send(sender, MessageKey.UNKNOWN_USER);
} else if (auth.getTotpKey() == null) {
sender.sendMessage(ChatColor.RED + "Player '" + player + "' does NOT have two-factor auth enabled");
} else {
sender.sendMessage(ChatColor.DARK_GREEN + "Player '" + player + "' has enabled two-factor authentication");
}
}
}

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.help.HelpMessagesService; import fr.xephi.authme.command.help.HelpMessagesService;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.HelpTranslationGenerator; import fr.xephi.authme.service.HelpTranslationGenerator;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -17,6 +18,8 @@ import java.util.List;
*/ */
public class UpdateHelpMessagesCommand implements ExecutableCommand { public class UpdateHelpMessagesCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(UpdateHelpMessagesCommand.class);
@Inject @Inject
private HelpTranslationGenerator helpTranslationGenerator; private HelpTranslationGenerator helpTranslationGenerator;
@Inject @Inject
@ -30,7 +33,7 @@ public class UpdateHelpMessagesCommand implements ExecutableCommand {
helpMessagesService.reloadMessagesFile(); helpMessagesService.reloadMessagesFile();
} catch (IOException e) { } catch (IOException e) {
sender.sendMessage("Could not update help file: " + e.getMessage()); sender.sendMessage("Could not update help file: " + e.getMessage());
ConsoleLogger.logException("Could not update help file:", e); logger.logException("Could not update help file:", e);
} }
} }
} }

View File

@ -23,7 +23,7 @@ public class VersionCommand implements ExecutableCommand {
sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName() sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName()
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")"); + " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
sender.sendMessage(ChatColor.GOLD + "Developers:"); sender.sendMessage(ChatColor.GOLD + "Developers:");
Collection<? extends Player> onlinePlayers = bukkitService.getOnlinePlayers(); Collection<Player> onlinePlayers = bukkitService.getOnlinePlayers();
printDeveloper(sender, "Alexandre Vanhecke", "xephi59", "Original Author", onlinePlayers); printDeveloper(sender, "Alexandre Vanhecke", "xephi59", "Original Author", onlinePlayers);
printDeveloper(sender, "Lucas J.", "ljacqu", "Main Developer", onlinePlayers); printDeveloper(sender, "Lucas J.", "ljacqu", "Main Developer", onlinePlayers);
printDeveloper(sender, "Gnat008", "gnat008", "Developer", onlinePlayers); printDeveloper(sender, "Gnat008", "gnat008", "Developer", onlinePlayers);
@ -36,7 +36,7 @@ public class VersionCommand implements ExecutableCommand {
sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0" sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0"
+ ChatColor.GRAY + ChatColor.ITALIC + " (See LICENSE file)"); + ChatColor.GRAY + ChatColor.ITALIC + " (See LICENSE file)");
sender.sendMessage(ChatColor.GOLD + "Copyright: " + ChatColor.WHITE sender.sendMessage(ChatColor.GOLD + "Copyright: " + ChatColor.WHITE
+ "Copyright (c) AuthMe-Team 2017. All rights reserved."); + "Copyright (c) AuthMe-Team 2019. Released under GPL v3 License.");
} }
/** /**
@ -49,7 +49,7 @@ public class VersionCommand implements ExecutableCommand {
* @param onlinePlayers The list of online players * @param onlinePlayers The list of online players
*/ */
private static void printDeveloper(CommandSender sender, String name, String minecraftName, String function, private static void printDeveloper(CommandSender sender, String name, String minecraftName, String function,
Collection<? extends Player> onlinePlayers) { Collection<Player> onlinePlayers) {
// Print the name // Print the name
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
msg.append(" ") msg.append(" ")
@ -77,7 +77,7 @@ public class VersionCommand implements ExecutableCommand {
* *
* @return True if the player is online, false otherwise * @return True if the player is online, false otherwise
*/ */
private static boolean isPlayerOnline(String minecraftName, Collection<? extends Player> onlinePlayers) { private static boolean isPlayerOnline(String minecraftName, Collection<Player> onlinePlayers) {
for (Player player : onlinePlayers) { for (Player player : onlinePlayers) {
if (player.getName().equalsIgnoreCase(minecraftName)) { if (player.getName().equalsIgnoreCase(minecraftName)) {
return true; return true;

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService; import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.CacheDataSource; import fr.xephi.authme.datasource.CacheDataSource;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.Location; import org.bukkit.Location;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -19,6 +20,7 @@ import java.util.function.Function;
*/ */
final class DebugSectionUtils { final class DebugSectionUtils {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(DebugSectionUtils.class);
private static Field limboEntriesField; private static Field limboEntriesField;
private DebugSectionUtils() { private DebugSectionUtils() {
@ -72,7 +74,7 @@ final class DebugSectionUtils {
field.setAccessible(true); field.setAccessible(true);
limboEntriesField = field; limboEntriesField = field;
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not retrieve LimboService entries field:", e); logger.logException("Could not retrieve LimboService entries field:", e);
} }
} }
return limboEntriesField; return limboEntriesField;
@ -95,7 +97,7 @@ final class DebugSectionUtils {
try { try {
return function.apply((Map) limboEntriesField.get(limboService)); return function.apply((Map) limboEntriesField.get(limboService));
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not retrieve LimboService values:", e); logger.logException("Could not retrieve LimboService values:", e);
} }
} }
return null; return null;
@ -119,7 +121,7 @@ final class DebugSectionUtils {
source.setAccessible(true); source.setAccessible(true);
return (DataSource) source.get(dataSource); return (DataSource) source.get(dataSource);
} catch (NoSuchFieldException | IllegalAccessException e) { } catch (NoSuchFieldException | IllegalAccessException e) {
ConsoleLogger.logException("Could not get source of CacheDataSource:", e); logger.logException("Could not get source of CacheDataSource:", e);
return null; return null;
} }
} }

View File

@ -5,6 +5,7 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.MySQL; import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.DebugSectionPermissions; import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
@ -43,6 +44,8 @@ class MySqlDefaultChanger implements DebugSection {
private static final String NOT_NULL_SUFFIX = ChatColor.DARK_AQUA + "@" + ChatColor.RESET; private static final String NOT_NULL_SUFFIX = ChatColor.DARK_AQUA + "@" + ChatColor.RESET;
private static final String DEFAULT_VALUE_SUFFIX = ChatColor.GOLD + "#" + ChatColor.RESET; private static final String DEFAULT_VALUE_SUFFIX = ChatColor.GOLD + "#" + ChatColor.RESET;
private ConsoleLogger logger = ConsoleLoggerFactory.get(MySqlDefaultChanger.class);
@Inject @Inject
private Settings settings; private Settings settings;
@ -98,7 +101,7 @@ class MySqlDefaultChanger implements DebugSection {
throw new IllegalStateException("Unknown operation '" + operation + "'"); throw new IllegalStateException("Unknown operation '" + operation + "'");
} }
} catch (SQLException | IllegalStateException e) { } catch (SQLException | IllegalStateException e) {
ConsoleLogger.logException("Failed to perform MySQL default altering operation:", e); logger.logException("Failed to perform MySQL default altering operation:", e);
} }
} }
} }
@ -134,7 +137,7 @@ class MySqlDefaultChanger implements DebugSection {
} }
// Log success message // Log success message
ConsoleLogger.info("Changed MySQL column '" + columnName + "' to be NOT NULL, as initiated by '" logger.info("Changed MySQL column '" + columnName + "' to be NOT NULL, as initiated by '"
+ sender.getName() + "'"); + sender.getName() + "'");
} }
@ -168,7 +171,7 @@ class MySqlDefaultChanger implements DebugSection {
+ "') to be NULL, modifying " + updatedRows + " entries"); + "') to be NULL, modifying " + updatedRows + " entries");
// Log success message // Log success message
ConsoleLogger.info("Changed MySQL column '" + columnName + "' to allow NULL, as initiated by '" logger.info("Changed MySQL column '" + columnName + "' to allow NULL, as initiated by '"
+ sender.getName() + "'"); + sender.getName() + "'");
} }
@ -191,7 +194,7 @@ class MySqlDefaultChanger implements DebugSection {
+ " (" + columnName + "): " + isNullText + ", " + defaultText); + " (" + columnName + "): " + isNullText + ", " + defaultText);
} }
} catch (SQLException e) { } catch (SQLException e) {
ConsoleLogger.logException("Failed while showing column details:", e); logger.logException("Failed while showing column details:", e);
sender.sendMessage("Failed while showing column details. See log for info"); sender.sendMessage("Failed while showing column details. See log for info");
} }
@ -228,7 +231,7 @@ class MySqlDefaultChanger implements DebugSection {
} }
return String.join(ChatColor.RESET + ", ", formattedColumns); return String.join(ChatColor.RESET + ", ", formattedColumns);
} catch (SQLException e) { } catch (SQLException e) {
ConsoleLogger.logException("Failed to construct column list:", e); logger.logException("Failed to construct column list:", e);
return ChatColor.RED + "An error occurred! Please see the console for details."; return ChatColor.RED + "An error occurred! Please see the console for details.";
} }
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.authme.debug;
import ch.jalu.datasourcecolumns.data.DataSourceValue; import ch.jalu.datasourcecolumns.data.DataSourceValue;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.SendMailSsl; import fr.xephi.authme.mail.SendMailSsl;
import fr.xephi.authme.permission.DebugSectionPermissions; import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
@ -22,6 +23,8 @@ import java.util.List;
*/ */
class TestEmailSender implements DebugSection { class TestEmailSender implements DebugSection {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TestEmailSender.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@ -110,7 +113,7 @@ class TestEmailSender implements DebugSection {
try { try {
htmlEmail = sendMailSsl.initializeMail(email); htmlEmail = sendMailSsl.initializeMail(email);
} catch (EmailException e) { } catch (EmailException e) {
ConsoleLogger.logException("Failed to create email for sample email:", e); logger.logException("Failed to create email for sample email:", e);
return false; return false;
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
@ -20,6 +21,8 @@ import java.util.List;
*/ */
public class EmailSetPasswordCommand extends PlayerCommand { public class EmailSetPasswordCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailSetPasswordCommand.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@ -46,7 +49,7 @@ public class EmailSetPasswordCommand extends PlayerCommand {
HashedPassword hashedPassword = passwordSecurity.computeHash(password, name); HashedPassword hashedPassword = passwordSecurity.computeHash(password, name);
dataSource.updatePassword(name, hashedPassword); dataSource.updatePassword(name, hashedPassword);
recoveryService.removeFromSuccessfulRecovery(player); recoveryService.removeFromSuccessfulRecovery(player);
ConsoleLogger.info("Player '" + name + "' has changed their password from recovery"); logger.info("Player '" + name + "' has changed their password from recovery");
commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS); commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS);
} else { } else {
commonService.send(player, result.getMessageKey(), result.getArgs()); commonService.send(player, result.getMessageKey(), result.getArgs());

View File

@ -5,6 +5,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -22,6 +23,8 @@ import java.util.List;
*/ */
public class RecoverEmailCommand extends PlayerCommand { public class RecoverEmailCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RecoverEmailCommand.class);
@Inject @Inject
private CommonService commonService; private CommonService commonService;
@ -49,7 +52,7 @@ public class RecoverEmailCommand extends PlayerCommand {
final String playerName = player.getName(); final String playerName = player.getName();
if (!emailService.hasAllInformation()) { if (!emailService.hasAllInformation()) {
ConsoleLogger.warning("Mail API is not set"); logger.warning("Mail API is not set");
commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
return; return;
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.captcha.RegistrationCaptchaManager; import fr.xephi.authme.data.captcha.RegistrationCaptchaManager;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
@ -34,6 +35,8 @@ import static fr.xephi.authme.settings.properties.RegistrationSettings.REGISTER_
*/ */
public class RegisterCommand extends PlayerCommand { public class RegisterCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RegisterCommand.class);
@Inject @Inject
private Management management; private Management management;
@ -155,7 +158,7 @@ public class RegisterCommand extends PlayerCommand {
private void handleEmailRegistration(Player player, List<String> arguments) { private void handleEmailRegistration(Player player, List<String> arguments) {
if (!emailService.hasAllInformation()) { if (!emailService.hasAllInformation()) {
commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
ConsoleLogger.warning("Cannot register player '" + player.getName() + "': no email or password is set " logger.warning("Cannot register player '" + player.getName() + "': no email or password is set "
+ "to send emails from. Please adjust your config at " + EmailSettings.MAIL_ACCOUNT.getPath()); + "to send emails from. Please adjust your config at " + EmailSettings.MAIL_ACCOUNT.getPath());
return; return;
} }

View File

@ -5,6 +5,7 @@ import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.security.totp.GenerateTotpService; import fr.xephi.authme.security.totp.GenerateTotpService;
@ -19,6 +20,8 @@ import java.util.List;
*/ */
public class ConfirmTotpCommand extends PlayerCommand { public class ConfirmTotpCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ConfirmTotpCommand.class);
@Inject @Inject
private GenerateTotpService generateTotpService; private GenerateTotpService generateTotpService;
@ -63,7 +66,7 @@ public class ConfirmTotpCommand extends PlayerCommand {
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_SUCCESS); messages.send(player, MessageKey.TWO_FACTOR_ENABLE_SUCCESS);
auth.setTotpKey(totpDetails.getTotpKey()); auth.setTotpKey(totpDetails.getTotpKey());
playerCache.updatePlayer(auth); playerCache.updatePlayer(auth);
ConsoleLogger.info("Player '" + player.getName() + "' has successfully added a TOTP key to their account"); logger.info("Player '" + player.getName() + "' has successfully added a TOTP key to their account");
} else { } else {
messages.send(player, MessageKey.ERROR); messages.send(player, MessageKey.ERROR);
} }

View File

@ -5,6 +5,7 @@ import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.security.totp.TotpAuthenticator; import fr.xephi.authme.security.totp.TotpAuthenticator;
@ -18,6 +19,8 @@ import java.util.List;
*/ */
public class RemoveTotpCommand extends PlayerCommand { public class RemoveTotpCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RemoveTotpCommand.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@ -51,7 +54,7 @@ public class RemoveTotpCommand extends PlayerCommand {
auth.setTotpKey(null); auth.setTotpKey(null);
playerCache.updatePlayer(auth); playerCache.updatePlayer(auth);
messages.send(player, MessageKey.TWO_FACTOR_REMOVED_SUCCESS); messages.send(player, MessageKey.TWO_FACTOR_REMOVED_SUCCESS);
ConsoleLogger.info("Player '" + player.getName() + "' removed their TOTP key"); logger.info("Player '" + player.getName() + "' removed their TOTP key");
} else { } else {
messages.send(player, MessageKey.ERROR); messages.send(player, MessageKey.ERROR);
} }

View File

@ -8,6 +8,7 @@ import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.data.limbo.LimboPlayerState; import fr.xephi.authme.data.limbo.LimboPlayerState;
import fr.xephi.authme.data.limbo.LimboService; import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.process.login.AsynchronousLogin; import fr.xephi.authme.process.login.AsynchronousLogin;
@ -22,6 +23,8 @@ import java.util.List;
*/ */
public class TotpCodeCommand extends PlayerCommand { public class TotpCodeCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TotpCodeCommand.class);
@Inject @Inject
private LimboService limboService; private LimboService limboService;
@ -57,7 +60,7 @@ public class TotpCodeCommand extends PlayerCommand {
if (limbo != null && limbo.getState() == LimboPlayerState.TOTP_REQUIRED) { if (limbo != null && limbo.getState() == LimboPlayerState.TOTP_REQUIRED) {
processCode(player, auth, arguments.get(0)); processCode(player, auth, arguments.get(0));
} else { } else {
ConsoleLogger.debug(() -> "Aborting TOTP check for player '" + player.getName() logger.debug(() -> "Aborting TOTP check for player '" + player.getName()
+ "'. Invalid limbo state: " + (limbo == null ? "no limbo" : limbo.getState())); + "'. Invalid limbo state: " + (limbo == null ? "no limbo" : limbo.getState()));
messages.send(player, MessageKey.LOGIN_MESSAGE); messages.send(player, MessageKey.LOGIN_MESSAGE);
} }
@ -66,10 +69,10 @@ public class TotpCodeCommand extends PlayerCommand {
private void processCode(Player player, PlayerAuth auth, String inputCode) { private void processCode(Player player, PlayerAuth auth, String inputCode) {
boolean isCodeValid = totpAuthenticator.checkCode(auth, inputCode); boolean isCodeValid = totpAuthenticator.checkCode(auth, inputCode);
if (isCodeValid) { if (isCodeValid) {
ConsoleLogger.debug("Successfully checked TOTP code for `{0}`", player.getName()); logger.debug("Successfully checked TOTP code for `{0}`", player.getName());
asynchronousLogin.performLogin(player, auth); asynchronousLogin.performLogin(player, auth);
} else { } else {
ConsoleLogger.debug("Input TOTP code was invalid for player `{0}`", player.getName()); logger.debug("Input TOTP code was invalid for player `{0}`", player.getName());
messages.send(player, MessageKey.TWO_FACTOR_INVALID_CODE); messages.send(player, MessageKey.TWO_FACTOR_INVALID_CODE);
} }
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.verification;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.VerificationCodeManager; import fr.xephi.authme.data.VerificationCodeManager;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.CommonService;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -15,6 +16,8 @@ import java.util.List;
*/ */
public class VerificationCommand extends PlayerCommand { public class VerificationCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(VerificationCommand.class);
@Inject @Inject
private CommonService commonService; private CommonService commonService;
@ -26,7 +29,7 @@ public class VerificationCommand extends PlayerCommand {
final String playerName = player.getName(); final String playerName = player.getName();
if (!codeManager.canSendMail()) { if (!codeManager.canSendMail()) {
ConsoleLogger.warning("Mail API is not set"); logger.warning("Mail API is not set");
commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
return; return;
} }

View File

@ -5,6 +5,7 @@ import org.bukkit.Location;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -40,6 +41,7 @@ public class PlayerAuth {
private String world; private String world;
private float yaw; private float yaw;
private float pitch; private float pitch;
private UUID uuid;
/** /**
* Hidden constructor. * Hidden constructor.
@ -169,6 +171,14 @@ public class PlayerAuth {
this.totpKey = totpKey; this.totpKey = totpKey;
} }
public UUID getUuid() {
return uuid;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof PlayerAuth)) { if (!(obj instanceof PlayerAuth)) {
@ -193,7 +203,8 @@ public class PlayerAuth {
+ " ! LastLogin : " + lastLogin + " ! LastLogin : " + lastLogin
+ " ! LastPosition : " + x + "," + y + "," + z + "," + world + " ! LastPosition : " + x + "," + y + "," + z + "," + world
+ " ! Email : " + email + " ! Email : " + email
+ " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}"; + " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}"
+ " ! UUID : " + uuid;
} }
public static Builder builder() { public static Builder builder() {
@ -218,6 +229,7 @@ public class PlayerAuth {
private String world; private String world;
private float yaw; private float yaw;
private float pitch; private float pitch;
private UUID uuid;
/** /**
* Creates a PlayerAuth object. * Creates a PlayerAuth object.
@ -243,6 +255,7 @@ public class PlayerAuth {
auth.world = Optional.ofNullable(world).orElse("world"); auth.world = Optional.ofNullable(world).orElse("world");
auth.yaw = yaw; auth.yaw = yaw;
auth.pitch = pitch; auth.pitch = pitch;
auth.uuid = uuid;
return auth; return auth;
} }
@ -349,5 +362,10 @@ public class PlayerAuth {
this.registrationDate = date; this.registrationDate = date;
return this; return this;
} }
public Builder uuid(UUID uuid) {
this.uuid = uuid;
return this;
}
} }
} }

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
@ -26,6 +27,8 @@ import java.util.Collections;
*/ */
class AuthGroupHandler implements Reloadable { class AuthGroupHandler implements Reloadable {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AuthGroupHandler.class);
@Inject @Inject
private PermissionsManager permissionsManager; private PermissionsManager permissionsManager;
@ -78,7 +81,7 @@ class AuthGroupHandler implements Reloadable {
throw new IllegalStateException("Encountered unhandled auth group type '" + groupType + "'"); throw new IllegalStateException("Encountered unhandled auth group type '" + groupType + "'");
} }
ConsoleLogger.debug(() -> player.getName() + " changed to " logger.debug(() -> player.getName() + " changed to "
+ groupType + ": has groups " + permissionsManager.getGroups(player)); + groupType + ": has groups " + permissionsManager.getGroups(player));
} }
@ -95,7 +98,7 @@ class AuthGroupHandler implements Reloadable {
// Make sure group support is available // Make sure group support is available
if (!permissionsManager.hasGroupSupport()) { if (!permissionsManager.hasGroupSupport()) {
ConsoleLogger.warning("The current permissions system doesn't have group support, unable to set group!"); logger.warning("The current permissions system doesn't have group support, unable to set group!");
return false; return false;
} }
return true; return true;

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.persistence.LimboPersistence; import fr.xephi.authme.data.limbo.persistence.LimboPersistence;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.SpawnLoader;
import org.bukkit.Location; import org.bukkit.Location;
@ -22,6 +23,8 @@ import static fr.xephi.authme.settings.properties.LimboSettings.RESTORE_WALK_SPE
*/ */
public class LimboService { public class LimboService {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LimboService.class);
private final Map<String, LimboPlayer> entries = new ConcurrentHashMap<>(); private final Map<String, LimboPlayer> entries = new ConcurrentHashMap<>();
@Inject @Inject
@ -56,13 +59,13 @@ public class LimboService {
LimboPlayer limboFromDisk = persistence.getLimboPlayer(player); LimboPlayer limboFromDisk = persistence.getLimboPlayer(player);
if (limboFromDisk != null) { if (limboFromDisk != null) {
ConsoleLogger.debug("LimboPlayer for `{0}` already exists on disk", name); logger.debug("LimboPlayer for `{0}` already exists on disk", name);
} }
LimboPlayer existingLimbo = entries.remove(name); LimboPlayer existingLimbo = entries.remove(name);
if (existingLimbo != null) { if (existingLimbo != null) {
existingLimbo.clearTasks(); existingLimbo.clearTasks();
ConsoleLogger.debug("LimboPlayer for `{0}` already present in memory", name); logger.debug("LimboPlayer for `{0}` already present in memory", name);
} }
Location location = spawnLoader.getPlayerLocationOrSpawn(player); Location location = spawnLoader.getPlayerLocationOrSpawn(player);
@ -112,14 +115,14 @@ public class LimboService {
LimboPlayer limbo = entries.remove(lowerName); LimboPlayer limbo = entries.remove(lowerName);
if (limbo == null) { if (limbo == null) {
ConsoleLogger.debug("No LimboPlayer found for `{0}` - cannot restore", lowerName); logger.debug("No LimboPlayer found for `{0}` - cannot restore", lowerName);
} else { } else {
player.setOp(limbo.isOperator()); player.setOp(limbo.isOperator());
settings.getProperty(RESTORE_ALLOW_FLIGHT).restoreAllowFlight(player, limbo); settings.getProperty(RESTORE_ALLOW_FLIGHT).restoreAllowFlight(player, limbo);
settings.getProperty(RESTORE_FLY_SPEED).restoreFlySpeed(player, limbo); settings.getProperty(RESTORE_FLY_SPEED).restoreFlySpeed(player, limbo);
settings.getProperty(RESTORE_WALK_SPEED).restoreWalkSpeed(player, limbo); settings.getProperty(RESTORE_WALK_SPEED).restoreWalkSpeed(player, limbo);
limbo.clearTasks(); limbo.clearTasks();
ConsoleLogger.debug("Restored LimboPlayer stats for `{0}`", lowerName); logger.debug("Restored LimboPlayer stats for `{0}`", lowerName);
persistence.removeLimboPlayer(player); persistence.removeLimboPlayer(player);
} }
authGroupHandler.setGroup(player, limbo, AuthGroupType.LOGGED_IN); authGroupHandler.setGroup(player, limbo, AuthGroupType.LOGGED_IN);
@ -177,7 +180,7 @@ public class LimboService {
private Optional<LimboPlayer> getLimboOrLogError(Player player, String context) { private Optional<LimboPlayer> getLimboOrLogError(Player player, String context) {
LimboPlayer limbo = entries.get(player.getName().toLowerCase()); LimboPlayer limbo = entries.get(player.getName().toLowerCase());
if (limbo == null) { if (limbo == null) {
ConsoleLogger.debug("No LimboPlayer found for `{0}`. Action: {1}", player.getName(), context); logger.debug("No LimboPlayer found for `{0}`. Action: {1}", player.getName(), context);
} }
return Optional.ofNullable(limbo); return Optional.ofNullable(limbo);
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.data.limbo; package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings; import fr.xephi.authme.settings.properties.LimboSettings;
@ -19,6 +20,8 @@ import static fr.xephi.authme.util.Utils.isCollectionEmpty;
*/ */
class LimboServiceHelper { class LimboServiceHelper {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LimboServiceHelper.class);
@Inject @Inject
private PermissionsManager permissionsManager; private PermissionsManager permissionsManager;
@ -41,7 +44,7 @@ class LimboServiceHelper {
float flySpeed = player.getFlySpeed(); float flySpeed = player.getFlySpeed();
Collection<String> playerGroups = permissionsManager.hasGroupSupport() Collection<String> playerGroups = permissionsManager.hasGroupSupport()
? permissionsManager.getGroups(player) : Collections.emptyList(); ? permissionsManager.getGroups(player) : Collections.emptyList();
ConsoleLogger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups)); logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups));
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed); return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed);
} }
@ -98,9 +101,8 @@ class LimboServiceHelper {
return first == null ? second : first; return first == null ? second : first;
} }
private static Collection<String> getLimboGroups(Collection<String> oldLimboGroups, private Collection<String> getLimboGroups(Collection<String> oldLimboGroups, Collection<String> newLimboGroups) {
Collection<String> newLimboGroups) { logger.debug("Limbo merge: new and old groups are `{0}` and `{1}`", newLimboGroups, oldLimboGroups);
ConsoleLogger.debug("Limbo merge: new and old groups are `{0}` and `{1}`", newLimboGroups, oldLimboGroups);
return isCollectionEmpty(oldLimboGroups) ? newLimboGroups : oldLimboGroups; return isCollectionEmpty(oldLimboGroups) ? newLimboGroups : oldLimboGroups;
} }
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.data.limbo; package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
@ -15,14 +16,14 @@ public enum WalkFlySpeedRestoreType {
RESTORE { RESTORE {
@Override @Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) { public void restoreFlySpeed(Player player, LimboPlayer limbo) {
ConsoleLogger.debug("Restoring fly speed for LimboPlayer " + player.getName() + " to " logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName() + " to "
+ limbo.getFlySpeed() + " (RESTORE mode)"); + limbo.getFlySpeed() + " (RESTORE mode)");
player.setFlySpeed(limbo.getFlySpeed()); player.setFlySpeed(limbo.getFlySpeed());
} }
@Override @Override
public void restoreWalkSpeed(Player player, LimboPlayer limbo) { public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
ConsoleLogger.debug("Restoring walk speed for LimboPlayer " + player.getName() + " to " logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + " to "
+ limbo.getWalkSpeed() + " (RESTORE mode)"); + limbo.getWalkSpeed() + " (RESTORE mode)");
player.setWalkSpeed(limbo.getWalkSpeed()); player.setWalkSpeed(limbo.getWalkSpeed());
} }
@ -36,11 +37,11 @@ public enum WalkFlySpeedRestoreType {
public void restoreFlySpeed(Player player, LimboPlayer limbo) { public void restoreFlySpeed(Player player, LimboPlayer limbo) {
float limboFlySpeed = limbo.getFlySpeed(); float limboFlySpeed = limbo.getFlySpeed();
if (limboFlySpeed > 0.01f) { if (limboFlySpeed > 0.01f) {
ConsoleLogger.debug("Restoring fly speed for LimboPlayer " + player.getName() + " to " logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName() + " to "
+ limboFlySpeed + " (RESTORE_NO_ZERO mode)"); + limboFlySpeed + " (RESTORE_NO_ZERO mode)");
player.setFlySpeed(limboFlySpeed); player.setFlySpeed(limboFlySpeed);
} else { } else {
ConsoleLogger.debug("Restoring fly speed for LimboPlayer " + player.getName() logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName()
+ " to DEFAULT, it was 0! (RESTORE_NO_ZERO mode)"); + " to DEFAULT, it was 0! (RESTORE_NO_ZERO mode)");
player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED); player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
} }
@ -50,11 +51,11 @@ public enum WalkFlySpeedRestoreType {
public void restoreWalkSpeed(Player player, LimboPlayer limbo) { public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
float limboWalkSpeed = limbo.getWalkSpeed(); float limboWalkSpeed = limbo.getWalkSpeed();
if (limboWalkSpeed > 0.01f) { if (limboWalkSpeed > 0.01f) {
ConsoleLogger.debug("Restoring walk speed for LimboPlayer " + player.getName() + " to " logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + " to "
+ limboWalkSpeed + " (RESTORE_NO_ZERO mode)"); + limboWalkSpeed + " (RESTORE_NO_ZERO mode)");
player.setWalkSpeed(limboWalkSpeed); player.setWalkSpeed(limboWalkSpeed);
} else { } else {
ConsoleLogger.debug("Restoring walk speed for LimboPlayer " + player.getName() + "" logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + ""
+ " to DEFAULT, it was 0! (RESTORE_NO_ZERO mode)"); + " to DEFAULT, it was 0! (RESTORE_NO_ZERO mode)");
player.setWalkSpeed(LimboPlayer.DEFAULT_WALK_SPEED); player.setWalkSpeed(LimboPlayer.DEFAULT_WALK_SPEED);
} }
@ -68,7 +69,7 @@ public enum WalkFlySpeedRestoreType {
@Override @Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) { public void restoreFlySpeed(Player player, LimboPlayer limbo) {
float newSpeed = Math.max(player.getFlySpeed(), limbo.getFlySpeed()); float newSpeed = Math.max(player.getFlySpeed(), limbo.getFlySpeed());
ConsoleLogger.debug("Restoring fly speed for LimboPlayer " + player.getName() + " to " + newSpeed logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName() + " to " + newSpeed
+ " (Current: " + player.getFlySpeed() + ", Limbo: " + limbo.getFlySpeed() + ") (MAX_RESTORE mode)"); + " (Current: " + player.getFlySpeed() + ", Limbo: " + limbo.getFlySpeed() + ") (MAX_RESTORE mode)");
player.setFlySpeed(newSpeed); player.setFlySpeed(newSpeed);
} }
@ -76,7 +77,7 @@ public enum WalkFlySpeedRestoreType {
@Override @Override
public void restoreWalkSpeed(Player player, LimboPlayer limbo) { public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
float newSpeed = Math.max(player.getWalkSpeed(), limbo.getWalkSpeed()); float newSpeed = Math.max(player.getWalkSpeed(), limbo.getWalkSpeed());
ConsoleLogger.debug("Restoring walk speed for LimboPlayer " + player.getName() + " to " + newSpeed logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + " to " + newSpeed
+ " (Current: " + player.getWalkSpeed() + ", Limbo: " + limbo.getWalkSpeed() + ") (MAX_RESTORE mode)"); + " (Current: " + player.getWalkSpeed() + ", Limbo: " + limbo.getWalkSpeed() + ") (MAX_RESTORE mode)");
player.setWalkSpeed(newSpeed); player.setWalkSpeed(newSpeed);
} }
@ -88,19 +89,21 @@ public enum WalkFlySpeedRestoreType {
DEFAULT { DEFAULT {
@Override @Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) { public void restoreFlySpeed(Player player, LimboPlayer limbo) {
ConsoleLogger.debug("Restoring fly speed for LimboPlayer " + player.getName() logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName()
+ " to DEFAULT (DEFAULT mode)"); + " to DEFAULT (DEFAULT mode)");
player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED); player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
} }
@Override @Override
public void restoreWalkSpeed(Player player, LimboPlayer limbo) { public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
ConsoleLogger.debug("Restoring walk speed for LimboPlayer " + player.getName() logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName()
+ " to DEFAULT (DEFAULT mode)"); + " to DEFAULT (DEFAULT mode)");
player.setWalkSpeed(LimboPlayer.DEFAULT_WALK_SPEED); player.setWalkSpeed(LimboPlayer.DEFAULT_WALK_SPEED);
} }
}; };
private static final ConsoleLogger logger = ConsoleLoggerFactory.get(WalkFlySpeedRestoreType.class);
/** /**
* Restores the fly speed from Limbo to Player according to the restoration type. * Restores the fly speed from Limbo to Player according to the restoration type.
* *

View File

@ -7,11 +7,11 @@ import com.google.gson.GsonBuilder;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboPlayer; import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings; import fr.xephi.authme.settings.properties.LimboSettings;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
@ -34,6 +34,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
private static final Type LIMBO_MAP_TYPE = new TypeToken<Map<String, LimboPlayer>>(){}.getType(); private static final Type LIMBO_MAP_TYPE = new TypeToken<Map<String, LimboPlayer>>(){}.getType();
private final ConsoleLogger logger = ConsoleLoggerFactory.get(DistributedFilesPersistenceHandler.class);
private final File cacheFolder; private final File cacheFolder;
private final Gson gson; private final Gson gson;
private final SegmentNameBuilder segmentNameBuilder; private final SegmentNameBuilder segmentNameBuilder;
@ -104,7 +105,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
try (FileWriter fw = new FileWriter(file)) { try (FileWriter fw = new FileWriter(file)) {
gson.toJson(entries, fw); gson.toJson(entries, fw);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not write to '" + file + "':", e); logger.logException("Could not write to '" + file + "':", e);
} }
} }
@ -116,7 +117,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
try { try {
return gson.fromJson(Files.asCharSource(file, StandardCharsets.UTF_8).read(), LIMBO_MAP_TYPE); return gson.fromJson(Files.asCharSource(file, StandardCharsets.UTF_8).read(), LIMBO_MAP_TYPE);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Failed reading '" + file + "':", e); logger.logException("Failed reading '" + file + "':", e);
} }
return null; return null;
} }
@ -165,7 +166,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
private void saveToNewSegments(Map<String, LimboPlayer> limbosFromOldSegments) { private void saveToNewSegments(Map<String, LimboPlayer> limbosFromOldSegments) {
Map<String, Map<String, LimboPlayer>> limboBySegment = groupBySegment(limbosFromOldSegments); Map<String, Map<String, LimboPlayer>> limboBySegment = groupBySegment(limbosFromOldSegments);
ConsoleLogger.info("Saving " + limbosFromOldSegments.size() + " LimboPlayers from old segments into " logger.info("Saving " + limbosFromOldSegments.size() + " LimboPlayers from old segments into "
+ limboBySegment.size() + " current segments"); + limboBySegment.size() + " current segments");
for (Map.Entry<String, Map<String, LimboPlayer>> entry : limboBySegment.entrySet()) { for (Map.Entry<String, Map<String, LimboPlayer>> entry : limboBySegment.entrySet()) {
File file = getSegmentFile(entry.getKey()); File file = getSegmentFile(entry.getKey());
@ -204,7 +205,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
.filter(f -> isLimboJsonFile(f) && f.length() < 3) .filter(f -> isLimboJsonFile(f) && f.length() < 3)
.peek(FileUtils::delete) .peek(FileUtils::delete)
.count(); .count();
ConsoleLogger.debug("Limbo: Deleted {0} empty segment files", deletedFiles); logger.debug("Limbo: Deleted {0} empty segment files", deletedFiles);
} }
/** /**
@ -216,10 +217,10 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
return name.startsWith("seg") && name.endsWith("-limbo.json"); return name.startsWith("seg") && name.endsWith("-limbo.json");
} }
private static File[] listFiles(File folder) { private File[] listFiles(File folder) {
File[] files = folder.listFiles(); File[] files = folder.listFiles();
if (files == null) { if (files == null) {
ConsoleLogger.warning("Could not get files of '" + folder + "'"); logger.warning("Could not get files of '" + folder + "'");
return new File[0]; return new File[0];
} }
return files; return files;

View File

@ -6,9 +6,9 @@ import com.google.gson.GsonBuilder;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboPlayer; import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
@ -21,6 +21,8 @@ import java.nio.charset.StandardCharsets;
*/ */
class IndividualFilesPersistenceHandler implements LimboPersistenceHandler { class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(IndividualFilesPersistenceHandler.class);
private final Gson gson; private final Gson gson;
private final File cacheDir; private final File cacheDir;
@ -28,7 +30,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
IndividualFilesPersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService) { IndividualFilesPersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService) {
cacheDir = new File(dataFolder, "playerdata"); cacheDir = new File(dataFolder, "playerdata");
if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) { if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) {
ConsoleLogger.warning("Failed to create playerdata directory '" + cacheDir + "'"); logger.warning("Failed to create playerdata directory '" + cacheDir + "'");
} }
gson = new GsonBuilder() gson = new GsonBuilder()
.registerTypeAdapter(LimboPlayer.class, new LimboPlayerSerializer()) .registerTypeAdapter(LimboPlayer.class, new LimboPlayerSerializer())
@ -49,7 +51,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
String str = Files.asCharSource(file, StandardCharsets.UTF_8).read(); String str = Files.asCharSource(file, StandardCharsets.UTF_8).read();
return gson.fromJson(str, LimboPlayer.class); return gson.fromJson(str, LimboPlayer.class);
} catch (IOException e) { } catch (IOException e) {
ConsoleLogger.logException("Could not read player data on disk for '" + player.getName() + "'", e); logger.logException("Could not read player data on disk for '" + player.getName() + "'", e);
return null; return null;
} }
} }
@ -63,7 +65,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
Files.touch(file); Files.touch(file);
Files.write(gson.toJson(limboPlayer), file, StandardCharsets.UTF_8); Files.write(gson.toJson(limboPlayer), file, StandardCharsets.UTF_8);
} catch (IOException e) { } catch (IOException e) {
ConsoleLogger.logException("Failed to write " + player.getName() + " data:", e); logger.logException("Failed to write " + player.getName() + " data:", e);
} }
} }

View File

@ -4,6 +4,7 @@ import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboPlayer; import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings; import fr.xephi.authme.settings.properties.LimboSettings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -15,6 +16,8 @@ import javax.inject.Inject;
*/ */
public class LimboPersistence implements SettingsDependent { public class LimboPersistence implements SettingsDependent {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LimboPersistence.class);
private final Factory<LimboPersistenceHandler> handlerFactory; private final Factory<LimboPersistenceHandler> handlerFactory;
private LimboPersistenceHandler handler; private LimboPersistenceHandler handler;
@ -35,7 +38,7 @@ public class LimboPersistence implements SettingsDependent {
try { try {
return handler.getLimboPlayer(player); return handler.getLimboPlayer(player);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not get LimboPlayer for '" + player.getName() + "'", e); logger.logException("Could not get LimboPlayer for '" + player.getName() + "'", e);
} }
return null; return null;
} }
@ -50,7 +53,7 @@ public class LimboPersistence implements SettingsDependent {
try { try {
handler.saveLimboPlayer(player, limbo); handler.saveLimboPlayer(player, limbo);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not save LimboPlayer for '" + player.getName() + "'", e); logger.logException("Could not save LimboPlayer for '" + player.getName() + "'", e);
} }
} }
@ -63,7 +66,7 @@ public class LimboPersistence implements SettingsDependent {
try { try {
handler.removeLimboPlayer(player); handler.removeLimboPlayer(player);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not remove LimboPlayer for '" + player.getName() + "'", e); logger.logException("Could not remove LimboPlayer for '" + player.getName() + "'", e);
} }
} }
@ -72,7 +75,7 @@ public class LimboPersistence implements SettingsDependent {
LimboPersistenceType persistenceType = settings.getProperty(LimboSettings.LIMBO_PERSISTENCE_TYPE); LimboPersistenceType persistenceType = settings.getProperty(LimboSettings.LIMBO_PERSISTENCE_TYPE);
// If we're changing from an existing handler, output a quick hint that nothing is converted. // If we're changing from an existing handler, output a quick hint that nothing is converted.
if (handler != null && handler.getType() != persistenceType) { if (handler != null && handler.getType() != persistenceType) {
ConsoleLogger.info("Limbo persistence type has changed! Note that the data is not converted."); logger.info("Limbo persistence type has changed! Note that the data is not converted.");
} }
handler = handlerFactory.newInstance(persistenceType.getImplementationClass()); handler = handlerFactory.newInstance(persistenceType.getImplementationClass());
} }

View File

@ -53,7 +53,8 @@ public abstract class AbstractSqlDataSource implements DataSource {
public boolean saveAuth(PlayerAuth auth) { public boolean saveAuth(PlayerAuth auth) {
return columnsHandler.insert(auth, return columnsHandler.insert(auth,
AuthMeColumns.NAME, AuthMeColumns.NICK_NAME, AuthMeColumns.PASSWORD, AuthMeColumns.SALT, AuthMeColumns.NAME, AuthMeColumns.NICK_NAME, AuthMeColumns.PASSWORD, AuthMeColumns.SALT,
AuthMeColumns.EMAIL, AuthMeColumns.REGISTRATION_DATE, AuthMeColumns.REGISTRATION_IP); AuthMeColumns.EMAIL, AuthMeColumns.REGISTRATION_DATE, AuthMeColumns.REGISTRATION_IP,
AuthMeColumns.UUID);
} }
@Override @Override

View File

@ -12,6 +12,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
@ -25,6 +26,8 @@ import java.util.stream.Collectors;
public class CacheDataSource implements DataSource { public class CacheDataSource implements DataSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(CacheDataSource.class);
private final DataSource source; private final DataSource source;
private final PlayerCache playerCache; private final PlayerCache playerCache;
private final LoadingCache<String, Optional<PlayerAuth>> cachedAuths; private final LoadingCache<String, Optional<PlayerAuth>> cachedAuths;
@ -164,7 +167,7 @@ public class CacheDataSource implements DataSource {
try { try {
executorService.awaitTermination(5, TimeUnit.SECONDS); executorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
ConsoleLogger.logException("Could not close executor service:", e); logger.logException("Could not close executor service:", e);
} }
cachedAuths.invalidateAll(); cachedAuths.invalidateAll();
source.closeConnection(); source.closeConnection();

View File

@ -30,6 +30,7 @@ public final class Columns {
public final String HAS_SESSION; public final String HAS_SESSION;
public final String REGISTRATION_DATE; public final String REGISTRATION_DATE;
public final String REGISTRATION_IP; public final String REGISTRATION_IP;
public final String PLAYER_UUID;
public Columns(Settings settings) { public Columns(Settings settings) {
NAME = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME); NAME = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME);
@ -52,6 +53,7 @@ public final class Columns {
HAS_SESSION = settings.getProperty(DatabaseSettings.MYSQL_COL_HASSESSION); HAS_SESSION = settings.getProperty(DatabaseSettings.MYSQL_COL_HASSESSION);
REGISTRATION_DATE = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_DATE); REGISTRATION_DATE = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_DATE);
REGISTRATION_IP = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_IP); REGISTRATION_IP = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_IP);
PLAYER_UUID = settings.getProperty(DatabaseSettings.MYSQL_COL_PLAYER_UUID);
} }
} }

View File

@ -8,9 +8,11 @@ import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler; import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension; import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory; import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.util.UuidUtils;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
@ -23,6 +25,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong; import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException; import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
@ -32,8 +35,10 @@ import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
*/ */
@SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore @SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore
public class MySQL extends AbstractSqlDataSource { public class MySQL extends AbstractSqlDataSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(MySQL.class);
private boolean useSsl; private boolean useSsl;
private boolean serverCertificateVerification;
private String host; private String host;
private String port; private String port;
private String username; private String username;
@ -55,14 +60,14 @@ public class MySQL extends AbstractSqlDataSource {
this.setConnectionArguments(); this.setConnectionArguments();
} catch (RuntimeException e) { } catch (RuntimeException e) {
if (e instanceof IllegalArgumentException) { if (e instanceof IllegalArgumentException) {
ConsoleLogger.warning("Invalid database arguments! Please check your configuration!"); logger.warning("Invalid database arguments! Please check your configuration!");
ConsoleLogger.warning("If this error persists, please report it to the developer!"); logger.warning("If this error persists, please report it to the developer!");
} }
if (e instanceof PoolInitializationException) { if (e instanceof PoolInitializationException) {
ConsoleLogger.warning("Can't initialize database connection! Please check your configuration!"); logger.warning("Can't initialize database connection! Please check your configuration!");
ConsoleLogger.warning("If this error persists, please report it to the developer!"); logger.warning("If this error persists, please report it to the developer!");
} }
ConsoleLogger.warning("Can't use the Hikari Connection Pool! Please, report this error to the developer!"); logger.warning("Can't use the Hikari Connection Pool! Please, report this error to the developer!");
throw e; throw e;
} }
@ -71,8 +76,8 @@ public class MySQL extends AbstractSqlDataSource {
checkTablesAndColumns(); checkTablesAndColumns();
} catch (SQLException e) { } catch (SQLException e) {
closeConnection(); closeConnection();
ConsoleLogger.logException("Can't initialize the MySQL database:", e); logger.logException("Can't initialize the MySQL database:", e);
ConsoleLogger.warning("Please check your database settings in the config.yml file!"); logger.warning("Please check your database settings in the config.yml file!");
throw e; throw e;
} }
} }
@ -103,6 +108,7 @@ public class MySQL extends AbstractSqlDataSource {
this.poolSize = settings.getProperty(DatabaseSettings.MYSQL_POOL_SIZE); this.poolSize = settings.getProperty(DatabaseSettings.MYSQL_POOL_SIZE);
this.maxLifetime = settings.getProperty(DatabaseSettings.MYSQL_CONNECTION_MAX_LIFETIME); this.maxLifetime = settings.getProperty(DatabaseSettings.MYSQL_CONNECTION_MAX_LIFETIME);
this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL); this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL);
this.serverCertificateVerification = settings.getProperty(DatabaseSettings.MYSQL_CHECK_SERVER_CERTIFICATE);
} }
/** /**
@ -126,6 +132,11 @@ public class MySQL extends AbstractSqlDataSource {
// Request mysql over SSL // Request mysql over SSL
ds.addDataSourceProperty("useSSL", String.valueOf(useSsl)); ds.addDataSourceProperty("useSSL", String.valueOf(useSsl));
// Disabling server certificate verification on need
if (!serverCertificateVerification) {
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
}
// Encoding // Encoding
ds.addDataSourceProperty("characterEncoding", "utf8"); ds.addDataSourceProperty("characterEncoding", "utf8");
ds.addDataSourceProperty("encoding", "UTF-8"); ds.addDataSourceProperty("encoding", "UTF-8");
@ -140,7 +151,7 @@ public class MySQL extends AbstractSqlDataSource {
ds.addDataSourceProperty("prepStmtCacheSize", "275"); ds.addDataSourceProperty("prepStmtCacheSize", "275");
ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
ConsoleLogger.info("Connection arguments loaded, Hikari ConnectionPool ready!"); logger.info("Connection arguments loaded, Hikari ConnectionPool ready!");
} }
@Override @Override
@ -149,7 +160,7 @@ public class MySQL extends AbstractSqlDataSource {
ds.close(); ds.close();
} }
setConnectionArguments(); setConnectionArguments();
ConsoleLogger.info("Hikari ConnectionPool arguments reloaded!"); logger.info("Hikari ConnectionPool arguments reloaded!");
} }
private Connection getConnection() throws SQLException { private Connection getConnection() throws SQLException {
@ -257,8 +268,13 @@ public class MySQL extends AbstractSqlDataSource {
st.executeUpdate("ALTER TABLE " + tableName st.executeUpdate("ALTER TABLE " + tableName
+ " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);"); + " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);");
} }
if (!col.PLAYER_UUID.isEmpty() && isColumnMissing(md, col.PLAYER_UUID)) {
st.executeUpdate("ALTER TABLE " + tableName
+ " ADD COLUMN " + col.PLAYER_UUID + " VARCHAR(36)");
} }
ConsoleLogger.info("MySQL setup finished"); }
logger.info("MySQL setup finished");
} }
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException { private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {
@ -447,6 +463,8 @@ public class MySQL extends AbstractSqlDataSource {
private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException { private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException {
String salt = col.SALT.isEmpty() ? null : row.getString(col.SALT); String salt = col.SALT.isEmpty() ? null : row.getString(col.SALT);
int group = col.GROUP.isEmpty() ? -1 : row.getInt(col.GROUP); int group = col.GROUP.isEmpty() ? -1 : row.getInt(col.GROUP);
UUID uuid = col.PLAYER_UUID.isEmpty()
? null : UuidUtils.parseUuidSafely(row.getString(col.PLAYER_UUID));
return PlayerAuth.builder() return PlayerAuth.builder()
.name(row.getString(col.NAME)) .name(row.getString(col.NAME))
.realName(row.getString(col.REAL_NAME)) .realName(row.getString(col.REAL_NAME))
@ -464,6 +482,7 @@ public class MySQL extends AbstractSqlDataSource {
.locZ(row.getDouble(col.LASTLOC_Z)) .locZ(row.getDouble(col.LASTLOC_Z))
.locYaw(row.getFloat(col.LASTLOC_YAW)) .locYaw(row.getFloat(col.LASTLOC_YAW))
.locPitch(row.getFloat(col.LASTLOC_PITCH)) .locPitch(row.getFloat(col.LASTLOC_PITCH))
.uuid(uuid)
.build(); .build();
} }
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.datasource; package fr.xephi.authme.datasource;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -13,6 +14,8 @@ import java.sql.Types;
*/ */
final class MySqlMigrater { final class MySqlMigrater {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(MySqlMigrater.class);
private MySqlMigrater() { private MySqlMigrater() {
} }
@ -35,7 +38,7 @@ final class MySqlMigrater {
String sql = String.format("ALTER TABLE %s MODIFY %s VARCHAR(40) CHARACTER SET ascii COLLATE ascii_bin", String sql = String.format("ALTER TABLE %s MODIFY %s VARCHAR(40) CHARACTER SET ascii COLLATE ascii_bin",
tableName, col.LAST_IP); tableName, col.LAST_IP);
st.execute(sql); st.execute(sql);
ConsoleLogger.info("Changed last login column to allow NULL values. Please verify the registration feature " logger.info("Changed last login column to allow NULL values. Please verify the registration feature "
+ "if you are hooking into a forum."); + "if you are hooking into a forum.");
} }
} }
@ -53,7 +56,7 @@ final class MySqlMigrater {
final int columnType; final int columnType;
try (ResultSet rs = metaData.getColumns(null, null, tableName, col.LAST_LOGIN)) { try (ResultSet rs = metaData.getColumns(null, null, tableName, col.LAST_LOGIN)) {
if (!rs.next()) { if (!rs.next()) {
ConsoleLogger.warning("Could not get LAST_LOGIN meta data. This should never happen!"); logger.warning("Could not get LAST_LOGIN meta data. This should never happen!");
return; return;
} }
columnType = rs.getInt("DATA_TYPE"); columnType = rs.getInt("DATA_TYPE");
@ -75,7 +78,7 @@ final class MySqlMigrater {
*/ */
private static void migrateLastLoginColumnFromInt(Statement st, String tableName, Columns col) throws SQLException { private static void migrateLastLoginColumnFromInt(Statement st, String tableName, Columns col) throws SQLException {
// Change from int to bigint // Change from int to bigint
ConsoleLogger.info("Migrating lastlogin column from int to bigint"); logger.info("Migrating lastlogin column from int to bigint");
String sql = String.format("ALTER TABLE %s MODIFY %s BIGINT;", tableName, col.LAST_LOGIN); String sql = String.format("ALTER TABLE %s MODIFY %s BIGINT;", tableName, col.LAST_LOGIN);
st.execute(sql); st.execute(sql);
@ -86,7 +89,7 @@ final class MySqlMigrater {
tableName, col.LAST_LOGIN, col.LAST_LOGIN, col.LAST_LOGIN, rangeStart, col.LAST_LOGIN, rangeEnd); tableName, col.LAST_LOGIN, col.LAST_LOGIN, col.LAST_LOGIN, rangeStart, col.LAST_LOGIN, rangeEnd);
int changedRows = st.executeUpdate(sql); int changedRows = st.executeUpdate(sql);
ConsoleLogger.warning("You may have entries with invalid timestamps. Please check your data " logger.warning("You may have entries with invalid timestamps. Please check your data "
+ "before purging. " + changedRows + " rows were migrated from seconds to milliseconds."); + "before purging. " + changedRows + " rows were migrated from seconds to milliseconds.");
} }
@ -107,7 +110,7 @@ final class MySqlMigrater {
long currentTimestamp = System.currentTimeMillis(); long currentTimestamp = System.currentTimeMillis();
int updatedRows = st.executeUpdate(String.format("UPDATE %s SET %s = %d;", int updatedRows = st.executeUpdate(String.format("UPDATE %s SET %s = %d;",
tableName, col.REGISTRATION_DATE, currentTimestamp)); tableName, col.REGISTRATION_DATE, currentTimestamp));
ConsoleLogger.info("Created column '" + col.REGISTRATION_DATE + "' and set the current timestamp, " logger.info("Created column '" + col.REGISTRATION_DATE + "' and set the current timestamp, "
+ currentTimestamp + ", to all " + updatedRows + " rows"); + currentTimestamp + ", to all " + updatedRows + " rows");
} }
} }

View File

@ -8,6 +8,7 @@ import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler; import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension; import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory; import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
@ -32,6 +33,8 @@ import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
*/ */
public class PostgreSqlDataSource extends AbstractSqlDataSource { public class PostgreSqlDataSource extends AbstractSqlDataSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PostgreSqlDataSource.class);
private String host; private String host;
private String port; private String port;
private String username; private String username;
@ -53,14 +56,14 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
this.setConnectionArguments(); this.setConnectionArguments();
} catch (RuntimeException e) { } catch (RuntimeException e) {
if (e instanceof IllegalArgumentException) { if (e instanceof IllegalArgumentException) {
ConsoleLogger.warning("Invalid database arguments! Please check your configuration!"); logger.warning("Invalid database arguments! Please check your configuration!");
ConsoleLogger.warning("If this error persists, please report it to the developer!"); logger.warning("If this error persists, please report it to the developer!");
} }
if (e instanceof PoolInitializationException) { if (e instanceof PoolInitializationException) {
ConsoleLogger.warning("Can't initialize database connection! Please check your configuration!"); logger.warning("Can't initialize database connection! Please check your configuration!");
ConsoleLogger.warning("If this error persists, please report it to the developer!"); logger.warning("If this error persists, please report it to the developer!");
} }
ConsoleLogger.warning("Can't use the Hikari Connection Pool! Please, report this error to the developer!"); logger.warning("Can't use the Hikari Connection Pool! Please, report this error to the developer!");
throw e; throw e;
} }
@ -69,8 +72,8 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
checkTablesAndColumns(); checkTablesAndColumns();
} catch (SQLException e) { } catch (SQLException e) {
closeConnection(); closeConnection();
ConsoleLogger.logException("Can't initialize the PostgreSQL database:", e); logger.logException("Can't initialize the PostgreSQL database:", e);
ConsoleLogger.warning("Please check your database settings in the config.yml file!"); logger.warning("Please check your database settings in the config.yml file!");
throw e; throw e;
} }
} }
@ -129,7 +132,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
ds.addDataSourceProperty("cachePrepStmts", "true"); ds.addDataSourceProperty("cachePrepStmts", "true");
ds.addDataSourceProperty("preparedStatementCacheQueries", "275"); ds.addDataSourceProperty("preparedStatementCacheQueries", "275");
ConsoleLogger.info("Connection arguments loaded, Hikari ConnectionPool ready!"); logger.info("Connection arguments loaded, Hikari ConnectionPool ready!");
} }
@Override @Override
@ -138,7 +141,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
ds.close(); ds.close();
} }
setConnectionArguments(); setConnectionArguments();
ConsoleLogger.info("Hikari ConnectionPool arguments reloaded!"); logger.info("Hikari ConnectionPool arguments reloaded!");
} }
private Connection getConnection() throws SQLException { private Connection getConnection() throws SQLException {
@ -241,8 +244,13 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
st.executeUpdate("ALTER TABLE " + tableName st.executeUpdate("ALTER TABLE " + tableName
+ " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);"); + " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);");
} }
if (!col.PLAYER_UUID.isEmpty() && isColumnMissing(md, col.PLAYER_UUID)) {
st.executeUpdate("ALTER TABLE " + tableName
+ " ADD COLUMN " + col.PLAYER_UUID + " VARCHAR(36)");
} }
ConsoleLogger.info("PostgreSQL setup finished"); }
logger.info("PostgreSQL setup finished");
} }
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException { private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {

View File

@ -4,6 +4,7 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler; import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
@ -30,6 +31,7 @@ import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
@SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore @SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore
public class SQLite extends AbstractSqlDataSource { public class SQLite extends AbstractSqlDataSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(SQLite.class);
private final Settings settings; private final Settings settings;
private final File dataFolder; private final File dataFolder;
private final String database; private final String database;
@ -57,7 +59,7 @@ public class SQLite extends AbstractSqlDataSource {
this.setup(); this.setup();
this.migrateIfNeeded(); this.migrateIfNeeded();
} catch (Exception ex) { } catch (Exception ex) {
ConsoleLogger.logException("Error during SQLite initialization:", ex); logger.logException("Error during SQLite initialization:", ex);
throw ex; throw ex;
} }
} }
@ -85,7 +87,7 @@ public class SQLite extends AbstractSqlDataSource {
throw new IllegalStateException("Failed to load SQLite JDBC class", e); throw new IllegalStateException("Failed to load SQLite JDBC class", e);
} }
ConsoleLogger.debug("SQLite driver loaded"); logger.debug("SQLite driver loaded");
this.con = DriverManager.getConnection("jdbc:sqlite:plugins/AuthMe/" + database + ".db"); this.con = DriverManager.getConnection("jdbc:sqlite:plugins/AuthMe/" + database + ".db");
this.columnsHandler = AuthMeColumnsHandler.createForSqlite(con, settings); this.columnsHandler = AuthMeColumnsHandler.createForSqlite(con, settings);
} }
@ -182,8 +184,13 @@ public class SQLite extends AbstractSqlDataSource {
st.executeUpdate("ALTER TABLE " + tableName st.executeUpdate("ALTER TABLE " + tableName
+ " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);"); + " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);");
} }
if (!col.PLAYER_UUID.isEmpty() && isColumnMissing(md, col.PLAYER_UUID)) {
st.executeUpdate("ALTER TABLE " + tableName
+ " ADD COLUMN " + col.PLAYER_UUID + " VARCHAR(36)");
} }
ConsoleLogger.info("SQLite Setup finished"); }
logger.info("SQLite Setup finished");
} }
/** /**
@ -214,7 +221,7 @@ public class SQLite extends AbstractSqlDataSource {
this.setup(); this.setup();
this.migrateIfNeeded(); this.migrateIfNeeded();
} catch (SQLException ex) { } catch (SQLException ex) {
ConsoleLogger.logException("Error while reloading SQLite:", ex); logger.logException("Error while reloading SQLite:", ex);
} }
} }
@ -393,7 +400,7 @@ public class SQLite extends AbstractSqlDataSource {
long currentTimestamp = System.currentTimeMillis(); long currentTimestamp = System.currentTimeMillis();
int updatedRows = st.executeUpdate(String.format("UPDATE %s SET %s = %d;", int updatedRows = st.executeUpdate(String.format("UPDATE %s SET %s = %d;",
tableName, col.REGISTRATION_DATE, currentTimestamp)); tableName, col.REGISTRATION_DATE, currentTimestamp));
ConsoleLogger.info("Created column '" + col.REGISTRATION_DATE + "' and set the current timestamp, " logger.info("Created column '" + col.REGISTRATION_DATE + "' and set the current timestamp, "
+ currentTimestamp + ", to all " + updatedRows + " rows"); + currentTimestamp + ", to all " + updatedRows + " rows");
} }

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.datasource;
import com.google.common.io.Files; import com.google.common.io.Files;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
@ -19,6 +20,7 @@ import java.sql.Statement;
*/ */
class SqLiteMigrater { class SqLiteMigrater {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(SqLiteMigrater.class);
private final File dataFolder; private final File dataFolder;
private final String databaseName; private final String databaseName;
private final String tableName; private final String tableName;
@ -53,13 +55,13 @@ class SqLiteMigrater {
* @param sqLite the instance to migrate * @param sqLite the instance to migrate
*/ */
void performMigration(SQLite sqLite) throws SQLException { void performMigration(SQLite sqLite) throws SQLException {
ConsoleLogger.warning("YOUR SQLITE DATABASE NEEDS MIGRATING! DO NOT TURN OFF YOUR SERVER"); logger.warning("YOUR SQLITE DATABASE NEEDS MIGRATING! DO NOT TURN OFF YOUR SERVER");
String backupName = createBackup(); String backupName = createBackup();
ConsoleLogger.info("Made a backup of your database at 'backups/" + backupName + "'"); logger.info("Made a backup of your database at 'backups/" + backupName + "'");
recreateDatabaseWithNewDefinitions(sqLite); recreateDatabaseWithNewDefinitions(sqLite);
ConsoleLogger.info("SQLite database migrated successfully"); logger.info("SQLite database migrated successfully");
} }
private String createBackup() { private String createBackup() {
@ -104,7 +106,7 @@ class SqLiteMigrater {
+ " CASE WHEN $email = 'your@email.com' THEN NULL ELSE $email END, $isLogged" + " CASE WHEN $email = 'your@email.com' THEN NULL ELSE $email END, $isLogged"
+ " FROM " + tempTable + ";"; + " FROM " + tempTable + ";";
int insertedEntries = st.executeUpdate(replaceColumnVariables(copySql)); int insertedEntries = st.executeUpdate(replaceColumnVariables(copySql));
ConsoleLogger.info("Copied over " + insertedEntries + " from the old table to the new one"); logger.info("Copied over " + insertedEntries + " from the old table to the new one");
st.execute("DROP TABLE " + tempTable + ";"); st.execute("DROP TABLE " + tempTable + ";");
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.datasource; package fr.xephi.authme.datasource;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -11,6 +12,8 @@ import java.sql.SQLException;
*/ */
public final class SqlDataSourceUtils { public final class SqlDataSourceUtils {
private static final ConsoleLogger logger = ConsoleLoggerFactory.get(SqlDataSourceUtils.class);
private SqlDataSourceUtils() { private SqlDataSourceUtils() {
} }
@ -20,7 +23,7 @@ public final class SqlDataSourceUtils {
* @param e the exception to log * @param e the exception to log
*/ */
public static void logSqlException(SQLException e) { public static void logSqlException(SQLException e) {
ConsoleLogger.logException("Error during SQL operation:", e); logger.logException("Error during SQL operation:", e);
} }
/** /**
@ -58,7 +61,7 @@ public final class SqlDataSourceUtils {
if (nullableCode == DatabaseMetaData.columnNoNulls) { if (nullableCode == DatabaseMetaData.columnNoNulls) {
return true; return true;
} else if (nullableCode == DatabaseMetaData.columnNullableUnknown) { } else if (nullableCode == DatabaseMetaData.columnNullableUnknown) {
ConsoleLogger.warning("Unknown nullable status for column '" + columnName + "'"); logger.warning("Unknown nullable status for column '" + columnName + "'");
} }
} }
return false; return false;

View File

@ -3,6 +3,8 @@ package fr.xephi.authme.datasource.columnshandler;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import java.util.UUID;
import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.ColumnOptions.DEFAULT_FOR_NULL; import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.ColumnOptions.DEFAULT_FOR_NULL;
import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.ColumnOptions.OPTIONAL; import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.ColumnOptions.OPTIONAL;
import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.createDouble; import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.createDouble;
@ -46,6 +48,11 @@ public final class AuthMeColumns {
public static final PlayerAuthColumn<Long> REGISTRATION_DATE = createLong( public static final PlayerAuthColumn<Long> REGISTRATION_DATE = createLong(
DatabaseSettings.MYSQL_COL_REGISTER_DATE, PlayerAuth::getRegistrationDate); DatabaseSettings.MYSQL_COL_REGISTER_DATE, PlayerAuth::getRegistrationDate);
public static final PlayerAuthColumn<String> UUID = createString(
DatabaseSettings.MYSQL_COL_PLAYER_UUID,
auth -> ( auth.getUuid() == null ? null : auth.getUuid().toString()),
OPTIONAL);
// -------- // --------
// Location columns // Location columns
// -------- // --------
@ -76,7 +83,6 @@ public final class AuthMeColumns {
public static final DataSourceColumn<Integer> HAS_SESSION = createInteger( public static final DataSourceColumn<Integer> HAS_SESSION = createInteger(
DatabaseSettings.MYSQL_COL_HASSESSION); DatabaseSettings.MYSQL_COL_HASSESSION);
private AuthMeColumns() { private AuthMeColumns() {
} }
} }

View File

@ -2,8 +2,8 @@ package fr.xephi.authme.datasource.columnshandler;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Context for resolving the properties of {@link AuthMeColumns} entries. * Context for resolving the properties of {@link AuthMeColumns} entries.
@ -11,7 +11,7 @@ import java.util.Map;
public class ColumnContext { public class ColumnContext {
private final Settings settings; private final Settings settings;
private final Map<DataSourceColumn<?>, String> columnNames = new HashMap<>(); private final Map<DataSourceColumn<?>, String> columnNames = new ConcurrentHashMap<>();
private final boolean hasDefaultSupport; private final boolean hasDefaultSupport;
/** /**

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
@ -18,8 +19,10 @@ import static fr.xephi.authme.util.Utils.logAndSendMessage;
*/ */
public abstract class AbstractDataSourceConverter<S extends DataSource> implements Converter { public abstract class AbstractDataSourceConverter<S extends DataSource> implements Converter {
private DataSource destination; private final ConsoleLogger logger = ConsoleLoggerFactory.get(MySqlToSqlite.class);
private DataSourceType destinationType;
private final DataSource destination;
private final DataSourceType destinationType;
/** /**
* Constructor. * Constructor.
@ -51,7 +54,7 @@ public abstract class AbstractDataSourceConverter<S extends DataSource> implemen
source = getSource(); source = getSource();
} catch (Exception e) { } catch (Exception e) {
logAndSendMessage(sender, "The data source to convert from could not be initialized"); logAndSendMessage(sender, "The data source to convert from could not be initialized");
ConsoleLogger.logException("Could not initialize source:", e); logger.logException("Could not initialize source:", e);
return; return;
} }
@ -60,7 +63,6 @@ public abstract class AbstractDataSourceConverter<S extends DataSource> implemen
if (destination.isAuthAvailable(auth.getNickname())) { if (destination.isAuthAvailable(auth.getNickname())) {
skippedPlayers.add(auth.getNickname()); skippedPlayers.add(auth.getNickname());
} else { } else {
adaptPlayerAuth(auth);
destination.saveAuth(auth); destination.saveAuth(auth);
destination.updateSession(auth); destination.updateSession(auth);
destination.updateQuitLoc(auth); destination.updateQuitLoc(auth);
@ -75,15 +77,6 @@ public abstract class AbstractDataSourceConverter<S extends DataSource> implemen
+ " to " + destinationType); + " to " + destinationType);
} }
/**
* Adapts the PlayerAuth from the source before it is saved in the destination.
*
* @param auth the auth from the source
*/
protected void adaptPlayerAuth(PlayerAuth auth) {
// noop
}
/** /**
* @return the data source to convert from * @return the data source to convert from
* @throws Exception during initialization of source * @throws Exception during initialization of source

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ConverterSettings; import fr.xephi.authme.settings.properties.ConverterSettings;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -19,6 +20,8 @@ import java.io.IOException;
*/ */
public class CrazyLoginConverter implements Converter { public class CrazyLoginConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(CrazyLoginConverter.class);
private final DataSource database; private final DataSource database;
private final Settings settings; private final Settings settings;
private final File dataFolder; private final File dataFolder;
@ -46,10 +49,10 @@ public class CrazyLoginConverter implements Converter {
migrateAccount(line); migrateAccount(line);
} }
} }
ConsoleLogger.info("CrazyLogin database has been imported correctly"); logger.info("CrazyLogin database has been imported correctly");
} catch (IOException ex) { } catch (IOException ex) {
ConsoleLogger.warning("Can't open the crazylogin database file! Does it exist?"); logger.warning("Can't open the crazylogin database file! Does it exist?");
ConsoleLogger.logException("Encountered", ex); logger.logException("Encountered", ex);
} }
} }

View File

@ -5,8 +5,10 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ConverterSettings; import fr.xephi.authme.settings.properties.ConverterSettings;
import fr.xephi.authme.util.UuidUtils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import javax.inject.Inject; import javax.inject.Inject;
@ -21,6 +23,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import static fr.xephi.authme.util.Utils.logAndSendMessage; import static fr.xephi.authme.util.Utils.logAndSendMessage;
@ -29,6 +32,7 @@ import static fr.xephi.authme.util.Utils.logAndSendMessage;
*/ */
public class LoginSecurityConverter implements Converter { public class LoginSecurityConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LoginSecurityConverter.class);
private final File dataFolder; private final File dataFolder;
private final DataSource dataSource; private final DataSource dataSource;
@ -58,7 +62,7 @@ public class LoginSecurityConverter implements Converter {
} }
} catch (SQLException e) { } catch (SQLException e) {
sender.sendMessage("Failed to convert from SQLite. Please see the log for more info"); sender.sendMessage("Failed to convert from SQLite. Please see the log for more info");
ConsoleLogger.logException("Could not fetch or migrate data:", e); logger.logException("Could not fetch or migrate data:", e);
} }
} }
@ -119,6 +123,7 @@ public class LoginSecurityConverter implements Converter {
.map(Timestamp::getTime).orElse(null); .map(Timestamp::getTime).orElse(null);
long regDate = Optional.ofNullable(resultSet.getDate("registration_date")) long regDate = Optional.ofNullable(resultSet.getDate("registration_date"))
.map(Date::getTime).orElse(System.currentTimeMillis()); .map(Date::getTime).orElse(System.currentTimeMillis());
UUID uuid = UuidUtils.parseUuidSafely(resultSet.getString("unique_user_id"));
return PlayerAuth.builder() return PlayerAuth.builder()
.name(name) .name(name)
.realName(name) .realName(name)
@ -132,6 +137,7 @@ public class LoginSecurityConverter implements Converter {
.locWorld(resultSet.getString("world")) .locWorld(resultSet.getString("world"))
.locYaw(resultSet.getFloat("yaw")) .locYaw(resultSet.getFloat("yaw"))
.locPitch(resultSet.getFloat("pitch")) .locPitch(resultSet.getFloat("pitch"))
.uuid(uuid)
.build(); .build();
} }
@ -185,7 +191,7 @@ public class LoginSecurityConverter implements Converter {
return DriverManager.getConnection( return DriverManager.getConnection(
"jdbc:sqlite:" + path, "trump", "donald"); "jdbc:sqlite:" + path, "trump", "donald");
} catch (SQLException e) { } catch (SQLException e) {
ConsoleLogger.logException("Could not connect to SQLite database", e); logger.logException("Could not connect to SQLite database", e);
return null; return null;
} }
} }
@ -195,7 +201,7 @@ public class LoginSecurityConverter implements Converter {
return DriverManager.getConnection( return DriverManager.getConnection(
"jdbc:mysql://" + mySqlHost + "/" + mySqlDatabase, mySqlUser, mySqlPassword); "jdbc:mysql://" + mySqlHost + "/" + mySqlDatabase, mySqlUser, mySqlPassword);
} catch (SQLException e) { } catch (SQLException e) {
ConsoleLogger.logException("Could not connect to SQLite database", e); logger.logException("Could not connect to SQLite database", e);
return null; return null;
} }
} }

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
@ -25,6 +26,7 @@ import java.util.Map.Entry;
*/ */
public class RakamakConverter implements Converter { public class RakamakConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RakamakConverter.class);
private final DataSource database; private final DataSource database;
private final Settings settings; private final Settings settings;
private final File pluginFolder; private final File pluginFolder;
@ -88,7 +90,7 @@ public class RakamakConverter implements Converter {
} }
Utils.logAndSendMessage(sender, "Rakamak database has been imported successfully"); Utils.logAndSendMessage(sender, "Rakamak database has been imported successfully");
} catch (IOException ex) { } catch (IOException ex) {
ConsoleLogger.logException("Can't open the rakamak database file! Does it exist?", ex); logger.logException("Can't open the rakamak database file! Does it exist?", ex);
} }
} }
} }

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@ -18,6 +19,9 @@ public class RoyalAuthConverter implements Converter {
private static final String LAST_LOGIN_PATH = "timestamps.quit"; private static final String LAST_LOGIN_PATH = "timestamps.quit";
private static final String PASSWORD_PATH = "login.password"; private static final String PASSWORD_PATH = "login.password";
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RoyalAuthConverter.class);
private final AuthMe plugin; private final AuthMe plugin;
private final DataSource dataSource; private final DataSource dataSource;
@ -48,7 +52,7 @@ public class RoyalAuthConverter implements Converter {
dataSource.saveAuth(auth); dataSource.saveAuth(auth);
dataSource.updateSession(auth); dataSource.updateSession(auth);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Error while trying to import " + player.getName() + " RoyalAuth data", e); logger.logException("Error while trying to import " + player.getName() + " RoyalAuth data", e);
} }
} }
} }

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -18,6 +19,7 @@ import static fr.xephi.authme.util.FileUtils.makePath;
public class VAuthConverter implements Converter { public class VAuthConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(VAuthConverter.class);
private final DataSource dataSource; private final DataSource dataSource;
private final File vAuthPasswordsFile; private final File vAuthPasswordsFile;
@ -58,7 +60,7 @@ public class VAuthConverter implements Converter {
dataSource.saveAuth(auth); dataSource.saveAuth(auth);
} }
} catch (IOException e) { } catch (IOException e) {
ConsoleLogger.logException("Error while trying to import some vAuth data", e); logger.logException("Error while trying to import some vAuth data", e);
} }
} }

View File

@ -9,6 +9,7 @@ import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.datasource.PostgreSqlDataSource; import fr.xephi.authme.datasource.PostgreSqlDataSource;
import fr.xephi.authme.datasource.SQLite; import fr.xephi.authme.datasource.SQLite;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory; import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
@ -16,7 +17,6 @@ import fr.xephi.authme.settings.properties.DatabaseSettings;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider; import javax.inject.Provider;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
/** /**
@ -26,6 +26,8 @@ public class DataSourceProvider implements Provider<DataSource> {
private static final int SQLITE_MAX_SIZE = 4000; private static final int SQLITE_MAX_SIZE = 4000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(DataSourceProvider.class);
@Inject @Inject
@DataFolder @DataFolder
private File dataFolder; private File dataFolder;
@ -46,7 +48,7 @@ public class DataSourceProvider implements Provider<DataSource> {
try { try {
return createDataSource(); return createDataSource();
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Could not create data source:", e); logger.logException("Could not create data source:", e);
throw new IllegalStateException("Error during initialization of data source", e); throw new IllegalStateException("Error during initialization of data source", e);
} }
} }
@ -54,11 +56,10 @@ public class DataSourceProvider implements Provider<DataSource> {
/** /**
* Sets up the data source. * Sets up the data source.
* *
* @return the constructed datasource * @return the constructed data source
* @throws SQLException when initialization of a SQL datasource failed * @throws SQLException when initialization of a SQL data source failed
* @throws IOException if flat file cannot be read
*/ */
private DataSource createDataSource() throws SQLException, IOException { private DataSource createDataSource() throws SQLException {
DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND); DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND);
DataSource dataSource; DataSource dataSource;
switch (dataSourceType) { switch (dataSourceType) {
@ -88,7 +89,7 @@ public class DataSourceProvider implements Provider<DataSource> {
bukkitService.runTaskAsynchronously(() -> { bukkitService.runTaskAsynchronously(() -> {
int accounts = dataSource.getAccountsRegistered(); int accounts = dataSource.getAccountsRegistered();
if (accounts >= SQLITE_MAX_SIZE) { if (accounts >= SQLITE_MAX_SIZE) {
ConsoleLogger.warning("YOU'RE USING THE SQLITE DATABASE WITH " logger.warning("YOU'RE USING THE SQLITE DATABASE WITH "
+ accounts + "+ ACCOUNTS; FOR BETTER PERFORMANCE, PLEASE UPGRADE TO MYSQL!!"); + accounts + "+ ACCOUNTS; FOR BETTER PERFORMANCE, PLEASE UPGRADE TO MYSQL!!");
} }
}); });

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.initialization;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.output.ConsoleFilter; import fr.xephi.authme.output.ConsoleFilter;
@ -29,6 +30,8 @@ import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
*/ */
public class OnStartupTasks { public class OnStartupTasks {
private static ConsoleLogger consoleLogger = ConsoleLoggerFactory.get(OnStartupTasks.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@Inject @Inject
@ -61,7 +64,6 @@ public class OnStartupTasks {
/** /**
* Sets up the console filter if enabled. * Sets up the console filter if enabled.
* *
* @param settings the settings
* @param logger the plugin logger * @param logger the plugin logger
*/ */
public void setupConsoleFilter(Settings settings, Logger logger) { public void setupConsoleFilter(Settings settings, Logger logger) {
@ -71,7 +73,7 @@ public class OnStartupTasks {
setLog4JFilter(); setLog4JFilter();
} catch (ClassNotFoundException | NoClassDefFoundError e) { } catch (ClassNotFoundException | NoClassDefFoundError e) {
// log4j is not available // log4j is not available
ConsoleLogger.info("You're using Minecraft 1.6.x or older, Log4J support will be disabled"); consoleLogger.info("You're using Minecraft 1.6.x or older, Log4J support will be disabled");
ConsoleFilter filter = new ConsoleFilter(logFilterService); ConsoleFilter filter = new ConsoleFilter(logFilterService);
logger.setFilter(filter); logger.setFilter(filter);
Bukkit.getLogger().setFilter(filter); Bukkit.getLogger().setFilter(filter);

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.listener; package fr.xephi.authme.listener;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
@ -22,18 +23,21 @@ import java.lang.reflect.Method;
public class EntityListener implements Listener { public class EntityListener implements Listener {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EntityListener.class);
private final ListenerService listenerService; private final ListenerService listenerService;
private Method getShooter; private Method getShooter;
private boolean shooterIsLivingEntity; private boolean shooterIsLivingEntity;
@Inject @Inject
EntityListener(ListenerService listenerService) { EntityListener(ListenerService listenerService) {
this.listenerService = listenerService; this.listenerService = listenerService;
try { try {
getShooter = Projectile.class.getDeclaredMethod("getShooter"); getShooter = Projectile.class.getDeclaredMethod("getShooter");
shooterIsLivingEntity = getShooter.getReturnType() == LivingEntity.class; shooterIsLivingEntity = getShooter.getReturnType() == LivingEntity.class;
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
ConsoleLogger.logException("Cannot load getShooter() method on Projectile class", e); logger.logException("Cannot load getShooter() method on Projectile class", e);
} }
} }
@ -56,7 +60,7 @@ public class EntityListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onEntityTarget(EntityTargetEvent event) { public void onEntityTarget(EntityTargetEvent event) {
if (listenerService.shouldCancelEvent(event)) { if (listenerService.shouldCancelEvent(event.getTarget())) {
event.setTarget(null); event.setTarget(null);
event.setCancelled(true); event.setCancelled(true);
} }
@ -107,7 +111,7 @@ public class EntityListener implements Listener {
} }
shooterRaw = getShooter.invoke(projectile); shooterRaw = getShooter.invoke(projectile);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
ConsoleLogger.logException("Error getting shooter", e); logger.logException("Error getting shooter", e);
} }
} else { } else {
shooterRaw = projectile.getShooter(); shooterRaw = projectile.getShooter();

View File

@ -52,12 +52,12 @@ class ListenerService implements SettingsDependent {
* @return true if the associated event should be canceled, false otherwise * @return true if the associated event should be canceled, false otherwise
*/ */
public boolean shouldCancelEvent(Entity entity) { public boolean shouldCancelEvent(Entity entity) {
if (entity == null || !(entity instanceof Player)) { if (entity instanceof Player) {
return false;
}
Player player = (Player) entity; Player player = (Player) entity;
return shouldCancelEvent(player); return shouldCancelEvent(player);
} }
return false;
}
/** /**
* Returns whether an event should be canceled (for unauthenticated, non-NPC players). * Returns whether an event should be canceled (for unauthenticated, non-NPC players).

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
@ -31,6 +32,8 @@ import java.util.regex.Pattern;
*/ */
public class OnJoinVerifier implements Reloadable { public class OnJoinVerifier implements Reloadable {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(OnJoinVerifier.class);
@Inject @Inject
private Settings settings; private Settings settings;
@Inject @Inject
@ -128,7 +131,7 @@ public class OnJoinVerifier implements Reloadable {
} }
// Server is full and player is VIP; attempt to kick a non-VIP player to make room // Server is full and player is VIP; attempt to kick a non-VIP player to make room
Collection<? extends Player> onlinePlayers = bukkitService.getOnlinePlayers(); Collection<Player> onlinePlayers = bukkitService.getOnlinePlayers();
if (onlinePlayers.size() < server.getMaxPlayers()) { if (onlinePlayers.size() < server.getMaxPlayers()) {
event.allow(); event.allow();
return false; return false;
@ -139,7 +142,7 @@ public class OnJoinVerifier implements Reloadable {
event.allow(); event.allow();
return false; return false;
} else { } else {
ConsoleLogger.info("VIP player " + player.getName() + " tried to join, but the server was full"); logger.info("VIP player " + player.getName() + " tried to join, but the server was full");
event.setKickMessage(messages.retrieveSingle(player, MessageKey.KICK_FULL_SERVER)); event.setKickMessage(messages.retrieveSingle(player, MessageKey.KICK_FULL_SERVER));
return true; return true;
} }
@ -207,7 +210,7 @@ public class OnJoinVerifier implements Reloadable {
* *
* @return the player to kick, or null if none applicable * @return the player to kick, or null if none applicable
*/ */
private Player generateKickPlayer(Collection<? extends Player> onlinePlayers) { private Player generateKickPlayer(Collection<Player> onlinePlayers) {
for (Player player : onlinePlayers) { for (Player player : onlinePlayers) {
if (!permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)) { if (!permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)) {
return player; return player;

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.QuickCommandsProtectionManager; import fr.xephi.authme.data.QuickCommandsProtectionManager;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
@ -35,8 +36,27 @@ import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.*; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerEditBookEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.inventory.InventoryView;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.HashSet; import java.util.HashSet;
@ -50,6 +70,8 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAU
*/ */
public class PlayerListener implements Listener { public class PlayerListener implements Listener {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PlayerListener.class);
@Inject @Inject
private Settings settings; private Settings settings;
@Inject @Inject
@ -270,7 +292,7 @@ public class PlayerListener implements Listener {
try { try {
permissionsManager.loadUserData(event.getUniqueId()); permissionsManager.loadUserData(event.getUniqueId());
} catch (PermissionLoadUserException e) { } catch (PermissionLoadUserException e) {
ConsoleLogger.logException("Unable to load the permission data of user " + name, e); logger.logException("Unable to load the permission data of user " + name, e);
} }
// getAddress() sometimes returning null if not yet resolved // getAddress() sometimes returning null if not yet resolved
@ -391,12 +413,12 @@ public class PlayerListener implements Listener {
} }
} }
private boolean isInventoryWhitelisted(Inventory inventory) { private boolean isInventoryWhitelisted(InventoryView inventory) {
if (inventory == null) { if (inventory == null) {
return false; return false;
} }
Set<String> whitelist = settings.getProperty(RestrictionSettings.UNRESTRICTED_INVENTORIES); Set<String> whitelist = settings.getProperty(RestrictionSettings.UNRESTRICTED_INVENTORIES);
return whitelist.contains(ChatColor.stripColor(inventory.getName())); return whitelist.contains(ChatColor.stripColor(inventory.getTitle()));
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
@ -404,7 +426,7 @@ public class PlayerListener implements Listener {
final HumanEntity player = event.getPlayer(); final HumanEntity player = event.getPlayer();
if (listenerService.shouldCancelEvent(player) if (listenerService.shouldCancelEvent(player)
&& !isInventoryWhitelisted(event.getInventory())) { && !isInventoryWhitelisted(event.getView())) {
event.setCancelled(true); event.setCancelled(true);
/* /*
@ -418,7 +440,7 @@ public class PlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInventoryClick(InventoryClickEvent event) { public void onPlayerInventoryClick(InventoryClickEvent event) {
if (listenerService.shouldCancelEvent(event.getWhoClicked()) if (listenerService.shouldCancelEvent(event.getWhoClicked())
&& !isInventoryWhitelisted(event.getClickedInventory())) { && !isInventoryWhitelisted(event.getView())) {
event.setCancelled(true); event.setCancelled(true);
} }
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.listener; package fr.xephi.authme.listener;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.listener.protocollib.ProtocolLibService; import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.service.PluginHookService; import fr.xephi.authme.service.PluginHookService;
@ -14,9 +15,12 @@ import org.bukkit.event.server.PluginEnableEvent;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* Listener for server events.
*/ */
public class ServerListener implements Listener { public class ServerListener implements Listener {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ServerListener.class);
@Inject @Inject
private PluginHookService pluginHookService; private PluginHookService pluginHookService;
@Inject @Inject
@ -40,20 +44,20 @@ public class ServerListener implements Listener {
if ("Essentials".equalsIgnoreCase(pluginName)) { if ("Essentials".equalsIgnoreCase(pluginName)) {
pluginHookService.unhookEssentials(); pluginHookService.unhookEssentials();
ConsoleLogger.info("Essentials has been disabled: unhooking"); logger.info("Essentials has been disabled: unhooking");
} else if ("CMI".equalsIgnoreCase(pluginName)) { } else if ("CMI".equalsIgnoreCase(pluginName)) {
pluginHookService.unhookCmi(); pluginHookService.unhookCmi();
spawnLoader.unloadCmiSpawn(); spawnLoader.unloadCmiSpawn();
ConsoleLogger.info("CMI has been disabled: unhooking"); logger.info("CMI has been disabled: unhooking");
} else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) { } else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) {
pluginHookService.unhookMultiverse(); pluginHookService.unhookMultiverse();
ConsoleLogger.info("Multiverse-Core has been disabled: unhooking"); logger.info("Multiverse-Core has been disabled: unhooking");
} else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) { } else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) {
spawnLoader.unloadEssentialsSpawn(); spawnLoader.unloadEssentialsSpawn();
ConsoleLogger.info("EssentialsSpawn has been disabled: unhooking"); logger.info("EssentialsSpawn has been disabled: unhooking");
} else if ("ProtocolLib".equalsIgnoreCase(pluginName)) { } else if ("ProtocolLib".equalsIgnoreCase(pluginName)) {
protocolLibService.disable(); protocolLibService.disable();
ConsoleLogger.warning("ProtocolLib has been disabled, unhooking packet adapters!"); logger.warning("ProtocolLib has been disabled, unhooking packet adapters!");
} }
} }

View File

@ -27,6 +27,9 @@ import com.comphenix.protocol.reflect.StructureModifier;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -45,11 +48,14 @@ class InventoryPacketAdapter extends PacketAdapter {
private static final int MAIN_SIZE = 27; private static final int MAIN_SIZE = 27;
private static final int HOTBAR_SIZE = 9; private static final int HOTBAR_SIZE = 9;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(InventoryPacketAdapter.class);
private final PlayerCache playerCache; private final PlayerCache playerCache;
private final DataSource dataSource;
InventoryPacketAdapter(AuthMe plugin, PlayerCache playerCache) { InventoryPacketAdapter(AuthMe plugin, PlayerCache playerCache, DataSource dataSource) {
super(plugin, PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS); super(plugin, PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS);
this.playerCache = playerCache; this.playerCache = playerCache;
this.dataSource = dataSource;
} }
@Override @Override
@ -57,14 +63,22 @@ class InventoryPacketAdapter extends PacketAdapter {
Player player = packetEvent.getPlayer(); Player player = packetEvent.getPlayer();
PacketContainer packet = packetEvent.getPacket(); PacketContainer packet = packetEvent.getPacket();
byte windowId = packet.getIntegers().read(0).byteValue(); int windowId = packet.getIntegers().read(0);
if (windowId == PLAYER_INVENTORY && !playerCache.isAuthenticated(player.getName())) { if (windowId == PLAYER_INVENTORY && shouldHideInventory(player.getName())) {
packetEvent.setCancelled(true); packetEvent.setCancelled(true);
} }
} }
public void register() { public void register(BukkitService bukkitService) {
ProtocolLibrary.getProtocolManager().addPacketListener(this); ProtocolLibrary.getProtocolManager().addPacketListener(this);
bukkitService.getOnlinePlayers().stream()
.filter(player -> shouldHideInventory(player.getName()))
.forEach(this::sendBlankInventoryPacket);
}
private boolean shouldHideInventory(String playerName) {
return !playerCache.isAuthenticated(playerName) && dataSource.isAuthAvailable(playerName);
} }
public void unregister() { public void unregister() {
@ -93,7 +107,7 @@ class InventoryPacketAdapter extends PacketAdapter {
try { try {
protocolManager.sendServerPacket(player, inventoryPacket, false); protocolManager.sendServerPacket(player, inventoryPacket, false);
} catch (InvocationTargetException invocationExc) { } catch (InvocationTargetException invocationExc) {
ConsoleLogger.logException("Error during sending blank inventory", invocationExc); logger.logException("Error during sending blank inventory", invocationExc);
} }
} }
} }

View File

@ -4,7 +4,9 @@ import ch.jalu.injector.annotations.NoFieldScan;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
@ -15,6 +17,8 @@ import javax.inject.Inject;
@NoFieldScan @NoFieldScan
public class ProtocolLibService implements SettingsDependent { public class ProtocolLibService implements SettingsDependent {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProtocolLibService.class);
/* Packet Adapters */ /* Packet Adapters */
private InventoryPacketAdapter inventoryPacketAdapter; private InventoryPacketAdapter inventoryPacketAdapter;
private TabCompletePacketAdapter tabCompletePacketAdapter; private TabCompletePacketAdapter tabCompletePacketAdapter;
@ -25,15 +29,18 @@ public class ProtocolLibService implements SettingsDependent {
/* Service */ /* Service */
private boolean isEnabled; private boolean isEnabled;
private AuthMe plugin; private final AuthMe plugin;
private BukkitService bukkitService; private final BukkitService bukkitService;
private PlayerCache playerCache; private final PlayerCache playerCache;
private final DataSource dataSource;
@Inject @Inject
ProtocolLibService(AuthMe plugin, Settings settings, BukkitService bukkitService, PlayerCache playerCache) { ProtocolLibService(AuthMe plugin, Settings settings, BukkitService bukkitService, PlayerCache playerCache,
DataSource dataSource) {
this.plugin = plugin; this.plugin = plugin;
this.bukkitService = bukkitService; this.bukkitService = bukkitService;
this.playerCache = playerCache; this.playerCache = playerCache;
this.dataSource = dataSource;
reload(settings); reload(settings);
} }
@ -44,11 +51,11 @@ public class ProtocolLibService implements SettingsDependent {
// Check if ProtocolLib is enabled on the server. // Check if ProtocolLib is enabled on the server.
if (!plugin.getServer().getPluginManager().isPluginEnabled("ProtocolLib")) { if (!plugin.getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
if (protectInvBeforeLogin) { if (protectInvBeforeLogin) {
ConsoleLogger.warning("WARNING! The protectInventory feature requires ProtocolLib! Disabling it..."); logger.warning("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
} }
if (denyTabCompleteBeforeLogin) { if (denyTabCompleteBeforeLogin) {
ConsoleLogger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it..."); logger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it...");
} }
this.isEnabled = false; this.isEnabled = false;
@ -58,8 +65,9 @@ public class ProtocolLibService implements SettingsDependent {
// Set up packet adapters // Set up packet adapters
if (protectInvBeforeLogin) { if (protectInvBeforeLogin) {
if (inventoryPacketAdapter == null) { if (inventoryPacketAdapter == null) {
inventoryPacketAdapter = new InventoryPacketAdapter(plugin, playerCache); // register the packet listener and start hiding it for all already online players (reload)
inventoryPacketAdapter.register(); inventoryPacketAdapter = new InventoryPacketAdapter(plugin, playerCache, dataSource);
inventoryPacketAdapter.register(bukkitService);
} }
} else if (inventoryPacketAdapter != null) { } else if (inventoryPacketAdapter != null) {
inventoryPacketAdapter.unregister(); inventoryPacketAdapter.unregister();

View File

@ -9,9 +9,11 @@ import com.comphenix.protocol.reflect.FieldAccessException;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.output.ConsoleLoggerFactory;
class TabCompletePacketAdapter extends PacketAdapter { class TabCompletePacketAdapter extends PacketAdapter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TabCompletePacketAdapter.class);
private final PlayerCache playerCache; private final PlayerCache playerCache;
TabCompletePacketAdapter(AuthMe plugin, PlayerCache playerCache) { TabCompletePacketAdapter(AuthMe plugin, PlayerCache playerCache) {
@ -27,7 +29,7 @@ class TabCompletePacketAdapter extends PacketAdapter {
event.setCancelled(true); event.setCancelled(true);
} }
} catch (FieldAccessException e) { } catch (FieldAccessException e) {
ConsoleLogger.logException("Couldn't access field:", e); logger.logException("Couldn't access field:", e);
} }
} }
} }

View File

@ -2,13 +2,14 @@ package fr.xephi.authme.mail;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import org.apache.commons.mail.EmailException; import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail; import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Server;
import javax.activation.DataSource; import javax.activation.DataSource;
import javax.activation.FileDataSource; import javax.activation.FileDataSource;
@ -22,15 +23,15 @@ import java.io.IOException;
*/ */
public class EmailService { public class EmailService {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
private final File dataFolder; private final File dataFolder;
private final String serverName;
private final Settings settings; private final Settings settings;
private final SendMailSsl sendMailSsl; private final SendMailSsl sendMailSsl;
@Inject @Inject
EmailService(@DataFolder File dataFolder, Server server, Settings settings, SendMailSsl sendMailSsl) { EmailService(@DataFolder File dataFolder, Settings settings, SendMailSsl sendMailSsl) {
this.dataFolder = dataFolder; this.dataFolder = dataFolder;
this.serverName = server.getServerName();
this.settings = settings; this.settings = settings;
this.sendMailSsl = sendMailSsl; this.sendMailSsl = sendMailSsl;
} }
@ -50,7 +51,7 @@ public class EmailService {
*/ */
public boolean sendPasswordMail(String name, String mailAddress, String newPass) { public boolean sendPasswordMail(String name, String mailAddress, String newPass) {
if (!hasAllInformation()) { if (!hasAllInformation()) {
ConsoleLogger.warning("Cannot perform email registration: not all email settings are complete"); logger.warning("Cannot perform email registration: not all email settings are complete");
return false; return false;
} }
@ -58,7 +59,7 @@ public class EmailService {
try { try {
email = sendMailSsl.initializeMail(mailAddress); email = sendMailSsl.initializeMail(mailAddress);
} catch (EmailException e) { } catch (EmailException e) {
ConsoleLogger.logException("Failed to create email with the given settings:", e); logger.logException("Failed to create email with the given settings:", e);
return false; return false;
} }
@ -70,7 +71,7 @@ public class EmailService {
file = generatePasswordImage(name, newPass); file = generatePasswordImage(name, newPass);
mailText = embedImageIntoEmailContent(file, email, mailText); mailText = embedImageIntoEmailContent(file, email, mailText);
} catch (IOException | EmailException e) { } catch (IOException | EmailException e) {
ConsoleLogger.logException( logger.logException(
"Unable to send new password as image for email " + mailAddress + ":", e); "Unable to send new password as image for email " + mailAddress + ":", e);
} }
} }
@ -90,7 +91,7 @@ public class EmailService {
*/ */
public boolean sendVerificationMail(String name, String mailAddress, String code) { public boolean sendVerificationMail(String name, String mailAddress, String code) {
if (!hasAllInformation()) { if (!hasAllInformation()) {
ConsoleLogger.warning("Cannot send verification email: not all email settings are complete"); logger.warning("Cannot send verification email: not all email settings are complete");
return false; return false;
} }
@ -98,7 +99,7 @@ public class EmailService {
try { try {
email = sendMailSsl.initializeMail(mailAddress); email = sendMailSsl.initializeMail(mailAddress);
} catch (EmailException e) { } catch (EmailException e) {
ConsoleLogger.logException("Failed to create verification email with the given settings:", e); logger.logException("Failed to create verification email with the given settings:", e);
return false; return false;
} }
@ -120,7 +121,7 @@ public class EmailService {
try { try {
htmlEmail = sendMailSsl.initializeMail(email); htmlEmail = sendMailSsl.initializeMail(email);
} catch (EmailException e) { } catch (EmailException e) {
ConsoleLogger.logException("Failed to create email for recovery code:", e); logger.logException("Failed to create email for recovery code:", e);
return false; return false;
} }
@ -146,14 +147,14 @@ public class EmailService {
private String replaceTagsForPasswordMail(String mailText, String name, String newPass) { private String replaceTagsForPasswordMail(String mailText, String name, String newPass) {
return mailText return mailText
.replace("<playername />", name) .replace("<playername />", name)
.replace("<servername />", serverName) .replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
.replace("<generatedpass />", newPass); .replace("<generatedpass />", newPass);
} }
private String replaceTagsForVerificationEmail(String mailText, String name, String code, int minutesValid) { private String replaceTagsForVerificationEmail(String mailText, String name, String code, int minutesValid) {
return mailText return mailText
.replace("<playername />", name) .replace("<playername />", name)
.replace("<servername />", serverName) .replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
.replace("<generatedcode />", code) .replace("<generatedcode />", code)
.replace("<minutesvalid />", String.valueOf(minutesValid)); .replace("<minutesvalid />", String.valueOf(minutesValid));
} }
@ -161,7 +162,7 @@ public class EmailService {
private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid) { private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid) {
return mailText return mailText
.replace("<playername />", name) .replace("<playername />", name)
.replace("<servername />", serverName) .replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
.replace("<recoverycode />", code) .replace("<recoverycode />", code)
.replace("<hoursvalid />", String.valueOf(hoursValid)); .replace("<hoursvalid />", String.valueOf(hoursValid));
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.mail; package fr.xephi.authme.mail;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
@ -26,6 +27,8 @@ import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
*/ */
public class SendMailSsl { public class SendMailSsl {
private ConsoleLogger logger = ConsoleLoggerFactory.get(SendMailSsl.class);
@Inject @Inject
private Settings settings; private Settings settings;
@ -96,14 +99,14 @@ public class SendMailSsl {
email.setHtmlMsg(content); email.setHtmlMsg(content);
email.setTextMsg(content); email.setTextMsg(content);
} catch (EmailException e) { } catch (EmailException e) {
ConsoleLogger.logException("Your email.html config contains an error and cannot be sent:", e); logger.logException("Your email.html config contains an error and cannot be sent:", e);
return false; return false;
} }
try { try {
email.send(); email.send();
return true; return true;
} catch (EmailException e) { } catch (EmailException e) {
ConsoleLogger.logException("Failed to send a mail to " + email.getToAddresses() + ":", e); logger.logException("Failed to send a mail to " + email.getToAddresses() + ":", e);
return false; return false;
} }
} }

View File

@ -4,6 +4,7 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
@ -14,12 +15,14 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.File; import java.io.File;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
/** /**
* Handles a YAML message file with a default file fallback. * Handles a YAML message file with a default file fallback.
*/ */
public abstract class AbstractMessageFileHandler implements Reloadable { public abstract class AbstractMessageFileHandler implements Reloadable {
protected static final String DEFAULT_LANGUAGE = "en"; private final ConsoleLogger logger = ConsoleLoggerFactory.get(AbstractMessageFileHandler.class);
@DataFolder @DataFolder
@Inject @Inject
@ -116,8 +119,7 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
if (FileUtils.copyFileFromResource(file, defaultFile)) { if (FileUtils.copyFileFromResource(file, defaultFile)) {
return file; return file;
} else { } else {
ConsoleLogger.warning("Wanted to copy default messages file '" + defaultFile logger.warning("Wanted to copy default messages file '" + defaultFile + "' from JAR but it didn't exist");
+ "' from JAR but it didn't exist");
return null; return null;
} }
} }

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.message; package fr.xephi.authme.message;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -9,11 +10,15 @@ import javax.inject.Inject;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
/** /**
* File handler for the help_xx.yml resource. * File handler for the help_xx.yml resource.
*/ */
public class HelpMessagesFileHandler extends AbstractMessageFileHandler { public class HelpMessagesFileHandler extends AbstractMessageFileHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(HelpMessagesFileHandler.class);
private FileConfiguration defaultConfiguration; private FileConfiguration defaultConfiguration;
@Inject // Trigger injection in the superclass @Inject // Trigger injection in the superclass
@ -31,7 +36,7 @@ public class HelpMessagesFileHandler extends AbstractMessageFileHandler {
String message = getMessageIfExists(key); String message = getMessageIfExists(key);
if (message == null) { if (message == null) {
ConsoleLogger.warning("Error getting message with key '" + key + "'. " logger.warning("Error getting message with key '" + key + "'. "
+ "Please update your config file '" + getFilename() + "' or run /authme messages help"); + "Please update your config file '" + getFilename() + "' or run /authme messages help");
return getDefault(key); return getDefault(key);
} }
@ -57,6 +62,6 @@ public class HelpMessagesFileHandler extends AbstractMessageFileHandler {
@Override @Override
protected String createFilePath(String language) { protected String createFilePath(String language) {
return "messages/help_" + language + ".yml"; return MessagePathHelper.createHelpMessageFilePath(language);
} }
} }

View File

@ -0,0 +1,77 @@
package fr.xephi.authme.message;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Helper for creating and processing paths to message files.
*/
public final class MessagePathHelper {
/** The default language (used as fallback, assumed to be complete, etc.). */
public static final String DEFAULT_LANGUAGE = "en";
/** Local path to the folder containing the message files. */
public static final String MESSAGES_FOLDER = "messages/";
/** Local path to the default messages file (messages/messages_en.yml). */
public static final String DEFAULT_MESSAGES_FILE = createMessageFilePath(DEFAULT_LANGUAGE);
private static final Pattern MESSAGE_FILE_PATTERN = Pattern.compile("messages_([a-z]+)\\.yml");
private static final Pattern HELP_MESSAGES_FILE = Pattern.compile("help_[a-z]+\\.yml");
private MessagePathHelper() {
}
/**
* Creates the local path to the messages file for the provided language code.
*
* @param languageCode the language code
* @return local path to the messages file of the given language
*/
public static String createMessageFilePath(String languageCode) {
return "messages/messages_" + languageCode + ".yml";
}
/**
* Creates the local path to the help messages file for the provided language code.
*
* @param languageCode the language code
* @return local path to the help messages file of the given language
*/
public static String createHelpMessageFilePath(String languageCode) {
return "messages/help_" + languageCode + ".yml";
}
/**
* Returns whether the given file name is a messages file.
*
* @param filename the file name to test
* @return true if it is a messages file, false otherwise
*/
public static boolean isMessagesFile(String filename) {
return MESSAGE_FILE_PATTERN.matcher(filename).matches();
}
/**
* Returns the language code the given file name is for if it is a messages file, otherwise null is returned.
*
* @param filename the file name to process
* @return the language code the file name is a messages file for, or null if not applicable
*/
public static String getLanguageIfIsMessagesFile(String filename) {
Matcher matcher = MESSAGE_FILE_PATTERN.matcher(filename);
if (matcher.matches()) {
return matcher.group(1);
}
return null;
}
/**
* Returns whether the given file name is a help messages file.
*
* @param filename the file name to test
* @return true if it is a help messages file, false otherwise
*/
public static boolean isHelpFile(String filename) {
return HELP_MESSAGES_FILE.matcher(filename).matches();
}
}

View File

@ -2,6 +2,8 @@ package fr.xephi.authme.message;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.util.expiring.Duration; import fr.xephi.authme.util.expiring.Duration;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -37,6 +39,8 @@ public class Messages {
.put(TimeUnit.HOURS, MessageKey.HOURS) .put(TimeUnit.HOURS, MessageKey.HOURS)
.put(TimeUnit.DAYS, MessageKey.DAYS).build(); .put(TimeUnit.DAYS, MessageKey.DAYS).build();
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
private MessagesFileHandler messagesFileHandler; private MessagesFileHandler messagesFileHandler;
/* /*
@ -162,7 +166,7 @@ public class Messages {
message = message.replace(tags[i], replacements[i]); message = message.replace(tags[i], replacements[i]);
} }
} else { } else {
ConsoleLogger.warning("Invalid number of replacements for message key '" + key + "'"); logger.warning("Invalid number of replacements for message key '" + key + "'");
} }
return message; return message;
} }
@ -185,7 +189,7 @@ public class Messages {
message = message.replace(tags[i], replacements[i]); message = message.replace(tags[i], replacements[i]);
} }
} else { } else {
ConsoleLogger.warning("Invalid number of replacements for message key '" + key + "'"); logger.warning("Invalid number of replacements for message key '" + key + "'");
} }
return message; return message;
} }

View File

@ -1,15 +1,20 @@
package fr.xephi.authme.message; package fr.xephi.authme.message;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.updater.MessageUpdater; import fr.xephi.authme.message.updater.MessageUpdater;
import javax.inject.Inject; import javax.inject.Inject;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
/** /**
* File handler for the messages_xx.yml resource. * File handler for the messages_xx.yml resource.
*/ */
public class MessagesFileHandler extends AbstractMessageFileHandler { public class MessagesFileHandler extends AbstractMessageFileHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(MessagesFileHandler.class);
@Inject @Inject
private MessageUpdater messageUpdater; private MessageUpdater messageUpdater;
@ -29,7 +34,7 @@ public class MessagesFileHandler extends AbstractMessageFileHandler {
getUserLanguageFile(), createFilePath(language), createFilePath(DEFAULT_LANGUAGE)); getUserLanguageFile(), createFilePath(language), createFilePath(DEFAULT_LANGUAGE));
if (hasChange) { if (hasChange) {
if (isFromReload) { if (isFromReload) {
ConsoleLogger.warning("Migration after reload attempt"); logger.warning("Migration after reload attempt");
} else { } else {
reloadInternal(true); reloadInternal(true);
} }
@ -38,6 +43,6 @@ public class MessagesFileHandler extends AbstractMessageFileHandler {
@Override @Override
protected String createFilePath(String language) { protected String createFilePath(String language) {
return "messages/messages_" + language + ".yml"; return MessagePathHelper.createMessageFilePath(language);
} }
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.message.updater;
import ch.jalu.configme.properties.Property; import ch.jalu.configme.properties.Property;
import ch.jalu.configme.resource.PropertyReader; import ch.jalu.configme.resource.PropertyReader;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import java.io.IOException; import java.io.IOException;
@ -14,6 +15,7 @@ import java.io.InputStream;
*/ */
public class JarMessageSource { public class JarMessageSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(JarMessageSource.class);
private final PropertyReader localJarMessages; private final PropertyReader localJarMessages;
private final PropertyReader defaultJarMessages; private final PropertyReader defaultJarMessages;
@ -42,15 +44,15 @@ public class JarMessageSource {
return reader == null ? null : reader.getString(path); return reader == null ? null : reader.getString(path);
} }
private static MessageMigraterPropertyReader loadJarFile(String jarPath) { private MessageMigraterPropertyReader loadJarFile(String jarPath) {
try (InputStream stream = FileUtils.getResourceFromJar(jarPath)) { try (InputStream stream = FileUtils.getResourceFromJar(jarPath)) {
if (stream == null) { if (stream == null) {
ConsoleLogger.debug("Could not load '" + jarPath + "' from JAR"); logger.debug("Could not load '" + jarPath + "' from JAR");
return null; return null;
} }
return MessageMigraterPropertyReader.loadFromStream(stream); return MessageMigraterPropertyReader.loadFromStream(stream);
} catch (IOException e) { } catch (IOException e) {
ConsoleLogger.logException("Exception while handling JAR path '" + jarPath + "'", e); logger.logException("Exception while handling JAR path '" + jarPath + "'", e);
} }
return null; return null;
} }

View File

@ -9,6 +9,7 @@ import ch.jalu.configme.resource.PropertyResource;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files; import com.google.common.io.Files;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
@ -29,6 +30,8 @@ import static java.util.Collections.singletonList;
*/ */
public class MessageUpdater { public class MessageUpdater {
private ConsoleLogger logger = ConsoleLoggerFactory.get(MessageUpdater.class);
/** /**
* Applies any necessary migrations to the user's messages file and saves it if it has been modified. * Applies any necessary migrations to the user's messages file and saves it if it has been modified.
* *
@ -68,7 +71,7 @@ public class MessageUpdater {
backupMessagesFile(userFile); backupMessagesFile(userFile);
userResource.exportProperties(configurationData); userResource.exportProperties(configurationData);
ConsoleLogger.debug("Successfully saved {0}", userFile); logger.debug("Successfully saved {0}", userFile);
return true; return true;
} }
return false; return false;
@ -91,7 +94,7 @@ public class MessageUpdater {
private boolean migrateOldKeys(PropertyReader propertyReader, MessageKeyConfigurationData configurationData) { private boolean migrateOldKeys(PropertyReader propertyReader, MessageKeyConfigurationData configurationData) {
boolean hasChange = OldMessageKeysMigrater.migrateOldPaths(propertyReader, configurationData); boolean hasChange = OldMessageKeysMigrater.migrateOldPaths(propertyReader, configurationData);
if (hasChange) { if (hasChange) {
ConsoleLogger.info("Old keys have been moved to the new ones in your messages_xx.yml file"); logger.info("Old keys have been moved to the new ones in your messages_xx.yml file");
} }
return hasChange; return hasChange;
} }
@ -106,7 +109,7 @@ public class MessageUpdater {
} }
} }
if (!addedKeys.isEmpty()) { if (!addedKeys.isEmpty()) {
ConsoleLogger.info( logger.info(
"Added " + addedKeys.size() + " missing keys to your messages_xx.yml file: " + addedKeys); "Added " + addedKeys.size() + " missing keys to your messages_xx.yml file: " + addedKeys);
return true; return true;
} }

View File

@ -0,0 +1,51 @@
package fr.xephi.authme.output;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.Settings;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Creates and keeps track of {@link ConsoleLogger} instances.
*/
public final class ConsoleLoggerFactory {
private static final Map<String, ConsoleLogger> consoleLoggers = new ConcurrentHashMap<>();
private static Settings settings;
private ConsoleLoggerFactory() {
}
/**
* Creates or returns the already existing logger associated with the given class.
*
* @param owningClass the class whose logger should be retrieved
* @return logger for the given class
*/
public static ConsoleLogger get(Class<?> owningClass) {
String name = owningClass.getCanonicalName();
return consoleLoggers.computeIfAbsent(name, ConsoleLoggerFactory::createLogger);
}
/**
* Sets up all loggers according to the properties returned by the settings instance.
*
* @param settings the settings instance
*/
public static void reloadSettings(Settings settings) {
ConsoleLoggerFactory.settings = settings;
ConsoleLogger.initializeSharedSettings(settings);
consoleLoggers.values()
.forEach(logger -> logger.initializeSettings(settings));
}
private static ConsoleLogger createLogger(String name) {
ConsoleLogger logger = new ConsoleLogger(name);
if (settings != null) {
logger.initializeSettings(settings);
}
return logger;
}
}

View File

@ -45,6 +45,16 @@ public enum AdminPermission implements PermissionNode {
*/ */
CHANGE_EMAIL("authme.admin.changemail"), CHANGE_EMAIL("authme.admin.changemail"),
/**
* Administrator command to see whether a player has enabled two-factor authentication.
*/
VIEW_TOTP_STATUS("authme.admin.totpviewstatus"),
/**
* Administrator command to disable the two-factor auth of a user.
*/
DISABLE_TOTP("authme.admin.totpdisable"),
/** /**
* Administrator command to get the last known IP of a user. * Administrator command to get the last known IP of a user.
*/ */

View File

@ -3,8 +3,8 @@ package fr.xephi.authme.permission;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.listener.JoiningPlayer; import fr.xephi.authme.listener.JoiningPlayer;
import fr.xephi.authme.permission.handlers.BPermissionsHandler;
import fr.xephi.authme.permission.handlers.LuckPermsHandler; import fr.xephi.authme.permission.handlers.LuckPermsHandler;
import fr.xephi.authme.permission.handlers.PermissionHandler; import fr.xephi.authme.permission.handlers.PermissionHandler;
import fr.xephi.authme.permission.handlers.PermissionHandlerException; import fr.xephi.authme.permission.handlers.PermissionHandlerException;
@ -41,6 +41,7 @@ import java.util.UUID;
*/ */
public class PermissionsManager implements Reloadable { public class PermissionsManager implements Reloadable {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PermissionsManager.class);
private final Server server; private final Server server;
private final PluginManager pluginManager; private final PluginManager pluginManager;
private final Settings settings; private final Settings settings;
@ -79,11 +80,11 @@ public class PermissionsManager implements Reloadable {
if (handler != null) { if (handler != null) {
// Show a success message and return // Show a success message and return
this.handler = handler; this.handler = handler;
ConsoleLogger.info("Hooked into " + PermissionsSystemType.VAULT.getDisplayName() + "!"); logger.info("Hooked into " + PermissionsSystemType.VAULT.getDisplayName() + "!");
return; return;
} }
} catch (PermissionHandlerException e) { } catch (PermissionHandlerException e) {
ConsoleLogger.logException("Failed to create Vault hook (forced):", e); logger.logException("Failed to create Vault hook (forced):", e);
} }
} else { } else {
// Loop through all the available permissions system types // Loop through all the available permissions system types
@ -93,18 +94,18 @@ public class PermissionsManager implements Reloadable {
if (handler != null) { if (handler != null) {
// Show a success message and return // Show a success message and return
this.handler = handler; this.handler = handler;
ConsoleLogger.info("Hooked into " + type.getDisplayName() + "!"); logger.info("Hooked into " + type.getDisplayName() + "!");
return; return;
} }
} catch (Exception ex) { } catch (Exception ex) {
// An error occurred, show a warning message // An error occurred, show a warning message
ConsoleLogger.logException("Error while hooking into " + type.getDisplayName(), ex); logger.logException("Error while hooking into " + type.getDisplayName(), ex);
} }
} }
} }
// No recognized permissions system found, show a message and return // No recognized permissions system found, show a message and return
ConsoleLogger.info("No supported permissions system found! Permissions are disabled!"); logger.info("No supported permissions system found! Permissions are disabled!");
} }
/** /**
@ -126,7 +127,7 @@ public class PermissionsManager implements Reloadable {
// Make sure the plugin is enabled before hooking // Make sure the plugin is enabled before hooking
if (!plugin.isEnabled()) { if (!plugin.isEnabled()) {
ConsoleLogger.info("Not hooking into " + type.getDisplayName() + " because it's disabled!"); logger.info("Not hooking into " + type.getDisplayName() + " because it's disabled!");
return null; return null;
} }
@ -139,8 +140,6 @@ public class PermissionsManager implements Reloadable {
return new ZPermissionsHandler(); return new ZPermissionsHandler();
case VAULT: case VAULT:
return new VaultHandler(server); return new VaultHandler(server);
case B_PERMISSIONS:
return new BPermissionsHandler();
default: default:
throw new IllegalStateException("Unhandled permission type '" + type + "'"); throw new IllegalStateException("Unhandled permission type '" + type + "'");
} }
@ -154,7 +153,7 @@ public class PermissionsManager implements Reloadable {
this.handler = null; this.handler = null;
// Print a status message to the console // Print a status message to the console
ConsoleLogger.info("Unhooked from Permissions!"); logger.info("Unhooked from Permissions!");
} }
/** /**
@ -177,7 +176,7 @@ public class PermissionsManager implements Reloadable {
public void onPluginEnable(String pluginName) { public void onPluginEnable(String pluginName) {
// Check if any known permissions system is enabling // Check if any known permissions system is enabling
if (PermissionsSystemType.isPermissionSystem(pluginName)) { if (PermissionsSystemType.isPermissionSystem(pluginName)) {
ConsoleLogger.info(pluginName + " plugin enabled, dynamically updating permissions hooks!"); logger.info(pluginName + " plugin enabled, dynamically updating permissions hooks!");
setup(); setup();
} }
} }
@ -190,7 +189,7 @@ public class PermissionsManager implements Reloadable {
public void onPluginDisable(String pluginName) { public void onPluginDisable(String pluginName) {
// Check if any known permission system is being disabled // Check if any known permission system is being disabled
if (PermissionsSystemType.isPermissionSystem(pluginName)) { if (PermissionsSystemType.isPermissionSystem(pluginName)) {
ConsoleLogger.info(pluginName + " plugin disabled, updating hooks!"); logger.info(pluginName + " plugin disabled, updating hooks!");
setup(); setup();
} }
} }
@ -457,7 +456,7 @@ public class PermissionsManager implements Reloadable {
try { try {
loadUserData(offlinePlayer.getUniqueId()); loadUserData(offlinePlayer.getUniqueId());
} catch (PermissionLoadUserException e) { } catch (PermissionLoadUserException e) {
ConsoleLogger.logException("Unable to load the permission data of user " + offlinePlayer.getName(), e); logger.logException("Unable to load the permission data of user " + offlinePlayer.getName(), e);
return false; return false;
} }
return true; return true;

View File

@ -15,11 +15,6 @@ public enum PermissionsSystemType {
*/ */
PERMISSIONS_EX("PermissionsEx", "PermissionsEx"), PERMISSIONS_EX("PermissionsEx", "PermissionsEx"),
/**
* bPermissions.
*/
B_PERMISSIONS("bPermissions", "bPermissions"),
/** /**
* zPermissions. * zPermissions.
*/ */

View File

@ -1,62 +0,0 @@
package fr.xephi.authme.permission.handlers;
import de.bananaco.bpermissions.api.ApiLayer;
import de.bananaco.bpermissions.api.CalculableType;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsSystemType;
import org.bukkit.OfflinePlayer;
import java.util.Arrays;
import java.util.List;
/**
* Handler for bPermissions.
*
* @see <a href="https://dev.bukkit.org/projects/bpermissions">bPermissions Bukkit page</a>
* @see <a href="https://github.com/rymate1234/bPermissions/">bPermissions on Github</a>
*/
public class BPermissionsHandler implements PermissionHandler {
@Override
public boolean addToGroup(OfflinePlayer player, String group) {
ApiLayer.addGroup(null, CalculableType.USER, player.getName(), group);
return true;
}
@Override
public boolean hasGroupSupport() {
return true;
}
@Override
public boolean hasPermissionOffline(String name, PermissionNode node) {
return ApiLayer.hasPermission(null, CalculableType.USER, name, node.getNode());
}
@Override
public boolean isInGroup(OfflinePlayer player, String group) {
return ApiLayer.hasGroup(null, CalculableType.USER, player.getName(), group);
}
@Override
public boolean removeFromGroup(OfflinePlayer player, String group) {
ApiLayer.removeGroup(null, CalculableType.USER, player.getName(), group);
return true;
}
@Override
public boolean setGroup(OfflinePlayer player, String group) {
ApiLayer.setGroup(null, CalculableType.USER, player.getName(), group);
return true;
}
@Override
public List<String> getGroups(OfflinePlayer player) {
return Arrays.asList(ApiLayer.getGroups(null, CalculableType.USER, player.getName()));
}
@Override
public PermissionsSystemType getPermissionSystem() {
return PermissionsSystemType.B_PERMISSIONS;
}
}

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.permission.handlers; package fr.xephi.authme.permission.handlers;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsSystemType; import fr.xephi.authme.permission.PermissionsSystemType;
import me.lucko.luckperms.LuckPerms; import me.lucko.luckperms.LuckPerms;
@ -31,6 +32,7 @@ import java.util.stream.Collectors;
*/ */
public class LuckPermsHandler implements PermissionHandler { public class LuckPermsHandler implements PermissionHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LuckPermsHandler.class);
private LuckPermsApi luckPermsApi; private LuckPermsApi luckPermsApi;
public LuckPermsHandler() throws PermissionHandlerException { public LuckPermsHandler() throws PermissionHandlerException {
@ -79,7 +81,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean hasPermissionOffline(String name, PermissionNode node) { public boolean hasPermissionOffline(String name, PermissionNode node) {
User user = luckPermsApi.getUser(name); User user = luckPermsApi.getUser(name);
if (user == null) { if (user == null) {
ConsoleLogger.warning("LuckPermsHandler: tried to check permission for offline user " logger.warning("LuckPermsHandler: tried to check permission for offline user "
+ name + " but it isn't loaded!"); + name + " but it isn't loaded!");
return false; return false;
} }
@ -96,7 +98,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean isInGroup(OfflinePlayer player, String group) { public boolean isInGroup(OfflinePlayer player, String group) {
User user = luckPermsApi.getUser(player.getName()); User user = luckPermsApi.getUser(player.getName());
if (user == null) { if (user == null) {
ConsoleLogger.warning("LuckPermsHandler: tried to check group for offline user " logger.warning("LuckPermsHandler: tried to check group for offline user "
+ player.getName() + " but it isn't loaded!"); + player.getName() + " but it isn't loaded!");
return false; return false;
} }
@ -112,7 +114,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean removeFromGroup(OfflinePlayer player, String group) { public boolean removeFromGroup(OfflinePlayer player, String group) {
User user = luckPermsApi.getUser(player.getName()); User user = luckPermsApi.getUser(player.getName());
if (user == null) { if (user == null) {
ConsoleLogger.warning("LuckPermsHandler: tried to remove group for offline user " logger.warning("LuckPermsHandler: tried to remove group for offline user "
+ player.getName() + " but it isn't loaded!"); + player.getName() + " but it isn't loaded!");
return false; return false;
} }
@ -133,7 +135,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean setGroup(OfflinePlayer player, String group) { public boolean setGroup(OfflinePlayer player, String group) {
User user = luckPermsApi.getUser(player.getName()); User user = luckPermsApi.getUser(player.getName());
if (user == null) { if (user == null) {
ConsoleLogger.warning("LuckPermsHandler: tried to set group for offline user " logger.warning("LuckPermsHandler: tried to set group for offline user "
+ player.getName() + " but it isn't loaded!"); + player.getName() + " but it isn't loaded!");
return false; return false;
} }
@ -157,7 +159,7 @@ public class LuckPermsHandler implements PermissionHandler {
public List<String> getGroups(OfflinePlayer player) { public List<String> getGroups(OfflinePlayer player) {
User user = luckPermsApi.getUser(player.getName()); User user = luckPermsApi.getUser(player.getName());
if (user == null) { if (user == null) {
ConsoleLogger.warning("LuckPermsHandler: tried to get groups for offline user " logger.warning("LuckPermsHandler: tried to get groups for offline user "
+ player.getName() + " but it isn't loaded!"); + player.getName() + " but it isn't loaded!");
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
@ -18,6 +19,8 @@ import javax.inject.Inject;
public class AsyncChangePassword implements AsynchronousProcess { public class AsyncChangePassword implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsyncChangePassword.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@ -58,7 +61,7 @@ public class AsyncChangePassword implements AsynchronousProcess {
playerCache.updatePlayer(auth); playerCache.updatePlayer(auth);
commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS); commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS);
ConsoleLogger.info(player.getName() + " changed his password"); logger.info(player.getName() + " changed his password");
} else { } else {
commonService.send(player, MessageKey.WRONG_PASSWORD); commonService.send(player, MessageKey.WRONG_PASSWORD);
} }
@ -75,7 +78,7 @@ public class AsyncChangePassword implements AsynchronousProcess {
final String lowerCaseName = playerName.toLowerCase(); final String lowerCaseName = playerName.toLowerCase();
if (!(playerCache.isAuthenticated(lowerCaseName) || dataSource.isAuthAvailable(lowerCaseName))) { if (!(playerCache.isAuthenticated(lowerCaseName) || dataSource.isAuthAvailable(lowerCaseName))) {
if (sender == null) { if (sender == null) {
ConsoleLogger.warning("Tried to change password for user " + lowerCaseName + " but it doesn't exist!"); logger.warning("Tried to change password for user " + lowerCaseName + " but it doesn't exist!");
} else { } else {
commonService.send(sender, MessageKey.UNKNOWN_USER); commonService.send(sender, MessageKey.UNKNOWN_USER);
} }
@ -87,15 +90,15 @@ public class AsyncChangePassword implements AsynchronousProcess {
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_PASSWORD, lowerCaseName); bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_PASSWORD, lowerCaseName);
if (sender != null) { if (sender != null) {
commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
ConsoleLogger.info(sender.getName() + " changed password of " + lowerCaseName); logger.info(sender.getName() + " changed password of " + lowerCaseName);
} else { } else {
ConsoleLogger.info("Changed password of " + lowerCaseName); logger.info("Changed password of " + lowerCaseName);
} }
} else { } else {
if (sender != null) { if (sender != null) {
commonService.send(sender, MessageKey.ERROR); commonService.send(sender, MessageKey.ERROR);
} }
ConsoleLogger.warning("An error occurred while changing password for user " + lowerCaseName + "!"); logger.warning("An error occurred while changing password for user " + lowerCaseName + "!");
} }
} }
} }

View File

@ -5,6 +5,7 @@ import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.EmailChangedEvent; import fr.xephi.authme.events.EmailChangedEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -22,6 +23,8 @@ import javax.inject.Inject;
*/ */
public class AsyncAddEmail implements AsynchronousProcess { public class AsyncAddEmail implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsyncAddEmail.class);
@Inject @Inject
private CommonService service; private CommonService service;
@ -65,7 +68,7 @@ public class AsyncAddEmail implements AsynchronousProcess {
EmailChangedEvent event = bukkitService.createAndCallEvent(isAsync EmailChangedEvent event = bukkitService.createAndCallEvent(isAsync
-> new EmailChangedEvent(player, null, email, isAsync)); -> new EmailChangedEvent(player, null, email, isAsync));
if (event.isCancelled()) { if (event.isCancelled()) {
ConsoleLogger.info("Could not add email to player '" + player + "' event was cancelled"); logger.info("Could not add email to player '" + player + "' event was cancelled");
service.send(player, MessageKey.EMAIL_ADD_NOT_ALLOWED); service.send(player, MessageKey.EMAIL_ADD_NOT_ALLOWED);
return; return;
} }
@ -75,7 +78,7 @@ public class AsyncAddEmail implements AsynchronousProcess {
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_EMAIL, playerName); bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_EMAIL, playerName);
service.send(player, MessageKey.EMAIL_ADDED_SUCCESS); service.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
} else { } else {
ConsoleLogger.warning("Could not save email for player '" + player + "'"); logger.warning("Could not save email for player '" + player + "'");
service.send(player, MessageKey.ERROR); service.send(player, MessageKey.ERROR);
} }
} }

View File

@ -5,6 +5,7 @@ import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.EmailChangedEvent; import fr.xephi.authme.events.EmailChangedEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -21,6 +22,8 @@ import javax.inject.Inject;
*/ */
public class AsyncChangeEmail implements AsynchronousProcess { public class AsyncChangeEmail implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsyncChangeEmail.class);
@Inject @Inject
private CommonService service; private CommonService service;
@ -83,7 +86,7 @@ public class AsyncChangeEmail implements AsynchronousProcess {
EmailChangedEvent event = bukkitService.createAndCallEvent(isAsync EmailChangedEvent event = bukkitService.createAndCallEvent(isAsync
-> new EmailChangedEvent(player, oldEmail, newEmail, isAsync)); -> new EmailChangedEvent(player, oldEmail, newEmail, isAsync));
if (event.isCancelled()) { if (event.isCancelled()) {
ConsoleLogger.info("Could not change email for player '" + player + "' event was cancelled"); logger.info("Could not change email for player '" + player + "' event was cancelled");
service.send(player, MessageKey.EMAIL_CHANGE_NOT_ALLOWED); service.send(player, MessageKey.EMAIL_CHANGE_NOT_ALLOWED);
return; return;
} }

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService; import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.ProtectInventoryEvent; import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.process.AsynchronousProcess;
@ -36,6 +37,8 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_IN
*/ */
public class AsynchronousJoin implements AsynchronousProcess { public class AsynchronousJoin implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsynchronousJoin.class);
@Inject @Inject
private Server server; private Server server;
@ -112,7 +115,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
isAsync -> new ProtectInventoryEvent(player, isAsync)); isAsync -> new ProtectInventoryEvent(player, isAsync));
if (ev.isCancelled()) { if (ev.isCancelled()) {
player.updateInventory(); player.updateInventory();
ConsoleLogger.fine("ProtectInventoryEvent has been cancelled for " + player.getName() + "..."); logger.fine("ProtectInventoryEvent has been cancelled for " + player.getName() + "...");
} }
} }

View File

@ -12,6 +12,7 @@ import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent; import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.events.FailedLoginEvent; import fr.xephi.authme.events.FailedLoginEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.AdminPermission;
@ -45,6 +46,8 @@ import java.util.List;
*/ */
public class AsynchronousLogin implements AsynchronousProcess { public class AsynchronousLogin implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsynchronousLogin.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@ -199,7 +202,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
* @param ip the ip address of the player * @param ip the ip address of the player
*/ */
private void handleWrongPassword(Player player, PlayerAuth auth, String ip) { private void handleWrongPassword(Player player, PlayerAuth auth, String ip) {
ConsoleLogger.fine(player.getName() + " used the wrong password"); logger.fine(player.getName() + " used the wrong password");
bukkitService.createAndCallEvent(isAsync -> new FailedLoginEvent(player, isAsync)); bukkitService.createAndCallEvent(isAsync -> new FailedLoginEvent(player, isAsync));
if (tempbanManager.shouldTempban(ip)) { if (tempbanManager.shouldTempban(ip)) {
@ -256,7 +259,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
service.send(player, MessageKey.ADD_EMAIL_MESSAGE); service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
} }
ConsoleLogger.fine(player.getName() + " logged in!"); logger.fine(player.getName() + " logged in!");
// makes player loggedin // makes player loggedin
playerCache.updatePlayer(auth); playerCache.updatePlayer(auth);
@ -270,7 +273,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
// processed in other order. // processed in other order.
syncProcessManager.processSyncPlayerLogin(player, isFirstLogin, auths); syncProcessManager.processSyncPlayerLogin(player, isFirstLogin, auths);
} else { } else {
ConsoleLogger.warning("Player '" + player.getName() + "' wasn't online during login process, aborted..."); logger.warning("Player '" + player.getName() + "' wasn't online during login process, aborted...");
} }
} }
@ -297,8 +300,8 @@ public class AsynchronousLogin implements AsynchronousProcess {
String message = ChatColor.GRAY + String.join(", ", formattedNames) + "."; String message = ChatColor.GRAY + String.join(", ", formattedNames) + ".";
ConsoleLogger.fine("The user " + player.getName() + " has " + auths.size() + " accounts:"); logger.fine("The user " + player.getName() + " has " + auths.size() + " accounts:");
ConsoleLogger.fine(message); logger.fine(message);
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) { for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
if (onlinePlayer.getName().equalsIgnoreCase(player.getName()) if (onlinePlayer.getName().equalsIgnoreCase(player.getName())

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.process.logout;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService; import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.events.LogoutEvent; import fr.xephi.authme.events.LogoutEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.listener.protocollib.ProtocolLibService; import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.process.SynchronousProcess;
@ -23,6 +24,8 @@ import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
public class ProcessSyncPlayerLogout implements SynchronousProcess { public class ProcessSyncPlayerLogout implements SynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProcessSyncPlayerLogout.class);
@Inject @Inject
private CommonService service; private CommonService service;
@ -61,7 +64,7 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
bukkitService.callEvent(new LogoutEvent(player)); bukkitService.callEvent(new LogoutEvent(player));
service.send(player, MessageKey.LOGOUT_SUCCESS); service.send(player, MessageKey.LOGOUT_SUCCESS);
ConsoleLogger.info(player.getName() + " logged out"); logger.info(player.getName() + " logged out");
} }
private void applyLogoutEffect(Player player) { private void applyLogoutEffect(Player player) {

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.process.register;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService; import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.events.RegisterEvent; import fr.xephi.authme.events.RegisterEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -17,6 +18,8 @@ import javax.inject.Inject;
*/ */
public class ProcessSyncEmailRegister implements SynchronousProcess { public class ProcessSyncEmailRegister implements SynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProcessSyncEmailRegister.class);
@Inject @Inject
private BukkitService bukkitService; private BukkitService bukkitService;
@ -40,7 +43,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
player.saveData(); player.saveData();
bukkitService.callEvent(new RegisterEvent(player)); bukkitService.callEvent(new RegisterEvent(player));
ConsoleLogger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player)); logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));
} }
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.process.register;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService; import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.events.RegisterEvent; import fr.xephi.authme.events.RegisterEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
@ -21,6 +22,8 @@ import javax.inject.Inject;
*/ */
public class ProcessSyncPasswordRegister implements SynchronousProcess { public class ProcessSyncPasswordRegister implements SynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProcessSyncPasswordRegister.class);
@Inject @Inject
private BungeeSender bungeeSender; private BungeeSender bungeeSender;
@ -66,7 +69,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
player.saveData(); player.saveData();
bukkitService.callEvent(new RegisterEvent(player)); bukkitService.callEvent(new RegisterEvent(player));
ConsoleLogger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player)); logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));
// Kick Player after Registration is enabled, kick the player // Kick Player after Registration is enabled, kick the player
if (service.getProperty(RegistrationSettings.FORCE_KICK_AFTER_REGISTER)) { if (service.getProperty(RegistrationSettings.FORCE_KICK_AFTER_REGISTER)) {

View File

@ -29,6 +29,7 @@ final class PlayerAuthBuilderHelper {
.email(email) .email(email)
.registrationIp(PlayerUtils.getPlayerIp(player)) .registrationIp(PlayerUtils.getPlayerIp(player))
.registrationDate(System.currentTimeMillis()) .registrationDate(System.currentTimeMillis())
.uuid(player.getUniqueId())
.build(); .build();
} }
} }

View File

@ -7,6 +7,7 @@ import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.UnregisterByAdminEvent; import fr.xephi.authme.events.UnregisterByAdminEvent;
import fr.xephi.authme.events.UnregisterByPlayerEvent; import fr.xephi.authme.events.UnregisterByPlayerEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
@ -29,6 +30,8 @@ import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
public class AsynchronousUnregister implements AsynchronousProcess { public class AsynchronousUnregister implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsynchronousUnregister.class);
@Inject @Inject
private DataSource dataSource; private DataSource dataSource;
@ -72,7 +75,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
if (passwordSecurity.comparePassword(password, cachedAuth.getPassword(), name)) { if (passwordSecurity.comparePassword(password, cachedAuth.getPassword(), name)) {
if (dataSource.removeAuth(name)) { if (dataSource.removeAuth(name)) {
performPostUnregisterActions(name, player); performPostUnregisterActions(name, player);
ConsoleLogger.info(name + " unregistered himself"); logger.info(name + " unregistered himself");
bukkitService.createAndCallEvent(isAsync -> new UnregisterByPlayerEvent(player, isAsync)); bukkitService.createAndCallEvent(isAsync -> new UnregisterByPlayerEvent(player, isAsync));
} else { } else {
service.send(player, MessageKey.ERROR); service.send(player, MessageKey.ERROR);
@ -97,9 +100,9 @@ public class AsynchronousUnregister implements AsynchronousProcess {
bukkitService.createAndCallEvent(isAsync -> new UnregisterByAdminEvent(player, name, isAsync, initiator)); bukkitService.createAndCallEvent(isAsync -> new UnregisterByAdminEvent(player, name, isAsync, initiator));
if (initiator == null) { if (initiator == null) {
ConsoleLogger.info(name + " was unregistered"); logger.info(name + " was unregistered");
} else { } else {
ConsoleLogger.info(name + " was unregistered by " + initiator.getName()); logger.info(name + " was unregistered by " + initiator.getName());
service.send(initiator, MessageKey.UNREGISTERED_SUCCESS); service.send(initiator, MessageKey.UNREGISTERED_SUCCESS);
} }
} else if (initiator != null) { } else if (initiator != null) {

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.security.crypts;
import de.mkammerer.argon2.Argon2Constants; import de.mkammerer.argon2.Argon2Constants;
import de.mkammerer.argon2.Argon2Factory; import de.mkammerer.argon2.Argon2Factory;
import fr.xephi.authme.ConsoleLogger; 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.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType; import fr.xephi.authme.security.crypts.description.SaltType;
@ -14,6 +15,8 @@ import fr.xephi.authme.security.crypts.description.Usage;
// and isn't exposed to the outside, so we treat it as an unsalted implementation // and isn't exposed to the outside, so we treat it as an unsalted implementation
public class Argon2 extends UnsaltedMethod { public class Argon2 extends UnsaltedMethod {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(Argon2.class);
private de.mkammerer.argon2.Argon2 argon2; private de.mkammerer.argon2.Argon2 argon2;
public Argon2() { public Argon2() {
@ -30,7 +33,7 @@ public class Argon2 extends UnsaltedMethod {
System.loadLibrary("argon2"); System.loadLibrary("argon2");
return true; return true;
} catch (UnsatisfiedLinkError e) { } catch (UnsatisfiedLinkError e) {
ConsoleLogger.logException( logger.logException(
"Cannot find argon2 library: https://github.com/AuthMe/AuthMeReloaded/wiki/Argon2-as-Password-Hash", e); "Cannot find argon2 library: https://github.com/AuthMe/AuthMeReloaded/wiki/Argon2-as-Password-Hash", e);
} }
return false; return false;

View File

@ -5,6 +5,7 @@ import de.rtner.misc.BinTools;
import de.rtner.security.auth.spi.PBKDF2Engine; import de.rtner.security.auth.spi.PBKDF2Engine;
import de.rtner.security.auth.spi.PBKDF2Parameters; import de.rtner.security.auth.spi.PBKDF2Parameters;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage; import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
@ -16,6 +17,7 @@ import javax.inject.Inject;
public class Pbkdf2 extends HexSaltedMethod { public class Pbkdf2 extends HexSaltedMethod {
private static final int DEFAULT_ROUNDS = 10_000; private static final int DEFAULT_ROUNDS = 10_000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Pbkdf2.class);
private int numberOfRounds; private int numberOfRounds;
@Inject @Inject
@ -41,7 +43,7 @@ public class Pbkdf2 extends HexSaltedMethod {
} }
Integer iterations = Ints.tryParse(line[1]); Integer iterations = Ints.tryParse(line[1]);
if (iterations == null) { if (iterations == null) {
ConsoleLogger.warning("Cannot read number of rounds for Pbkdf2: '" + line[1] + "'"); logger.warning("Cannot read number of rounds for Pbkdf2: '" + line[1] + "'");
return false; return false;
} }

View File

@ -4,6 +4,7 @@ import com.google.common.primitives.Ints;
import de.rtner.security.auth.spi.PBKDF2Engine; import de.rtner.security.auth.spi.PBKDF2Engine;
import de.rtner.security.auth.spi.PBKDF2Parameters; import de.rtner.security.auth.spi.PBKDF2Parameters;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.AsciiRestricted; import fr.xephi.authme.security.crypts.description.AsciiRestricted;
import java.util.Base64; import java.util.Base64;
@ -12,6 +13,7 @@ import java.util.Base64;
public class Pbkdf2Django extends HexSaltedMethod { public class Pbkdf2Django extends HexSaltedMethod {
private static final int DEFAULT_ITERATIONS = 24000; private static final int DEFAULT_ITERATIONS = 24000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Pbkdf2Django.class);
@Override @Override
public String computeHash(String password, String salt, String name) { public String computeHash(String password, String salt, String name) {
@ -30,7 +32,7 @@ public class Pbkdf2Django extends HexSaltedMethod {
} }
Integer iterations = Ints.tryParse(line[1]); Integer iterations = Ints.tryParse(line[1]);
if (iterations == null) { if (iterations == null) {
ConsoleLogger.warning("Cannot read number of rounds for Pbkdf2Django: '" + line[1] + "'"); logger.warning("Cannot read number of rounds for Pbkdf2Django: '" + line[1] + "'");
return false; return false;
} }

View File

@ -5,6 +5,7 @@ import com.google.common.io.BaseEncoding;
import com.google.common.net.UrlEscapers; import com.google.common.net.UrlEscapers;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import fr.xephi.authme.ConsoleLogger; 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.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType; import fr.xephi.authme.security.crypts.description.SaltType;
@ -35,6 +36,8 @@ public class TwoFactor extends UnsaltedMethod {
private static final int TIME_PRECISION = 3; private static final int TIME_PRECISION = 3;
private static final String CRYPTO_ALGO = "HmacSHA1"; private static final String CRYPTO_ALGO = "HmacSHA1";
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TwoFactor.class);
/** /**
* Creates a link to a QR barcode with the provided secret. * Creates a link to a QR barcode with the provided secret.
* *
@ -71,7 +74,7 @@ public class TwoFactor extends UnsaltedMethod {
try { try {
return checkPassword(hashedPassword.getHash(), password); return checkPassword(hashedPassword.getHash(), password);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Failed to verify two auth code:", e); logger.logException("Failed to verify two auth code:", e);
return false; return false;
} }
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.security.crypts;
import at.favre.lib.crypto.bcrypt.BCrypt; import at.favre.lib.crypto.bcrypt.BCrypt;
import at.favre.lib.crypto.bcrypt.IllegalBCryptFormatException; import at.favre.lib.crypto.bcrypt.IllegalBCryptFormatException;
import fr.xephi.authme.ConsoleLogger; 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.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType; import fr.xephi.authme.security.crypts.description.SaltType;
@ -19,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
@HasSalt(value = SaltType.TEXT, length = SALT_LENGTH_ENCODED) @HasSalt(value = SaltType.TEXT, length = SALT_LENGTH_ENCODED)
public class Wbb4 implements EncryptionMethod { public class Wbb4 implements EncryptionMethod {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Wbb4.class);
private BCryptHasher bCryptHasher = new BCryptHasher(BCrypt.Version.VERSION_2A, 8); private BCryptHasher bCryptHasher = new BCryptHasher(BCrypt.Version.VERSION_2A, 8);
private SecureRandom random = new SecureRandom(); private SecureRandom random = new SecureRandom();
@ -44,7 +46,7 @@ public class Wbb4 implements EncryptionMethod {
String computedHash = hashInternal(password, salt); String computedHash = hashInternal(password, salt);
return isEqual(hashedPassword.getHash(), computedHash); return isEqual(hashedPassword.getHash(), computedHash);
} catch (IllegalBCryptFormatException | IllegalArgumentException e) { } catch (IllegalBCryptFormatException | IllegalArgumentException e) {
ConsoleLogger.logException("Invalid WBB4 hash:", e); logger.logException("Invalid WBB4 hash:", e);
} }
return false; return false;
} }

View File

@ -59,7 +59,7 @@ public class GenerateTotpService implements HasCleanup {
*/ */
public boolean isTotpCodeCorrectForGeneratedTotpKey(Player player, String totpCode) { public boolean isTotpCodeCorrectForGeneratedTotpKey(Player player, String totpCode) {
TotpGenerationResult totpDetails = totpKeys.get(player.getName().toLowerCase()); TotpGenerationResult totpDetails = totpKeys.get(player.getName().toLowerCase());
return totpDetails != null && totpAuthenticator.checkCode(totpDetails.getTotpKey(), totpCode); return totpDetails != null && totpAuthenticator.checkCode(player.getName(), totpDetails.getTotpKey(), totpCode);
} }
@Override @Override

View File

@ -1,28 +1,37 @@
package fr.xephi.authme.security.totp; package fr.xephi.authme.security.totp;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.warrenstrange.googleauth.GoogleAuthenticator; import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey; import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator; import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
import com.warrenstrange.googleauth.IGoogleAuthenticator; import com.warrenstrange.googleauth.IGoogleAuthenticator;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
import static fr.xephi.authme.util.Utils.MILLIS_PER_MINUTE;
/** /**
* Provides TOTP functions (wrapping a third-party TOTP implementation). * Provides TOTP functions (wrapping a third-party TOTP implementation).
*/ */
public class TotpAuthenticator { public class TotpAuthenticator implements HasCleanup {
private static final int CODE_RETENTION_MINUTES = 5;
private final IGoogleAuthenticator authenticator; private final IGoogleAuthenticator authenticator;
private final BukkitService bukkitService; private final Settings settings;
private final Table<String, Integer, Long> usedCodes = HashBasedTable.create();
@Inject @Inject
TotpAuthenticator(BukkitService bukkitService) { TotpAuthenticator(Settings settings) {
this.authenticator = createGoogleAuthenticator(); this.authenticator = createGoogleAuthenticator();
this.bukkitService = bukkitService; this.settings = settings;
} }
/** /**
@ -33,28 +42,41 @@ public class TotpAuthenticator {
} }
public boolean checkCode(PlayerAuth auth, String totpCode) { public boolean checkCode(PlayerAuth auth, String totpCode) {
return checkCode(auth.getTotpKey(), totpCode); return checkCode(auth.getNickname(), auth.getTotpKey(), totpCode);
} }
/** /**
* Returns whether the given input code matches for the provided TOTP key. * Returns whether the given input code matches for the provided TOTP key.
* *
* @param playerName the player name
* @param totpKey the key to check with * @param totpKey the key to check with
* @param inputCode the input code to verify * @param inputCode the input code to verify
* @return true if code is valid, false otherwise * @return true if code is valid, false otherwise
*/ */
public boolean checkCode(String totpKey, String inputCode) { public boolean checkCode(String playerName, String totpKey, String inputCode) {
String nameLower = playerName.toLowerCase();
Integer totpCode = Ints.tryParse(inputCode); Integer totpCode = Ints.tryParse(inputCode);
return totpCode != null && authenticator.authorize(totpKey, totpCode); if (totpCode != null && !usedCodes.contains(nameLower, totpCode)
&& authenticator.authorize(totpKey, totpCode)) {
usedCodes.put(nameLower, totpCode, System.currentTimeMillis());
return true;
}
return false;
} }
public TotpGenerationResult generateTotpKey(Player player) { public TotpGenerationResult generateTotpKey(Player player) {
GoogleAuthenticatorKey credentials = authenticator.createCredentials(); GoogleAuthenticatorKey credentials = authenticator.createCredentials();
String qrCodeUrl = GoogleAuthenticatorQRGenerator.getOtpAuthURL( String qrCodeUrl = GoogleAuthenticatorQRGenerator.getOtpAuthURL(
bukkitService.getIp(), player.getName(), credentials); settings.getProperty(PluginSettings.SERVER_NAME), player.getName(), credentials);
return new TotpGenerationResult(credentials.getKey(), qrCodeUrl); return new TotpGenerationResult(credentials.getKey(), qrCodeUrl);
} }
@Override
public void performCleanup() {
long threshold = System.currentTimeMillis() - CODE_RETENTION_MINUTES * MILLIS_PER_MINUTE;
usedCodes.values().removeIf(value -> value < threshold);
}
public static final class TotpGenerationResult { public static final class TotpGenerationResult {
private final String totpKey; private final String totpKey;
private final String authenticatorQrCodeUrl; private final String authenticatorQrCodeUrl;

View File

@ -3,6 +3,8 @@ package fr.xephi.authme.service;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.BackupSettings; import fr.xephi.authme.settings.properties.BackupSettings;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
@ -25,10 +27,13 @@ import static fr.xephi.authme.util.Utils.logAndSendWarning;
*/ */
public class BackupService { public class BackupService {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
private final File dataFolder; private final File dataFolder;
private final File backupFolder; private final File backupFolder;
private final Settings settings; private final Settings settings;
/** /**
* Constructor. * Constructor.
* *
@ -89,7 +94,7 @@ public class BackupService {
String dbName = settings.getProperty(DatabaseSettings.MYSQL_DATABASE); String dbName = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
return performFileBackup(dbName + ".db"); return performFileBackup(dbName + ".db");
default: default:
ConsoleLogger.warning("Unknown data source type '" + dataSourceType + "' for backup"); logger.warning("Unknown data source type '" + dataSourceType + "' for backup");
} }
return false; return false;
@ -114,13 +119,13 @@ public class BackupService {
Process runtimeProcess = Runtime.getRuntime().exec(backupCommand); Process runtimeProcess = Runtime.getRuntime().exec(backupCommand);
int processComplete = runtimeProcess.waitFor(); int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) { if (processComplete == 0) {
ConsoleLogger.info("Backup created successfully. (Using Windows = " + isUsingWindows + ")"); logger.info("Backup created successfully. (Using Windows = " + isUsingWindows + ")");
return true; return true;
} else { } else {
ConsoleLogger.warning("Could not create the backup! (Using Windows = " + isUsingWindows + ")"); logger.warning("Could not create the backup! (Using Windows = " + isUsingWindows + ")");
} }
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
ConsoleLogger.logException("Error during backup (using Windows = " + isUsingWindows + "):", e); logger.logException("Error during backup (using Windows = " + isUsingWindows + "):", e);
} }
return false; return false;
} }
@ -133,7 +138,7 @@ public class BackupService {
copy(new File(dataFolder, filename), backupFile); copy(new File(dataFolder, filename), backupFile);
return true; return true;
} catch (IOException ex) { } catch (IOException ex) {
ConsoleLogger.logException("Encountered an error during file backup:", ex); logger.logException("Encountered an error during file backup:", ex);
} }
return false; return false;
} }
@ -145,13 +150,13 @@ public class BackupService {
* @param windowsPath The path to check * @param windowsPath The path to check
* @return True if the path is correct, false if it is incorrect or the OS is not Windows * @return True if the path is correct, false if it is incorrect or the OS is not Windows
*/ */
private static boolean useWindowsCommand(String windowsPath) { private boolean useWindowsCommand(String windowsPath) {
String isWin = System.getProperty("os.name").toLowerCase(); String isWin = System.getProperty("os.name").toLowerCase();
if (isWin.contains("win")) { if (isWin.contains("win")) {
if (new File(windowsPath + "\\bin\\mysqldump.exe").exists()) { if (new File(windowsPath + "\\bin\\mysqldump.exe").exists()) {
return true; return true;
} else { } else {
ConsoleLogger.warning("Mysql Windows Path is incorrect. Please check it"); logger.warning("Mysql Windows Path is incorrect. Please check it");
return false; return false;
} }
} }

View File

@ -19,7 +19,6 @@ import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject; import javax.inject.Inject;
import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.Optional; import java.util.Optional;
@ -37,7 +36,6 @@ public class BukkitService implements SettingsDependent {
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND; public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
private final AuthMe authMe; private final AuthMe authMe;
private Method getOnlinePlayers;
private boolean useAsyncTasks; private boolean useAsyncTasks;
@Inject @Inject
@ -235,8 +233,9 @@ public class BukkitService implements SettingsDependent {
* *
* @return collection of online players * @return collection of online players
*/ */
public Collection<? extends Player> getOnlinePlayers() { @SuppressWarnings("unchecked")
return Bukkit.getOnlinePlayers(); public Collection<Player> getOnlinePlayers() {
return (Collection<Player>) Bukkit.getOnlinePlayers();
} }
/** /**

View File

@ -15,6 +15,7 @@ import com.maxmind.db.model.Country;
import com.maxmind.db.model.CountryResponse; import com.maxmind.db.model.CountryResponse;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.InternetProtocolUtils; import fr.xephi.authme.util.InternetProtocolUtils;
@ -61,6 +62,7 @@ public class GeoIpService {
// but every HTTP implementation have to support RFC 1023 // but every HTTP implementation have to support RFC 1023
private static final String TIME_RFC_1023 = "EEE, dd-MMM-yy HH:mm:ss zzz"; private static final String TIME_RFC_1023 = "EEE, dd-MMM-yy HH:mm:ss zzz";
private final ConsoleLogger logger = ConsoleLoggerFactory.get(GeoIpService.class);
private final Path dataFile; private final Path dataFile;
private final BukkitService bukkitService; private final BukkitService bukkitService;
@ -109,10 +111,10 @@ public class GeoIpService {
// don't fire the update task - we are up to date // don't fire the update task - we are up to date
return true; return true;
} else { } else {
ConsoleLogger.debug("GEO IP database is older than " + UPDATE_INTERVAL_DAYS + " Days"); logger.debug("GEO IP database is older than " + UPDATE_INTERVAL_DAYS + " Days");
} }
} catch (IOException ioEx) { } catch (IOException ioEx) {
ConsoleLogger.logException("Failed to load GeoLiteAPI database", ioEx); logger.logException("Failed to load GeoLiteAPI database", ioEx);
return false; return false;
} }
} }
@ -130,7 +132,7 @@ public class GeoIpService {
* Tries to update the database by downloading a new version from the website. * Tries to update the database by downloading a new version from the website.
*/ */
private void updateDatabase() { private void updateDatabase() {
ConsoleLogger.info("Downloading GEO IP database, because the old database is older than " logger.info("Downloading GEO IP database, because the old database is older than "
+ UPDATE_INTERVAL_DAYS + " days or doesn't exist"); + UPDATE_INTERVAL_DAYS + " days or doesn't exist");
Path tempFile = null; Path tempFile = null;
@ -138,7 +140,7 @@ public class GeoIpService {
// download database to temporarily location // download database to temporarily location
tempFile = Files.createTempFile(ARCHIVE_FILE, null); tempFile = Files.createTempFile(ARCHIVE_FILE, null);
if (!downloadDatabaseArchive(tempFile)) { if (!downloadDatabaseArchive(tempFile)) {
ConsoleLogger.info("There is no newer GEO IP database uploaded to MaxMind. Using the old one for now."); logger.info("There is no newer GEO IP database uploaded to MaxMind. Using the old one for now.");
startReading(); startReading();
return; return;
} }
@ -151,10 +153,10 @@ public class GeoIpService {
extractDatabase(tempFile, dataFile); extractDatabase(tempFile, dataFile);
//only set this value to false on success otherwise errors could lead to endless download triggers //only set this value to false on success otherwise errors could lead to endless download triggers
ConsoleLogger.info("Successfully downloaded new GEO IP database to " + dataFile); logger.info("Successfully downloaded new GEO IP database to " + dataFile);
startReading(); startReading();
} catch (IOException ioEx) { } catch (IOException ioEx) {
ConsoleLogger.logException("Could not download GeoLiteAPI database", ioEx); logger.logException("Could not download GeoLiteAPI database", ioEx);
} finally { } finally {
// clean up // clean up
if (tempFile != null) { if (tempFile != null) {
@ -165,7 +167,7 @@ public class GeoIpService {
private void startReading() throws IOException { private void startReading() throws IOException {
databaseReader = new Reader(dataFile.toFile(), FileMode.MEMORY, new CHMCache()); databaseReader = new Reader(dataFile.toFile(), FileMode.MEMORY, new CHMCache());
ConsoleLogger.info(LICENSE); logger.info(LICENSE);
// clear downloading flag, because we now have working reader instance // clear downloading flag, because we now have working reader instance
downloading = false; downloading = false;
@ -315,7 +317,7 @@ public class GeoIpService {
// Ignore invalid ip addresses // Ignore invalid ip addresses
// Legacy GEO IP Database returned a unknown country object with Country-Code: '--' and Country-Name: 'N/A' // Legacy GEO IP Database returned a unknown country object with Country-Code: '--' and Country-Name: 'N/A'
} catch (IOException ioEx) { } catch (IOException ioEx) {
ConsoleLogger.logException("Cannot lookup country for " + ip + " at GEO IP database", ioEx); logger.logException("Cannot lookup country for " + ip + " at GEO IP database", ioEx);
} }
return Optional.empty(); return Optional.empty();

View File

@ -8,6 +8,7 @@ import fr.xephi.authme.command.help.HelpMessage;
import fr.xephi.authme.command.help.HelpMessagesService; import fr.xephi.authme.command.help.HelpMessagesService;
import fr.xephi.authme.command.help.HelpSection; import fr.xephi.authme.command.help.HelpSection;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.message.MessagePathHelper;
import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
@ -49,7 +50,7 @@ public class HelpTranslationGenerator {
*/ */
public File updateHelpFile() throws IOException { public File updateHelpFile() throws IOException {
String languageCode = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); String languageCode = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE);
File helpFile = new File(dataFolder, "messages/help_" + languageCode + ".yml"); File helpFile = new File(dataFolder, MessagePathHelper.createHelpMessageFilePath(languageCode));
Map<String, Object> helpEntries = generateHelpMessageEntries(); Map<String, Object> helpEntries = generateHelpMessageEntries();
String helpEntriesYaml = exportToYaml(helpEntries); String helpEntriesYaml = exportToYaml(helpEntries);

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.service;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.security.crypts.Sha256; import fr.xephi.authme.security.crypts.Sha256;
@ -16,6 +17,8 @@ import java.util.List;
*/ */
public final class MigrationService { public final class MigrationService {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(MigrationService.class);
private MigrationService() { private MigrationService() {
} }
@ -29,14 +32,14 @@ public final class MigrationService {
public static void changePlainTextToSha256(Settings settings, DataSource dataSource, public static void changePlainTextToSha256(Settings settings, DataSource dataSource,
Sha256 authmeSha256) { Sha256 authmeSha256) {
if (HashAlgorithm.PLAINTEXT == settings.getProperty(SecuritySettings.PASSWORD_HASH)) { if (HashAlgorithm.PLAINTEXT == settings.getProperty(SecuritySettings.PASSWORD_HASH)) {
ConsoleLogger.warning("Your HashAlgorithm has been detected as plaintext and is now deprecated;" logger.warning("Your HashAlgorithm has been detected as plaintext and is now deprecated;"
+ " it will be changed and hashed now to the AuthMe default hashing method"); + " it will be changed and hashed now to the AuthMe default hashing method");
ConsoleLogger.warning("Don't stop your server; wait for the conversion to have been completed!"); logger.warning("Don't stop your server; wait for the conversion to have been completed!");
List<PlayerAuth> allAuths = dataSource.getAllAuths(); List<PlayerAuth> allAuths = dataSource.getAllAuths();
for (PlayerAuth auth : allAuths) { for (PlayerAuth auth : allAuths) {
String hash = auth.getPassword().getHash(); String hash = auth.getPassword().getHash();
if (hash.startsWith("$SHA$")) { if (hash.startsWith("$SHA$")) {
ConsoleLogger.warning("Skipping conversion for " + auth.getNickname() + "; detected SHA hash"); logger.warning("Skipping conversion for " + auth.getNickname() + "; detected SHA hash");
} else { } else {
HashedPassword hashedPassword = authmeSha256.computeHash(hash, auth.getNickname()); HashedPassword hashedPassword = authmeSha256.computeHash(hash, auth.getNickname());
auth.setPassword(hashedPassword); auth.setPassword(hashedPassword);
@ -45,7 +48,7 @@ public final class MigrationService {
} }
settings.setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256); settings.setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
settings.save(); settings.save();
ConsoleLogger.info("Migrated " + allAuths.size() + " accounts from plaintext to SHA256"); logger.info("Migrated " + allAuths.size() + " accounts from plaintext to SHA256");
} }
} }
} }

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.HasCleanup; import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
@ -28,6 +29,8 @@ import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWOR
*/ */
public class PasswordRecoveryService implements Reloadable, HasCleanup { public class PasswordRecoveryService implements Reloadable, HasCleanup {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PasswordRecoveryService.class);
@Inject @Inject
private CommonService commonService; private CommonService commonService;
@ -95,7 +98,7 @@ public class PasswordRecoveryService implements Reloadable, HasCleanup {
String thePass = RandomStringUtils.generate(commonService.getProperty(RECOVERY_PASSWORD_LENGTH)); String thePass = RandomStringUtils.generate(commonService.getProperty(RECOVERY_PASSWORD_LENGTH));
HashedPassword hashNew = passwordSecurity.computeHash(thePass, name); HashedPassword hashNew = passwordSecurity.computeHash(thePass, name);
ConsoleLogger.info("Generating new password for '" + name + "'"); logger.info("Generating new password for '" + name + "'");
dataSource.updatePassword(name, hashNew); dataSource.updatePassword(name, hashNew);
boolean couldSendMail = emailService.sendPasswordMail(name, email, thePass); boolean couldSendMail = emailService.sendPasswordMail(name, email, thePass);

Some files were not shown because too many files have changed in this diff Show More