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:**
- <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>
```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:**
![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
##### Sponsor:
[FastVM.io](https://fastvm.io) is leader in VPS hosting solutions. With its own DataCenter offers Anti-DDoS solutions at affordable prices.
##### 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>

View File

@ -1,5 +1,5 @@
<!-- 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
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`
- **/authme getip** &lt;player>: Get the IP address of the specified online player.
<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.
<br />Requires `authme.admin.spawn`
- **/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 -->
<!-- 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
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.
```yml
DataSource:
# What type of database do you want to use?
# Valid values: SQLITE, MYSQL
backend: 'SQLITE'
# Valid values: SQLITE, MYSQL, POSTGRESQL
backend: SQLITE
# Enable the database caching system, should be disabled on bungeecord environments
# or when a website integration is being used.
caching: true
# Database host address
mySQLHost: '127.0.0.1'
mySQLHost: 127.0.0.1
# Database port
mySQLPort: '3306'
# Connect to MySQL database over SSL
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
mySQLUsername: 'authme'
mySQLUsername: authme
# Password to connect to the MySQL database
mySQLPassword: '12345'
# Database Name, use with converters or as SQLITE database name
mySQLDatabase: 'authme'
mySQLDatabase: authme
# Table of the database
mySQLTablename: 'authme'
mySQLTablename: authme
# Column of IDs to sort data
mySQLColumnId: 'id'
mySQLColumnId: id
# Column for storing or checking players nickname
mySQLColumnName: 'username'
mySQLColumnName: username
# Column for storing or checking players RealName
mySQLRealName: 'realname'
mySQLRealName: realname
# Column for storing players passwords
mySQLColumnPassword: 'password'
mySQLColumnPassword: password
# Column for storing players passwords salts
mySQLColumnSalt: ''
# Column for storing players emails
mySQLColumnEmail: 'email'
mySQLColumnEmail: email
# 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
mySQLColumnHasSession: 'hasSession'
mySQLColumnHasSession: hasSession
# Column for storing a player's TOTP key (for two-factor authentication)
mySQLtotpKey: 'totp'
mySQLtotpKey: totp
# Column for storing the player's last IP
mySQLColumnIp: 'ip'
mySQLColumnIp: ip
# Column for storing players lastlogins
mySQLColumnLastLogin: 'lastlogin'
mySQLColumnLastLogin: lastlogin
# Column storing the registration date
mySQLColumnRegisterDate: 'regdate'
mySQLColumnRegisterDate: regdate
# Column for storing the IP address at the time of registration
mySQLColumnRegisterIp: 'regip'
mySQLColumnRegisterIp: regip
# Column for storing player LastLocation - X
mySQLlastlocX: 'x'
mySQLlastlocX: x
# Column for storing player LastLocation - Y
mySQLlastlocY: 'y'
mySQLlastlocY: y
# Column for storing player LastLocation - Z
mySQLlastlocZ: 'z'
mySQLlastlocZ: z
# Column for storing player LastLocation - World Name
mySQLlastlocWorld: 'world'
mySQLlastlocWorld: world
# Column for storing player LastLocation - Yaw
mySQLlastlocYaw: 'yaw'
mySQLlastlocYaw: yaw
# Column for storing player LastLocation - Pitch
mySQLlastlocPitch: 'pitch'
mySQLlastlocPitch: pitch
# Overrides the size of the DB Connection Pool, default = 10
poolSize: 10
# 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)
bCryptLog2Round: 10
# 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
phpbbActivatedGroupId: 2
# 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
IPBActivatedGroupId: 3
# 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
XFActivatedGroupId: 2
# Wordpress prefix defined during WordPress installation
wordpressTablePrefix: 'wp_'
wordpressTablePrefix: wp_
settings:
sessions:
# Do you want to enable the session feature?
@ -111,13 +114,13 @@ settings:
timeout: 10
# Message language, available languages:
# 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.
forceVaultHook: false
# Log level: INFO, FINE, DEBUG. Use INFO for general messages,
# FINE for some additional detailed ones (like password failed),
# and DEBUG for debugging
logLevel: 'FINE'
logLevel: FINE
# 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
useAsyncTasks: true
@ -125,6 +128,8 @@ settings:
# 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.
useAsyncPreLoginEvent: true
# The name of the server, used in some placeholders.
serverName: Your Minecraft Server
restrictions:
# Can not authenticated players chat?
# Keep in mind that this feature also blocks all commands not
@ -134,14 +139,14 @@ settings:
hideChat: false
# Allowed commands for unauthenticated players
allowCommands:
- '/login'
- '/register'
- '/l'
- '/reg'
- '/email'
- '/captcha'
- '/2fa'
- '/totp'
- /login
- /register
- /l
- /reg
- /email
- /captcha
- /2fa
- /totp
# Max number of allowed registrations per IP
# The value 0 means an unlimited number of registrations!
maxRegPerIp: 1
@ -163,9 +168,9 @@ settings:
# WorldNames where we need to force the spawn location
# Case-sensitive!
worlds:
- 'world'
- 'world_nether'
- 'world_the_end'
- world
- world_nether
- world_the_end
# This option will save the quit location of the players.
SaveQuitLocation: false
# To activate the restricted user feature you need
@ -207,7 +212,7 @@ settings:
# permission: /authme.admin.accounts
displayOtherAccounts: true
# 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
maxLoginPerIp: 0
# Maximum Join authorized by IP
@ -230,6 +235,14 @@ settings:
# - 'npcPlayer'
# - 'npcPlayer2'
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:
# Minimum length of password
minPasswordLength: 5
@ -240,7 +253,7 @@ settings:
# PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, CUSTOM (for developers only). See full list at
# https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md
# If you use ARGON2, check that you have the argon2 c library on your system
passwordHash: 'SHA256'
passwordHash: SHA256
# If a password check fails, AuthMe will also try to check with the following hash methods.
# Use this setting when you change from one hash method to another.
# AuthMe will update the password to the new hash. Example:
@ -259,12 +272,12 @@ settings:
# - 'help'
unsafePasswords:
- '123456'
- 'password'
- 'qwerty'
- password
- qwerty
- '12345'
- '54321'
- '123456789'
- 'help'
- help
registration:
# Enable registration on the server?
enabled: true
@ -278,12 +291,12 @@ settings:
# PASSWORD = account is registered with a password supplied by the user;
# EMAIL = password is generated and sent to the email provided by the user.
# More info at https://github.com/AuthMe/AuthMeReloaded/wiki/Registration
type: 'PASSWORD'
type: PASSWORD
# Second argument the /register command should take: NONE = no 2nd argument
# CONFIRMATION = must repeat first argument (pass or email)
# EMAIL_OPTIONAL = for password register: 2nd argument can be empty or have email address
# EMAIL_MANDATORY = for password register: 2nd argument MUST be an email address
secondArg: 'CONFIRMATION'
secondArg: CONFIRMATION
# Do we force kick a player after a successful registration?
# Do not use with login feature below
forceKickAfterRegister: false
@ -339,7 +352,7 @@ GroupOptions:
unregisteredPlayerGroup: ''
Email:
# Email SMTP server host
mailSMTP: 'smtp.gmail.com'
mailSMTP: smtp.gmail.com
# Email SMTP server port
mailPort: 465
# Only affects port 25: enable TLS/STARTTLS?
@ -355,7 +368,7 @@ Email:
# Recovery password length
RecoveryPasswordLength: 8
# Mail Subject
mailSubject: 'Your new AuthMe password'
mailSubject: Your new AuthMe password
# Like maxRegPerIP but with email
maxRegPerEmail: 1
# Recall players to add an email?
@ -364,7 +377,7 @@ Email:
delayRecall: 5
# Blacklist these domains for emails
emailBlacklisted:
- '10minutemail.com'
- 10minutemail.com
# Whitelist ONLY these domains for emails
emailWhitelisted: []
# Send the new password drawn in an image?
@ -389,14 +402,16 @@ Protection:
enableProtectionRegistered: true
# Countries allowed to join the server and register. For country codes, see
# https://dev.maxmind.com/geoip/legacy/codes/iso3166/
# Use "LOCALHOST" for local addresses.
# PLEASE USE QUOTES!
countries:
- 'US'
- 'GB'
- US
- GB
- LOCALHOST
# Countries not allowed to join the server and register
# PLEASE USE QUOTES!
countriesBlacklist:
- 'A1'
- A1
# Do we need to enable automatic antibot system?
enableAntiBot: true
# The interval in seconds
@ -421,7 +436,7 @@ Purge:
# Do we need to remove the Essentials/userdata/player.yml file during purge process?
removeEssentialsFile: false
# World in which the players.dat are stored
defaultWorld: 'world'
defaultWorld: world
# Remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge?
removeLimitedCreativesInventories: false
# Do we need to remove the AntiXRayData/PlayerData/player file during purge process?
@ -498,7 +513,7 @@ limbo:
# DISABLED: no disk storage,
# INDIVIDUAL_FILES: each player data in its own file,
# DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below
type: 'INDIVIDUAL_FILES'
type: INDIVIDUAL_FILES
# This setting only affects DISTRIBUTED_FILES persistence. The distributed file
# persistence attempts to reduce the number of files by distributing players into various
# buckets based on their UUID. This setting defines into how many files the players should
@ -508,20 +523,20 @@ limbo:
# 6.25 players per file (100 / 16).
# Note: if you change this setting all data will be migrated. If you have a lot of data,
# change this setting only on server restart, not with /authme reload.
distributionSize: 'SIXTEEN'
distributionSize: SIXTEEN
# Whether the player is allowed to fly: RESTORE, ENABLE, DISABLE, NOTHING.
# RESTORE sets back the old property from the player. NOTHING will prevent AuthMe
# from modifying the 'allow flight' property on the player.
restoreAllowFlight: 'RESTORE'
restoreAllowFlight: RESTORE
# Restore fly speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.
# RESTORE: restore the speed the player had;
# DEFAULT: always set to default speed;
# MAX_RESTORE: take the maximum of the player's current speed and the previous one
# RESTORE_NO_ZERO: Like 'restore' but sets speed to default if the player's speed was 0
restoreFlySpeed: 'RESTORE_NO_ZERO'
restoreFlySpeed: RESTORE_NO_ZERO
# Restore walk speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.
# See above for a description of the values.
restoreWalkSpeed: 'RESTORE_NO_ZERO'
restoreWalkSpeed: RESTORE_NO_ZERO
BackupSystem:
# General configuration for backups: if false, no backups are possible
ActivateBackup: false
@ -530,19 +545,19 @@ BackupSystem:
# Create backup at every stop of server
OnServerStop: true
# 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:
Rakamak:
# Rakamak file name
fileName: 'users.rak'
fileName: users.rak
# Rakamak use IP?
useIP: false
# Rakamak IP file name
ipFileName: 'UsersIp.rak'
ipFileName: UsersIp.rak
CrazyLogin:
# CrazyLogin database file name
fileName: 'accounts.db'
fileName: accounts.db
loginSecurity:
# LoginSecurity: convert from SQLite; if false we use MySQL
useSqlite: true
@ -555,6 +570,7 @@ Converter:
user: ''
# LoginSecurity MySQL: password for database user
password: ''
```
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 -->
<!-- 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
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 -->
<!-- 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
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.spawn** Administrator command to teleport to the AuthMe spawn.
- **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.updatemessages** Permission to use the update messages command.
- **authme.allowchatbeforelogin** Permission to send chat messages before being logged in.
- **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.bypassbungeesend** Permission node to bypass BungeeCord server teleportation.
- **authme.bypasscountrycheck** Permission to bypass the GeoIp country code check.
- **authme.bypassforcesurvival** Permission for users to bypass force-survival mode.
- **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 -->
<!-- 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
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;
---- | -------- | ---------: | ------
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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 | 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 | 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://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://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://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://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 | 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://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://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 | 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://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 | 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 | 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://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 | 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://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://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://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://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://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 | 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://via.placeholder.com/80x7/aaaa11?text=%20" alt="80" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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" />
[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>
<artifactId>authme</artifactId>
<version>5.5.1-SNAPSHOT</version>
<version>5.6.0-SNAPSHOT</version>
<name>AuthMeReloaded</name>
<description>The first authentication plugin for the Bukkit API!</description>
@ -64,7 +64,7 @@
<maven.minimumVersion>3.3.9</maven.minimumVersion>
<!-- Dependencies versions -->
<spigot.version>1.13.2-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.14.2-R0.1-SNAPSHOT</spigot.version>
<!-- Versioning properties -->
<project.outputName>AuthMe</project.outputName>
@ -105,6 +105,21 @@
<project.skipExtendedHashTests>true</project.skipExtendedHashTests>
</properties>
</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>
<build>
@ -131,6 +146,16 @@
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- Enforce build environment -->
<plugin>
@ -170,7 +195,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
@ -180,7 +205,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</version>
<version>0.8.4</version>
<executions>
<execution>
<id>pre-unit-test</id>
@ -200,7 +225,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<version>2.22.2</version>
<configuration>
<!-- Force the right file encoding during unit testing -->
<!-- Set language to English in order to get consistent results for localized time formatting -->
@ -216,15 +241,16 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<version>3.1.2</version>
</plugin>
<!-- Generate a jar containing the source javadoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<finalName>${project.finalNameBase}</finalName>
<!-- In sync with the source/target properties of the maven-compiler-plugin -->
<source>8</source>
</configuration>
<executions>
<execution>
@ -239,7 +265,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<version>3.1.0</version>
<configuration>
<finalName>${project.finalNameBase}</finalName>
</configuration>
@ -362,7 +388,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
<version>3.8.2</version>
</plugin>
<!-- Publish coveralls test coverage reports, not included in the build cycle by default -->
<plugin>
@ -382,36 +408,102 @@
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<!-- CodeMC Repo (Contains many required libraries) -->
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<!-- EssentialsX Repo -->
<repository>
<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>
<!-- ProtocolLib Repo -->
<repository>
<id>dmulloy2-repo</id>
<url>http://repo.dmulloy2.net/content/groups/public/</url>
<id>dmulloy2-repo-releases</id>
<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>
<!-- Multiverse Repo -->
<repository>
<id>onarandombox-repo</id>
<url>http://repo.onarandombox.com/content/groups/public</url>
<id>onarandombox-repo-releases</id>
<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>
<!-- Vault Repo -->
<repository>
<id>vault-repo</id>
<id>vault-repo-releases</id>
<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>
</repositories>
@ -477,7 +569,7 @@
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.2.0</version>
<version>3.3.1</version>
<optional>true</optional>
<exclusions>
<exclusion>
@ -490,7 +582,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<version>1.7.27</version>
<optional>true</optional>
</dependency>
@ -498,7 +590,7 @@
<dependency>
<groupId>de.rtner</groupId>
<artifactId>PBKDF2</artifactId>
<version>1.1.2</version>
<version>1.1.4</version>
<optional>true</optional>
</dependency>
@ -560,7 +652,7 @@
<dependency>
<groupId>ch.jalu</groupId>
<artifactId>configme</artifactId>
<version>1.0.1</version>
<version>1.1.0</version>
<optional>true</optional>
<exclusions>
<exclusion>
@ -600,7 +692,7 @@
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>4.3</version>
<version>4.4</version>
<scope>provided</scope>
</dependency>
@ -611,93 +703,27 @@
<version>1.23.5-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>net.gravitydevelopment.updater</groupId>
<artifactId>updater</artifactId>
</exclusion>
<exclusion>
<artifactId>commons-dbcp</artifactId>
<groupId>commons-dbcp</groupId>
</exclusion>
<exclusion>
<artifactId>AccountsClient</artifactId>
<artifactId>accounts-client</artifactId>
<groupId>com.mojang</groupId>
</exclusion>
</exclusions>
</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 -->
<dependency>
<groupId>org.tyrannyofheaven.bukkit</groupId>
<artifactId>zPermissions</artifactId>
<version>1.4-SNAPSHOT</version>
<version>1.4.3-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<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>
</exclusion>
<exclusion>
<artifactId>persistence-api</artifactId>
<groupId>javax.persistence</groupId>
<artifactId>ebean</artifactId>
</exclusion>
</exclusions>
</dependency>
@ -724,7 +750,7 @@
<dependency>
<groupId>com.onarandombox.multiversecore</groupId>
<artifactId>Multiverse-Core</artifactId>
<version>2.6.0</version>
<version>4.0.1</version>
<type>jar</type>
<scope>provided</scope>
<exclusions>
@ -787,15 +813,49 @@
<dependency>
<groupId>net.ess3</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.15.0</version>
<version>2.16.1</version>
<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>
<!-- BCrypt implementation -->
<dependency>
<groupId>at.favre.lib</groupId>
<artifactId>bcrypt</artifactId>
<version>0.6.0</version>
<version>0.8.0</version>
<optional>true</optional>
</dependency>
@ -803,42 +863,8 @@
<dependency>
<groupId>de.luricos.bukkit</groupId>
<artifactId>xAuth</artifactId>
<version>2.6</version>
<version>2.6.1-SNAPSHOT</version>
<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>
@ -851,7 +877,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
<version>42.2.6</version>
</dependency>
<!-- Unit Testing Libraries -->
@ -874,7 +900,7 @@
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
<version>2.23.4</version>
<version>3.0.0</version>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
@ -887,7 +913,7 @@
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>2.5.8</version>
<version>2.10.0</version>
<scope>test</scope>
</dependency>
@ -895,13 +921,13 @@
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.25.2</version>
<version>3.28.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
<version>1.4.199</version>
<scope>test</scope>
</dependency>

View File

@ -6,8 +6,20 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.*;
import fr.xephi.authme.listener.*;
import fr.xephi.authme.initialization.DataFolder;
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.service.BackupService;
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 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 pluginBuildNumber = "Unknown";
@ -56,6 +68,7 @@ public class AuthMe extends JavaPlugin {
private BukkitService bukkitService;
private Injector injector;
private BackupService backupService;
private ConsoleLogger logger;
/**
* Constructor.
@ -67,8 +80,7 @@ public class AuthMe extends JavaPlugin {
* Constructor for unit testing.
*/
@VisibleForTesting
@SuppressWarnings("deprecation") // the super constructor is deprecated to mark it for unit testing only
protected AuthMe(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
AuthMe(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file);
}
@ -109,14 +121,14 @@ public class AuthMe extends JavaPlugin {
// Check server version
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();
return;
}
// Prevent running AuthMeBridge due to major exploit issues
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!");
stopOrUnload();
return;
@ -128,9 +140,10 @@ public class AuthMe extends JavaPlugin {
} catch (Throwable th) {
YamlParseException yamlParseException = ExceptionUtils.findThrowableInCause(YamlParseException.class, th);
if (yamlParseException == null) {
ConsoleLogger.logException("Aborting initialization of AuthMe:", th);
logger.logException("Aborting initialization of AuthMe:", th);
th.printStackTrace();
} 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);
}
stopOrUnload();
@ -146,14 +159,8 @@ public class AuthMe extends JavaPlugin {
// Set up Metrics
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
ConsoleLogger.info("AuthMe " + getPluginVersion() + " build n." + getPluginBuildNumber()
+ " correctly enabled!");
logger.info("AuthMe " + getPluginVersion() + " build n." + getPluginBuildNumber() + " successfully enabled!");
// Purge on start if enabled
PurgeService purgeService = injector.getSingleton(PurgeService.class);
@ -185,8 +192,7 @@ public class AuthMe extends JavaPlugin {
*/
private void initialize() {
// Set the Logger instance and log file path
ConsoleLogger.setLogger(getLogger());
ConsoleLogger.setLogFile(new File(getDataFolder(), LOG_FILENAME));
ConsoleLogger.initialize(getLogger(), new File(getDataFolder(), LOG_FILENAME));
// Check java version
if (!SystemUtils.isJavaVersionAtLeast(1.8f)) {
@ -210,7 +216,8 @@ public class AuthMe extends JavaPlugin {
// Get settings and set up logger
settings = injector.getSingleton(Settings.class);
ConsoleLogger.setLoggingOptions(settings);
ConsoleLoggerFactory.reloadSettings(settings);
logger = ConsoleLoggerFactory.get(AuthMe.class);
OnStartupTasks onStartupTasks = injector.newInstance(OnStartupTasks.class);
onStartupTasks.setupConsoleFilter(settings, getLogger());
@ -287,7 +294,7 @@ public class AuthMe extends JavaPlugin {
*/
public void stopOrUnload() {
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);
getServer().shutdown();
} else {
@ -314,8 +321,8 @@ public class AuthMe extends JavaPlugin {
new TaskCloser(this, database).run();
// Disabled correctly
ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!");
ConsoleLogger.close();
logger.info("AuthMe " + this.getDescription().getVersion() + " disabled!");
ConsoleLogger.closeFileWriter();
}
/**

View File

@ -1,15 +1,19 @@
package fr.xephi.authme;
import com.google.common.base.Throwables;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.ExceptionUtils;
import java.io.Closeable;
import java.io.File;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@ -20,64 +24,73 @@ import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* The plugin's static logger.
* AuthMe logger.
*/
public final class ConsoleLogger {
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 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
// --------
/**
* Set the logger to use.
*
* @param logger The logger
*/
public static void setLogger(Logger logger) {
public static void initialize(Logger logger, File logFile) {
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;
}
/**
* 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) {
ConsoleLogger.logLevel = settings.getProperty(PluginSettings.LOG_LEVEL);
ConsoleLogger.useLogging = settings.getProperty(SecuritySettings.USE_LOGGING);
public static void initializeSharedSettings(Settings settings) {
boolean useLogging = settings.getProperty(SecuritySettings.USE_LOGGING);
if (useLogging) {
if (fileWriter == null) {
try {
fileWriter = new FileWriter(logFile, true);
} catch (IOException e) {
ConsoleLogger.logException("Failed to create the log file:", e);
}
}
initializeFileWriter();
} 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
@ -88,7 +101,7 @@ public final class ConsoleLogger {
*
* @param message The message to log
*/
public static void warning(String message) {
public void warning(String message) {
logger.warning(message);
writeLog("[WARN] " + message);
}
@ -100,7 +113,7 @@ public final class ConsoleLogger {
* @param message The message to accompany the exception
* @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));
writeLog(Throwables.getStackTraceAsString(th));
}
@ -110,7 +123,7 @@ public final class ConsoleLogger {
*
* @param message The message to log
*/
public static void info(String message) {
public void info(String message) {
logger.info(message);
writeLog("[INFO] " + message);
}
@ -123,7 +136,7 @@ public final class ConsoleLogger {
*
* @param message The message to log
*/
public static void fine(String message) {
public void fine(String message) {
if (logLevel.includes(LogLevel.FINE)) {
logger.info(message);
writeLog("[FINE] " + message);
@ -142,7 +155,7 @@ public final class ConsoleLogger {
*
* @param message The message to log
*/
public static void debug(String message) {
public void debug(String message) {
if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + message;
logger.info(debugMessage);
@ -155,7 +168,7 @@ public final class ConsoleLogger {
*
* @param msgSupplier the message supplier
*/
public static void debug(Supplier<String> msgSupplier) {
public void debug(Supplier<String> msgSupplier) {
if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + msgSupplier.get();
logger.info(debugMessage);
@ -169,7 +182,7 @@ public final class ConsoleLogger {
* @param message 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)) {
String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, param1);
@ -185,7 +198,7 @@ public final class ConsoleLogger {
* @param param2 second param to replace in message
*/
// 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)) {
debug(message, new Object[]{param1, param2});
}
@ -197,7 +210,7 @@ public final class ConsoleLogger {
* @param message 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)) {
String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, params);
@ -206,21 +219,21 @@ public final class ConsoleLogger {
}
}
// --------
// Helpers
// --------
/**
* Close all file handles.
* Closes the file writer.
*/
public static void close() {
public static void closeFileWriter() {
if (fileWriter != null) {
try {
fileWriter.flush();
fileWriter.close();
fileWriter = null;
} 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
*/
private static void writeLog(String message) {
if (useLogging) {
if (fileWriter != null) {
String dateTime;
synchronized (DATE_FORMAT) {
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.SpawnCommand;
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.UpdateHelpMessagesCommand;
import fr.xephi.authme.command.executable.authme.VersionCommand;
@ -295,6 +297,28 @@ public class CommandInitializer {
.executableCommand(GetIpCommand.class)
.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
CommandDescription.builder()
.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.VAuthConverter;
import fr.xephi.authme.datasource.converter.XAuthConverter;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
@ -31,6 +32,8 @@ public class ConverterCommand implements ExecutableCommand {
@VisibleForTesting
static final Map<String, Class<? extends Converter>> CONVERTERS = getConverters();
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ConverterCommand.class);
@Inject
private CommonService commonService;
@ -59,7 +62,7 @@ public class ConverterCommand implements ExecutableCommand {
converter.execute(sender);
} catch (Exception e) {
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.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword;
@ -22,6 +23,8 @@ import java.util.List;
*/
public class RegisterAdminCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RegisterAdminCommand.class);
@Inject
private PasswordSecurity passwordSecurity;
@ -70,7 +73,7 @@ public class RegisterAdminCommand implements ExecutableCommand {
}
commonService.send(sender, MessageKey.REGISTER_SUCCESS);
ConsoleLogger.info(sender.getName() + " registered " + playerName);
logger.info(sender.getName() + " registered " + playerName);
final Player player = bukkitService.getPlayerExact(playerName);
if (player != null) {
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() ->

View File

@ -7,6 +7,7 @@ import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.Settings;
@ -23,6 +24,8 @@ import java.util.List;
*/
public class ReloadCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ReloadCommand.class);
@Inject
private AuthMe plugin;
@ -48,7 +51,7 @@ public class ReloadCommand implements ExecutableCommand {
public void executeCommand(CommandSender sender, List<String> arguments) {
try {
settings.reload();
ConsoleLogger.setLoggingOptions(settings);
ConsoleLoggerFactory.reloadSettings(settings);
settingsWarner.logWarningsForMisconfigurations();
// 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);
} catch (Exception e) {
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();
}
}

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.command.ExecutableCommand;
import fr.xephi.authme.command.help.HelpMessagesService;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.HelpTranslationGenerator;
import org.bukkit.command.CommandSender;
@ -17,6 +18,8 @@ import java.util.List;
*/
public class UpdateHelpMessagesCommand implements ExecutableCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(UpdateHelpMessagesCommand.class);
@Inject
private HelpTranslationGenerator helpTranslationGenerator;
@Inject
@ -30,7 +33,7 @@ public class UpdateHelpMessagesCommand implements ExecutableCommand {
helpMessagesService.reloadMessagesFile();
} catch (IOException e) {
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()
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
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, "Lucas J.", "ljacqu", "Main 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"
+ ChatColor.GRAY + ChatColor.ITALIC + " (See LICENSE file)");
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
*/
private static void printDeveloper(CommandSender sender, String name, String minecraftName, String function,
Collection<? extends Player> onlinePlayers) {
Collection<Player> onlinePlayers) {
// Print the name
StringBuilder msg = new StringBuilder();
msg.append(" ")
@ -77,7 +77,7 @@ public class VersionCommand implements ExecutableCommand {
*
* @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) {
if (player.getName().equalsIgnoreCase(minecraftName)) {
return true;

View File

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

View File

@ -5,6 +5,7 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
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 DEFAULT_VALUE_SUFFIX = ChatColor.GOLD + "#" + ChatColor.RESET;
private ConsoleLogger logger = ConsoleLoggerFactory.get(MySqlDefaultChanger.class);
@Inject
private Settings settings;
@ -98,7 +101,7 @@ class MySqlDefaultChanger implements DebugSection {
throw new IllegalStateException("Unknown operation '" + operation + "'");
}
} 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
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() + "'");
}
@ -168,7 +171,7 @@ class MySqlDefaultChanger implements DebugSection {
+ "') to be NULL, modifying " + updatedRows + " entries");
// 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() + "'");
}
@ -191,7 +194,7 @@ class MySqlDefaultChanger implements DebugSection {
+ " (" + columnName + "): " + isNullText + ", " + defaultText);
}
} 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");
}
@ -228,7 +231,7 @@ class MySqlDefaultChanger implements DebugSection {
}
return String.join(ChatColor.RESET + ", ", formattedColumns);
} 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.";
}
}

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.authme.debug;
import ch.jalu.datasourcecolumns.data.DataSourceValue;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.SendMailSsl;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
@ -22,6 +23,8 @@ import java.util.List;
*/
class TestEmailSender implements DebugSection {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TestEmailSender.class);
@Inject
private DataSource dataSource;
@ -110,7 +113,7 @@ class TestEmailSender implements DebugSection {
try {
htmlEmail = sendMailSsl.initializeMail(email);
} 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;
}

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword;
@ -20,6 +21,8 @@ import java.util.List;
*/
public class EmailSetPasswordCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailSetPasswordCommand.class);
@Inject
private DataSource dataSource;
@ -46,7 +49,7 @@ public class EmailSetPasswordCommand extends PlayerCommand {
HashedPassword hashedPassword = passwordSecurity.computeHash(password, name);
dataSource.updatePassword(name, hashedPassword);
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);
} else {
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.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService;
@ -22,6 +23,8 @@ import java.util.List;
*/
public class RecoverEmailCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RecoverEmailCommand.class);
@Inject
private CommonService commonService;
@ -49,7 +52,7 @@ public class RecoverEmailCommand extends PlayerCommand {
final String playerName = player.getName();
if (!emailService.hasAllInformation()) {
ConsoleLogger.warning("Mail API is not set");
logger.warning("Mail API is not set");
commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
return;
}

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.captcha.RegistrationCaptchaManager;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.Management;
@ -34,6 +35,8 @@ import static fr.xephi.authme.settings.properties.RegistrationSettings.REGISTER_
*/
public class RegisterCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RegisterCommand.class);
@Inject
private Management management;
@ -155,7 +158,7 @@ public class RegisterCommand extends PlayerCommand {
private void handleEmailRegistration(Player player, List<String> arguments) {
if (!emailService.hasAllInformation()) {
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());
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.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.security.totp.GenerateTotpService;
@ -19,6 +20,8 @@ import java.util.List;
*/
public class ConfirmTotpCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ConfirmTotpCommand.class);
@Inject
private GenerateTotpService generateTotpService;
@ -63,7 +66,7 @@ public class ConfirmTotpCommand extends PlayerCommand {
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_SUCCESS);
auth.setTotpKey(totpDetails.getTotpKey());
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 {
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.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.security.totp.TotpAuthenticator;
@ -18,6 +19,8 @@ import java.util.List;
*/
public class RemoveTotpCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RemoveTotpCommand.class);
@Inject
private DataSource dataSource;
@ -51,7 +54,7 @@ public class RemoveTotpCommand extends PlayerCommand {
auth.setTotpKey(null);
playerCache.updatePlayer(auth);
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 {
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.LimboService;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.process.login.AsynchronousLogin;
@ -22,6 +23,8 @@ import java.util.List;
*/
public class TotpCodeCommand extends PlayerCommand {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TotpCodeCommand.class);
@Inject
private LimboService limboService;
@ -57,7 +60,7 @@ public class TotpCodeCommand extends PlayerCommand {
if (limbo != null && limbo.getState() == LimboPlayerState.TOTP_REQUIRED) {
processCode(player, auth, arguments.get(0));
} 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()));
messages.send(player, MessageKey.LOGIN_MESSAGE);
}
@ -66,10 +69,10 @@ public class TotpCodeCommand extends PlayerCommand {
private void processCode(Player player, PlayerAuth auth, String inputCode) {
boolean isCodeValid = totpAuthenticator.checkCode(auth, inputCode);
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);
} 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);
}
}

View File

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

View File

@ -5,6 +5,7 @@ import org.bukkit.Location;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
@ -40,6 +41,7 @@ public class PlayerAuth {
private String world;
private float yaw;
private float pitch;
private UUID uuid;
/**
* Hidden constructor.
@ -169,6 +171,14 @@ public class PlayerAuth {
this.totpKey = totpKey;
}
public UUID getUuid() {
return uuid;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PlayerAuth)) {
@ -193,7 +203,8 @@ public class PlayerAuth {
+ " ! LastLogin : " + lastLogin
+ " ! LastPosition : " + x + "," + y + "," + z + "," + world
+ " ! Email : " + email
+ " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}";
+ " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}"
+ " ! UUID : " + uuid;
}
public static Builder builder() {
@ -218,6 +229,7 @@ public class PlayerAuth {
private String world;
private float yaw;
private float pitch;
private UUID uuid;
/**
* Creates a PlayerAuth object.
@ -243,6 +255,7 @@ public class PlayerAuth {
auth.world = Optional.ofNullable(world).orElse("world");
auth.yaw = yaw;
auth.pitch = pitch;
auth.uuid = uuid;
return auth;
}
@ -349,5 +362,10 @@ public class PlayerAuth {
this.registrationDate = date;
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.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
@ -26,6 +27,8 @@ import java.util.Collections;
*/
class AuthGroupHandler implements Reloadable {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AuthGroupHandler.class);
@Inject
private PermissionsManager permissionsManager;
@ -78,7 +81,7 @@ class AuthGroupHandler implements Reloadable {
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));
}
@ -95,7 +98,7 @@ class AuthGroupHandler implements Reloadable {
// Make sure group support is available
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 true;

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.entity.Player;
/**
@ -15,14 +16,14 @@ public enum WalkFlySpeedRestoreType {
RESTORE {
@Override
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)");
player.setFlySpeed(limbo.getFlySpeed());
}
@Override
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)");
player.setWalkSpeed(limbo.getWalkSpeed());
}
@ -36,11 +37,11 @@ public enum WalkFlySpeedRestoreType {
public void restoreFlySpeed(Player player, LimboPlayer limbo) {
float limboFlySpeed = limbo.getFlySpeed();
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)");
player.setFlySpeed(limboFlySpeed);
} 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)");
player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
}
@ -50,11 +51,11 @@ public enum WalkFlySpeedRestoreType {
public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
float limboWalkSpeed = limbo.getWalkSpeed();
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)");
player.setWalkSpeed(limboWalkSpeed);
} 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)");
player.setWalkSpeed(LimboPlayer.DEFAULT_WALK_SPEED);
}
@ -68,7 +69,7 @@ public enum WalkFlySpeedRestoreType {
@Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) {
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)");
player.setFlySpeed(newSpeed);
}
@ -76,7 +77,7 @@ public enum WalkFlySpeedRestoreType {
@Override
public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
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)");
player.setWalkSpeed(newSpeed);
}
@ -88,19 +89,21 @@ public enum WalkFlySpeedRestoreType {
DEFAULT {
@Override
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)");
player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
}
@Override
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)");
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.
*

View File

@ -7,11 +7,11 @@ import com.google.gson.GsonBuilder;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Player;
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 final ConsoleLogger logger = ConsoleLoggerFactory.get(DistributedFilesPersistenceHandler.class);
private final File cacheFolder;
private final Gson gson;
private final SegmentNameBuilder segmentNameBuilder;
@ -104,7 +105,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
try (FileWriter fw = new FileWriter(file)) {
gson.toJson(entries, fw);
} 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 {
return gson.fromJson(Files.asCharSource(file, StandardCharsets.UTF_8).read(), LIMBO_MAP_TYPE);
} catch (Exception e) {
ConsoleLogger.logException("Failed reading '" + file + "':", e);
logger.logException("Failed reading '" + file + "':", e);
}
return null;
}
@ -165,7 +166,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
private void saveToNewSegments(Map<String, LimboPlayer> 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");
for (Map.Entry<String, Map<String, LimboPlayer>> entry : limboBySegment.entrySet()) {
File file = getSegmentFile(entry.getKey());
@ -204,7 +205,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
.filter(f -> isLimboJsonFile(f) && f.length() < 3)
.peek(FileUtils::delete)
.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");
}
private static File[] listFiles(File folder) {
private File[] listFiles(File folder) {
File[] files = folder.listFiles();
if (files == null) {
ConsoleLogger.warning("Could not get files of '" + folder + "'");
logger.warning("Could not get files of '" + folder + "'");
return new File[0];
}
return files;

View File

@ -6,9 +6,9 @@ import com.google.gson.GsonBuilder;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Player;
import javax.inject.Inject;
@ -21,6 +21,8 @@ import java.nio.charset.StandardCharsets;
*/
class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(IndividualFilesPersistenceHandler.class);
private final Gson gson;
private final File cacheDir;
@ -28,7 +30,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
IndividualFilesPersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService) {
cacheDir = new File(dataFolder, "playerdata");
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()
.registerTypeAdapter(LimboPlayer.class, new LimboPlayerSerializer())
@ -49,7 +51,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
String str = Files.asCharSource(file, StandardCharsets.UTF_8).read();
return gson.fromJson(str, LimboPlayer.class);
} 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;
}
}
@ -63,7 +65,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
Files.touch(file);
Files.write(gson.toJson(limboPlayer), file, StandardCharsets.UTF_8);
} 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.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings;
import org.bukkit.entity.Player;
@ -15,6 +16,8 @@ import javax.inject.Inject;
*/
public class LimboPersistence implements SettingsDependent {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LimboPersistence.class);
private final Factory<LimboPersistenceHandler> handlerFactory;
private LimboPersistenceHandler handler;
@ -35,7 +38,7 @@ public class LimboPersistence implements SettingsDependent {
try {
return handler.getLimboPlayer(player);
} 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;
}
@ -50,7 +53,7 @@ public class LimboPersistence implements SettingsDependent {
try {
handler.saveLimboPlayer(player, limbo);
} 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 {
handler.removeLimboPlayer(player);
} 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);
// If we're changing from an existing handler, output a quick hint that nothing is converted.
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());
}

View File

@ -53,7 +53,8 @@ public abstract class AbstractSqlDataSource implements DataSource {
public boolean saveAuth(PlayerAuth auth) {
return columnsHandler.insert(auth,
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

View File

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

View File

@ -30,6 +30,7 @@ public final class Columns {
public final String HAS_SESSION;
public final String REGISTRATION_DATE;
public final String REGISTRATION_IP;
public final String PLAYER_UUID;
public Columns(Settings settings) {
NAME = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME);
@ -52,6 +53,7 @@ public final class Columns {
HAS_SESSION = settings.getProperty(DatabaseSettings.MYSQL_COL_HASSESSION);
REGISTRATION_DATE = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_DATE);
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.mysqlextensions.MySqlExtension;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.util.UuidUtils;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
@ -23,6 +25,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
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
public class MySQL extends AbstractSqlDataSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(MySQL.class);
private boolean useSsl;
private boolean serverCertificateVerification;
private String host;
private String port;
private String username;
@ -55,14 +60,14 @@ public class MySQL extends AbstractSqlDataSource {
this.setConnectionArguments();
} catch (RuntimeException e) {
if (e instanceof IllegalArgumentException) {
ConsoleLogger.warning("Invalid database arguments! Please check your configuration!");
ConsoleLogger.warning("If this error persists, please report it to the developer!");
logger.warning("Invalid database arguments! Please check your configuration!");
logger.warning("If this error persists, please report it to the developer!");
}
if (e instanceof PoolInitializationException) {
ConsoleLogger.warning("Can't initialize database connection! Please check your configuration!");
ConsoleLogger.warning("If this error persists, please report it to the developer!");
logger.warning("Can't initialize database connection! Please check your configuration!");
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;
}
@ -71,8 +76,8 @@ public class MySQL extends AbstractSqlDataSource {
checkTablesAndColumns();
} catch (SQLException e) {
closeConnection();
ConsoleLogger.logException("Can't initialize the MySQL database:", e);
ConsoleLogger.warning("Please check your database settings in the config.yml file!");
logger.logException("Can't initialize the MySQL database:", e);
logger.warning("Please check your database settings in the config.yml file!");
throw e;
}
}
@ -103,6 +108,7 @@ public class MySQL extends AbstractSqlDataSource {
this.poolSize = settings.getProperty(DatabaseSettings.MYSQL_POOL_SIZE);
this.maxLifetime = settings.getProperty(DatabaseSettings.MYSQL_CONNECTION_MAX_LIFETIME);
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
ds.addDataSourceProperty("useSSL", String.valueOf(useSsl));
// Disabling server certificate verification on need
if (!serverCertificateVerification) {
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
}
// Encoding
ds.addDataSourceProperty("characterEncoding", "utf8");
ds.addDataSourceProperty("encoding", "UTF-8");
@ -140,7 +151,7 @@ public class MySQL extends AbstractSqlDataSource {
ds.addDataSourceProperty("prepStmtCacheSize", "275");
ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
ConsoleLogger.info("Connection arguments loaded, Hikari ConnectionPool ready!");
logger.info("Connection arguments loaded, Hikari ConnectionPool ready!");
}
@Override
@ -149,7 +160,7 @@ public class MySQL extends AbstractSqlDataSource {
ds.close();
}
setConnectionArguments();
ConsoleLogger.info("Hikari ConnectionPool arguments reloaded!");
logger.info("Hikari ConnectionPool arguments reloaded!");
}
private Connection getConnection() throws SQLException {
@ -257,8 +268,13 @@ public class MySQL extends AbstractSqlDataSource {
st.executeUpdate("ALTER TABLE " + tableName
+ " 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 {
@ -447,6 +463,8 @@ public class MySQL extends AbstractSqlDataSource {
private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException {
String salt = col.SALT.isEmpty() ? null : row.getString(col.SALT);
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()
.name(row.getString(col.NAME))
.realName(row.getString(col.REAL_NAME))
@ -464,6 +482,7 @@ public class MySQL extends AbstractSqlDataSource {
.locZ(row.getDouble(col.LASTLOC_Z))
.locYaw(row.getFloat(col.LASTLOC_YAW))
.locPitch(row.getFloat(col.LASTLOC_PITCH))
.uuid(uuid)
.build();
}
}

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.datasource;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
@ -12,6 +13,8 @@ import java.sql.Types;
* Performs migrations on the MySQL data source if necessary.
*/
final class MySqlMigrater {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(MySqlMigrater.class);
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",
tableName, col.LAST_IP);
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.");
}
}
@ -53,7 +56,7 @@ final class MySqlMigrater {
final int columnType;
try (ResultSet rs = metaData.getColumns(null, null, tableName, col.LAST_LOGIN)) {
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;
}
columnType = rs.getInt("DATA_TYPE");
@ -75,7 +78,7 @@ final class MySqlMigrater {
*/
private static void migrateLastLoginColumnFromInt(Statement st, String tableName, Columns col) throws SQLException {
// 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);
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);
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.");
}
@ -107,7 +110,7 @@ final class MySqlMigrater {
long currentTimestamp = System.currentTimeMillis();
int updatedRows = st.executeUpdate(String.format("UPDATE %s SET %s = %d;",
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");
}
}

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

View File

@ -4,6 +4,7 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.columnshandler.AuthMeColumnsHandler;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
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
public class SQLite extends AbstractSqlDataSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(SQLite.class);
private final Settings settings;
private final File dataFolder;
private final String database;
@ -57,7 +59,7 @@ public class SQLite extends AbstractSqlDataSource {
this.setup();
this.migrateIfNeeded();
} catch (Exception ex) {
ConsoleLogger.logException("Error during SQLite initialization:", ex);
logger.logException("Error during SQLite initialization:", ex);
throw ex;
}
}
@ -85,7 +87,7 @@ public class SQLite extends AbstractSqlDataSource {
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.columnsHandler = AuthMeColumnsHandler.createForSqlite(con, settings);
}
@ -182,8 +184,13 @@ public class SQLite extends AbstractSqlDataSource {
st.executeUpdate("ALTER TABLE " + tableName
+ " 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.migrateIfNeeded();
} 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();
int updatedRows = st.executeUpdate(String.format("UPDATE %s SET %s = %d;",
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");
}

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.datasource;
import com.google.common.io.Files;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.util.FileUtils;
@ -19,6 +20,7 @@ import java.sql.Statement;
*/
class SqLiteMigrater {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(SqLiteMigrater.class);
private final File dataFolder;
private final String databaseName;
private final String tableName;
@ -53,13 +55,13 @@ class SqLiteMigrater {
* @param sqLite the instance to migrate
*/
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();
ConsoleLogger.info("Made a backup of your database at 'backups/" + backupName + "'");
logger.info("Made a backup of your database at 'backups/" + backupName + "'");
recreateDatabaseWithNewDefinitions(sqLite);
ConsoleLogger.info("SQLite database migrated successfully");
logger.info("SQLite database migrated successfully");
}
private String createBackup() {
@ -104,7 +106,7 @@ class SqLiteMigrater {
+ " CASE WHEN $email = 'your@email.com' THEN NULL ELSE $email END, $isLogged"
+ " FROM " + tempTable + ";";
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 + ";");
}

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.datasource;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
@ -11,6 +12,8 @@ import java.sql.SQLException;
*/
public final class SqlDataSourceUtils {
private static final ConsoleLogger logger = ConsoleLoggerFactory.get(SqlDataSourceUtils.class);
private SqlDataSourceUtils() {
}
@ -20,7 +23,7 @@ public final class SqlDataSourceUtils {
* @param e the exception to log
*/
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) {
return true;
} else if (nullableCode == DatabaseMetaData.columnNullableUnknown) {
ConsoleLogger.warning("Unknown nullable status for column '" + columnName + "'");
logger.warning("Unknown nullable status for column '" + columnName + "'");
}
}
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.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.OPTIONAL;
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(
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
// --------
@ -76,7 +83,6 @@ public final class AuthMeColumns {
public static final DataSourceColumn<Integer> HAS_SESSION = createInteger(
DatabaseSettings.MYSQL_COL_HASSESSION);
private AuthMeColumns() {
}
}

View File

@ -2,8 +2,8 @@ package fr.xephi.authme.datasource.columnshandler;
import fr.xephi.authme.settings.Settings;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Context for resolving the properties of {@link AuthMeColumns} entries.
@ -11,7 +11,7 @@ import java.util.Map;
public class ColumnContext {
private final Settings settings;
private final Map<DataSourceColumn<?>, String> columnNames = new HashMap<>();
private final Map<DataSourceColumn<?>, String> columnNames = new ConcurrentHashMap<>();
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.datasource.DataSource;
import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.command.CommandSender;
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 {
private DataSource destination;
private DataSourceType destinationType;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(MySqlToSqlite.class);
private final DataSource destination;
private final DataSourceType destinationType;
/**
* Constructor.
@ -51,7 +54,7 @@ public abstract class AbstractDataSourceConverter<S extends DataSource> implemen
source = getSource();
} catch (Exception e) {
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;
}
@ -60,7 +63,6 @@ public abstract class AbstractDataSourceConverter<S extends DataSource> implemen
if (destination.isAuthAvailable(auth.getNickname())) {
skippedPlayers.add(auth.getNickname());
} else {
adaptPlayerAuth(auth);
destination.saveAuth(auth);
destination.updateSession(auth);
destination.updateQuitLoc(auth);
@ -75,15 +77,6 @@ public abstract class AbstractDataSourceConverter<S extends DataSource> implemen
+ " 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
* @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.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ConverterSettings;
import org.bukkit.command.CommandSender;
@ -19,6 +20,8 @@ import java.io.IOException;
*/
public class CrazyLoginConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(CrazyLoginConverter.class);
private final DataSource database;
private final Settings settings;
private final File dataFolder;
@ -46,10 +49,10 @@ public class CrazyLoginConverter implements Converter {
migrateAccount(line);
}
}
ConsoleLogger.info("CrazyLogin database has been imported correctly");
logger.info("CrazyLogin database has been imported correctly");
} catch (IOException ex) {
ConsoleLogger.warning("Can't open the crazylogin database file! Does it exist?");
ConsoleLogger.logException("Encountered", ex);
logger.warning("Can't open the crazylogin database file! Does it exist?");
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.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ConverterSettings;
import fr.xephi.authme.util.UuidUtils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
@ -21,6 +23,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
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 {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LoginSecurityConverter.class);
private final File dataFolder;
private final DataSource dataSource;
@ -58,7 +62,7 @@ public class LoginSecurityConverter implements Converter {
}
} catch (SQLException e) {
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);
long regDate = Optional.ofNullable(resultSet.getDate("registration_date"))
.map(Date::getTime).orElse(System.currentTimeMillis());
UUID uuid = UuidUtils.parseUuidSafely(resultSet.getString("unique_user_id"));
return PlayerAuth.builder()
.name(name)
.realName(name)
@ -132,6 +137,7 @@ public class LoginSecurityConverter implements Converter {
.locWorld(resultSet.getString("world"))
.locYaw(resultSet.getFloat("yaw"))
.locPitch(resultSet.getFloat("pitch"))
.uuid(uuid)
.build();
}
@ -185,7 +191,7 @@ public class LoginSecurityConverter implements Converter {
return DriverManager.getConnection(
"jdbc:sqlite:" + path, "trump", "donald");
} catch (SQLException e) {
ConsoleLogger.logException("Could not connect to SQLite database", e);
logger.logException("Could not connect to SQLite database", e);
return null;
}
}
@ -195,7 +201,7 @@ public class LoginSecurityConverter implements Converter {
return DriverManager.getConnection(
"jdbc:mysql://" + mySqlHost + "/" + mySqlDatabase, mySqlUser, mySqlPassword);
} catch (SQLException e) {
ConsoleLogger.logException("Could not connect to SQLite database", e);
logger.logException("Could not connect to SQLite database", e);
return null;
}
}

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.Settings;
@ -25,6 +26,7 @@ import java.util.Map.Entry;
*/
public class RakamakConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RakamakConverter.class);
private final DataSource database;
private final Settings settings;
private final File pluginFolder;
@ -88,7 +90,7 @@ public class RakamakConverter implements Converter {
}
Utils.logAndSendMessage(sender, "Rakamak database has been imported successfully");
} 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.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
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 PASSWORD_PATH = "login.password";
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RoyalAuthConverter.class);
private final AuthMe plugin;
private final DataSource dataSource;
@ -48,7 +52,7 @@ public class RoyalAuthConverter implements Converter {
dataSource.saveAuth(auth);
dataSource.updateSession(auth);
} 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.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
@ -18,6 +19,7 @@ import static fr.xephi.authme.util.FileUtils.makePath;
public class VAuthConverter implements Converter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(VAuthConverter.class);
private final DataSource dataSource;
private final File vAuthPasswordsFile;
@ -58,7 +60,7 @@ public class VAuthConverter implements Converter {
dataSource.saveAuth(auth);
}
} 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.SQLite;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
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.Provider;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
/**
@ -26,6 +26,8 @@ public class DataSourceProvider implements Provider<DataSource> {
private static final int SQLITE_MAX_SIZE = 4000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(DataSourceProvider.class);
@Inject
@DataFolder
private File dataFolder;
@ -46,7 +48,7 @@ public class DataSourceProvider implements Provider<DataSource> {
try {
return createDataSource();
} 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);
}
}
@ -54,11 +56,10 @@ public class DataSourceProvider implements Provider<DataSource> {
/**
* Sets up the data source.
*
* @return the constructed datasource
* @throws SQLException when initialization of a SQL datasource failed
* @throws IOException if flat file cannot be read
* @return the constructed data source
* @throws SQLException when initialization of a SQL data source failed
*/
private DataSource createDataSource() throws SQLException, IOException {
private DataSource createDataSource() throws SQLException {
DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND);
DataSource dataSource;
switch (dataSourceType) {
@ -88,7 +89,7 @@ public class DataSourceProvider implements Provider<DataSource> {
bukkitService.runTaskAsynchronously(() -> {
int accounts = dataSource.getAccountsRegistered();
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!!");
}
});

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.initialization;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.output.ConsoleFilter;
@ -29,6 +30,8 @@ import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
*/
public class OnStartupTasks {
private static ConsoleLogger consoleLogger = ConsoleLoggerFactory.get(OnStartupTasks.class);
@Inject
private DataSource dataSource;
@Inject
@ -61,8 +64,7 @@ public class OnStartupTasks {
/**
* 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) {
// Try to set the log4j filter
@ -71,7 +73,7 @@ public class OnStartupTasks {
setLog4JFilter();
} catch (ClassNotFoundException | NoClassDefFoundError e) {
// 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);
logger.setFilter(filter);
Bukkit.getLogger().setFilter(filter);

View File

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

View File

@ -52,11 +52,11 @@ class ListenerService implements SettingsDependent {
* @return true if the associated event should be canceled, false otherwise
*/
public boolean shouldCancelEvent(Entity entity) {
if (entity == null || !(entity instanceof Player)) {
return false;
if (entity instanceof Player) {
Player player = (Player) entity;
return shouldCancelEvent(player);
}
Player player = (Player) entity;
return shouldCancelEvent(player);
return false;
}
/**

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager;
@ -30,6 +31,8 @@ import java.util.regex.Pattern;
* Service for performing various verifications when a player joins.
*/
public class OnJoinVerifier implements Reloadable {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(OnJoinVerifier.class);
@Inject
private Settings settings;
@ -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
Collection<? extends Player> onlinePlayers = bukkitService.getOnlinePlayers();
Collection<Player> onlinePlayers = bukkitService.getOnlinePlayers();
if (onlinePlayers.size() < server.getMaxPlayers()) {
event.allow();
return false;
@ -139,7 +142,7 @@ public class OnJoinVerifier implements Reloadable {
event.allow();
return false;
} 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));
return true;
}
@ -207,7 +210,7 @@ public class OnJoinVerifier implements Reloadable {
*
* @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) {
if (!permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)) {
return player;

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.QuickCommandsProtectionManager;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
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.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.Inventory;
import org.bukkit.event.player.AsyncPlayerChatEvent;
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 java.util.HashSet;
@ -50,6 +70,8 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAU
*/
public class PlayerListener implements Listener {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PlayerListener.class);
@Inject
private Settings settings;
@Inject
@ -270,7 +292,7 @@ public class PlayerListener implements Listener {
try {
permissionsManager.loadUserData(event.getUniqueId());
} 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
@ -391,12 +413,12 @@ public class PlayerListener implements Listener {
}
}
private boolean isInventoryWhitelisted(Inventory inventory) {
private boolean isInventoryWhitelisted(InventoryView inventory) {
if (inventory == null) {
return false;
}
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)
@ -404,7 +426,7 @@ public class PlayerListener implements Listener {
final HumanEntity player = event.getPlayer();
if (listenerService.shouldCancelEvent(player)
&& !isInventoryWhitelisted(event.getInventory())) {
&& !isInventoryWhitelisted(event.getView())) {
event.setCancelled(true);
/*
@ -418,7 +440,7 @@ public class PlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInventoryClick(InventoryClickEvent event) {
if (listenerService.shouldCancelEvent(event.getWhoClicked())
&& !isInventoryWhitelisted(event.getClickedInventory())) {
&& !isInventoryWhitelisted(event.getView())) {
event.setCancelled(true);
}
}

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.listener;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.service.PluginHookService;
@ -14,8 +15,11 @@ import org.bukkit.event.server.PluginEnableEvent;
import javax.inject.Inject;
/**
* Listener for server events.
*/
public class ServerListener implements Listener {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ServerListener.class);
@Inject
private PluginHookService pluginHookService;
@ -40,20 +44,20 @@ public class ServerListener implements Listener {
if ("Essentials".equalsIgnoreCase(pluginName)) {
pluginHookService.unhookEssentials();
ConsoleLogger.info("Essentials has been disabled: unhooking");
logger.info("Essentials has been disabled: unhooking");
} else if ("CMI".equalsIgnoreCase(pluginName)) {
pluginHookService.unhookCmi();
spawnLoader.unloadCmiSpawn();
ConsoleLogger.info("CMI has been disabled: unhooking");
logger.info("CMI has been disabled: unhooking");
} else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) {
pluginHookService.unhookMultiverse();
ConsoleLogger.info("Multiverse-Core has been disabled: unhooking");
logger.info("Multiverse-Core has been disabled: unhooking");
} else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) {
spawnLoader.unloadEssentialsSpawn();
ConsoleLogger.info("EssentialsSpawn has been disabled: unhooking");
logger.info("EssentialsSpawn has been disabled: unhooking");
} else if ("ProtocolLib".equalsIgnoreCase(pluginName)) {
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.ConsoleLogger;
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.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -45,11 +48,14 @@ class InventoryPacketAdapter extends PacketAdapter {
private static final int MAIN_SIZE = 27;
private static final int HOTBAR_SIZE = 9;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(InventoryPacketAdapter.class);
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);
this.playerCache = playerCache;
this.dataSource = dataSource;
}
@Override
@ -57,14 +63,22 @@ class InventoryPacketAdapter extends PacketAdapter {
Player player = packetEvent.getPlayer();
PacketContainer packet = packetEvent.getPacket();
byte windowId = packet.getIntegers().read(0).byteValue();
if (windowId == PLAYER_INVENTORY && !playerCache.isAuthenticated(player.getName())) {
int windowId = packet.getIntegers().read(0);
if (windowId == PLAYER_INVENTORY && shouldHideInventory(player.getName())) {
packetEvent.setCancelled(true);
}
}
public void register() {
public void register(BukkitService bukkitService) {
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() {
@ -93,7 +107,7 @@ class InventoryPacketAdapter extends PacketAdapter {
try {
protocolManager.sendServerPacket(player, inventoryPacket, false);
} 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.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
@ -15,6 +17,8 @@ import javax.inject.Inject;
@NoFieldScan
public class ProtocolLibService implements SettingsDependent {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProtocolLibService.class);
/* Packet Adapters */
private InventoryPacketAdapter inventoryPacketAdapter;
private TabCompletePacketAdapter tabCompletePacketAdapter;
@ -25,15 +29,18 @@ public class ProtocolLibService implements SettingsDependent {
/* Service */
private boolean isEnabled;
private AuthMe plugin;
private BukkitService bukkitService;
private PlayerCache playerCache;
private final AuthMe plugin;
private final BukkitService bukkitService;
private final PlayerCache playerCache;
private final DataSource dataSource;
@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.bukkitService = bukkitService;
this.playerCache = playerCache;
this.dataSource = dataSource;
reload(settings);
}
@ -44,11 +51,11 @@ public class ProtocolLibService implements SettingsDependent {
// Check if ProtocolLib is enabled on the server.
if (!plugin.getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
if (protectInvBeforeLogin) {
ConsoleLogger.warning("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
logger.warning("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
}
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;
@ -58,8 +65,9 @@ public class ProtocolLibService implements SettingsDependent {
// Set up packet adapters
if (protectInvBeforeLogin) {
if (inventoryPacketAdapter == null) {
inventoryPacketAdapter = new InventoryPacketAdapter(plugin, playerCache);
inventoryPacketAdapter.register();
// register the packet listener and start hiding it for all already online players (reload)
inventoryPacketAdapter = new InventoryPacketAdapter(plugin, playerCache, dataSource);
inventoryPacketAdapter.register(bukkitService);
}
} else if (inventoryPacketAdapter != null) {
inventoryPacketAdapter.unregister();

View File

@ -9,9 +9,11 @@ import com.comphenix.protocol.reflect.FieldAccessException;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.output.ConsoleLoggerFactory;
class TabCompletePacketAdapter extends PacketAdapter {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(TabCompletePacketAdapter.class);
private final PlayerCache playerCache;
TabCompletePacketAdapter(AuthMe plugin, PlayerCache playerCache) {
@ -27,7 +29,7 @@ class TabCompletePacketAdapter extends PacketAdapter {
event.setCancelled(true);
}
} 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.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.settings.Settings;
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.util.FileUtils;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Server;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
@ -22,15 +23,15 @@ import java.io.IOException;
*/
public class EmailService {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
private final File dataFolder;
private final String serverName;
private final Settings settings;
private final SendMailSsl sendMailSsl;
@Inject
EmailService(@DataFolder File dataFolder, Server server, Settings settings, SendMailSsl sendMailSsl) {
EmailService(@DataFolder File dataFolder, Settings settings, SendMailSsl sendMailSsl) {
this.dataFolder = dataFolder;
this.serverName = server.getServerName();
this.settings = settings;
this.sendMailSsl = sendMailSsl;
}
@ -50,7 +51,7 @@ public class EmailService {
*/
public boolean sendPasswordMail(String name, String mailAddress, String newPass) {
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;
}
@ -58,7 +59,7 @@ public class EmailService {
try {
email = sendMailSsl.initializeMail(mailAddress);
} 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;
}
@ -70,7 +71,7 @@ public class EmailService {
file = generatePasswordImage(name, newPass);
mailText = embedImageIntoEmailContent(file, email, mailText);
} catch (IOException | EmailException e) {
ConsoleLogger.logException(
logger.logException(
"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) {
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;
}
@ -98,7 +99,7 @@ public class EmailService {
try {
email = sendMailSsl.initializeMail(mailAddress);
} 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;
}
@ -120,7 +121,7 @@ public class EmailService {
try {
htmlEmail = sendMailSsl.initializeMail(email);
} 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;
}
@ -146,14 +147,14 @@ public class EmailService {
private String replaceTagsForPasswordMail(String mailText, String name, String newPass) {
return mailText
.replace("<playername />", name)
.replace("<servername />", serverName)
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
.replace("<generatedpass />", newPass);
}
private String replaceTagsForVerificationEmail(String mailText, String name, String code, int minutesValid) {
return mailText
.replace("<playername />", name)
.replace("<servername />", serverName)
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
.replace("<generatedcode />", code)
.replace("<minutesvalid />", String.valueOf(minutesValid));
}
@ -161,7 +162,7 @@ public class EmailService {
private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid) {
return mailText
.replace("<playername />", name)
.replace("<servername />", serverName)
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
.replace("<recoverycode />", code)
.replace("<hoursvalid />", String.valueOf(hoursValid));
}

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.mail;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
@ -26,6 +27,8 @@ import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
*/
public class SendMailSsl {
private ConsoleLogger logger = ConsoleLoggerFactory.get(SendMailSsl.class);
@Inject
private Settings settings;
@ -96,14 +99,14 @@ public class SendMailSsl {
email.setHtmlMsg(content);
email.setTextMsg(content);
} 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;
}
try {
email.send();
return true;
} 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;
}
}

View File

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

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.message;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.FileUtils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@ -9,11 +10,15 @@ import javax.inject.Inject;
import java.io.InputStream;
import java.io.InputStreamReader;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
/**
* File handler for the help_xx.yml resource.
*/
public class HelpMessagesFileHandler extends AbstractMessageFileHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(HelpMessagesFileHandler.class);
private FileConfiguration defaultConfiguration;
@Inject // Trigger injection in the superclass
@ -31,7 +36,7 @@ public class HelpMessagesFileHandler extends AbstractMessageFileHandler {
String message = getMessageIfExists(key);
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");
return getDefault(key);
}
@ -57,6 +62,6 @@ public class HelpMessagesFileHandler extends AbstractMessageFileHandler {
@Override
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 fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.util.expiring.Duration;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -37,6 +39,8 @@ public class Messages {
.put(TimeUnit.HOURS, MessageKey.HOURS)
.put(TimeUnit.DAYS, MessageKey.DAYS).build();
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
private MessagesFileHandler messagesFileHandler;
/*
@ -162,7 +166,7 @@ public class Messages {
message = message.replace(tags[i], replacements[i]);
}
} else {
ConsoleLogger.warning("Invalid number of replacements for message key '" + key + "'");
logger.warning("Invalid number of replacements for message key '" + key + "'");
}
return message;
}
@ -185,7 +189,7 @@ public class Messages {
message = message.replace(tags[i], replacements[i]);
}
} else {
ConsoleLogger.warning("Invalid number of replacements for message key '" + key + "'");
logger.warning("Invalid number of replacements for message key '" + key + "'");
}
return message;
}

View File

@ -1,15 +1,20 @@
package fr.xephi.authme.message;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.updater.MessageUpdater;
import javax.inject.Inject;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
/**
* File handler for the messages_xx.yml resource.
*/
public class MessagesFileHandler extends AbstractMessageFileHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(MessagesFileHandler.class);
@Inject
private MessageUpdater messageUpdater;
@ -29,7 +34,7 @@ public class MessagesFileHandler extends AbstractMessageFileHandler {
getUserLanguageFile(), createFilePath(language), createFilePath(DEFAULT_LANGUAGE));
if (hasChange) {
if (isFromReload) {
ConsoleLogger.warning("Migration after reload attempt");
logger.warning("Migration after reload attempt");
} else {
reloadInternal(true);
}
@ -38,6 +43,6 @@ public class MessagesFileHandler extends AbstractMessageFileHandler {
@Override
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.resource.PropertyReader;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.FileUtils;
import java.io.IOException;
@ -14,6 +15,7 @@ import java.io.InputStream;
*/
public class JarMessageSource {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(JarMessageSource.class);
private final PropertyReader localJarMessages;
private final PropertyReader defaultJarMessages;
@ -42,15 +44,15 @@ public class JarMessageSource {
return reader == null ? null : reader.getString(path);
}
private static MessageMigraterPropertyReader loadJarFile(String jarPath) {
private MessageMigraterPropertyReader loadJarFile(String jarPath) {
try (InputStream stream = FileUtils.getResourceFromJar(jarPath)) {
if (stream == null) {
ConsoleLogger.debug("Could not load '" + jarPath + "' from JAR");
logger.debug("Could not load '" + jarPath + "' from JAR");
return null;
}
return MessageMigraterPropertyReader.loadFromStream(stream);
} catch (IOException e) {
ConsoleLogger.logException("Exception while handling JAR path '" + jarPath + "'", e);
logger.logException("Exception while handling JAR path '" + jarPath + "'", e);
}
return null;
}

View File

@ -9,6 +9,7 @@ import ch.jalu.configme.resource.PropertyResource;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.util.FileUtils;
@ -29,6 +30,8 @@ import static java.util.Collections.singletonList;
*/
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.
*
@ -68,7 +71,7 @@ public class MessageUpdater {
backupMessagesFile(userFile);
userResource.exportProperties(configurationData);
ConsoleLogger.debug("Successfully saved {0}", userFile);
logger.debug("Successfully saved {0}", userFile);
return true;
}
return false;
@ -91,7 +94,7 @@ public class MessageUpdater {
private boolean migrateOldKeys(PropertyReader propertyReader, MessageKeyConfigurationData configurationData) {
boolean hasChange = OldMessageKeysMigrater.migrateOldPaths(propertyReader, configurationData);
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;
}
@ -106,7 +109,7 @@ public class MessageUpdater {
}
}
if (!addedKeys.isEmpty()) {
ConsoleLogger.info(
logger.info(
"Added " + addedKeys.size() + " missing keys to your messages_xx.yml file: " + addedKeys);
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"),
/**
* 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.
*/

View File

@ -3,8 +3,8 @@ package fr.xephi.authme.permission;
import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
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.PermissionHandler;
import fr.xephi.authme.permission.handlers.PermissionHandlerException;
@ -41,6 +41,7 @@ import java.util.UUID;
*/
public class PermissionsManager implements Reloadable {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PermissionsManager.class);
private final Server server;
private final PluginManager pluginManager;
private final Settings settings;
@ -79,11 +80,11 @@ public class PermissionsManager implements Reloadable {
if (handler != null) {
// Show a success message and return
this.handler = handler;
ConsoleLogger.info("Hooked into " + PermissionsSystemType.VAULT.getDisplayName() + "!");
logger.info("Hooked into " + PermissionsSystemType.VAULT.getDisplayName() + "!");
return;
}
} catch (PermissionHandlerException e) {
ConsoleLogger.logException("Failed to create Vault hook (forced):", e);
logger.logException("Failed to create Vault hook (forced):", e);
}
} else {
// Loop through all the available permissions system types
@ -93,18 +94,18 @@ public class PermissionsManager implements Reloadable {
if (handler != null) {
// Show a success message and return
this.handler = handler;
ConsoleLogger.info("Hooked into " + type.getDisplayName() + "!");
logger.info("Hooked into " + type.getDisplayName() + "!");
return;
}
} catch (Exception ex) {
// 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
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
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;
}
@ -139,8 +140,6 @@ public class PermissionsManager implements Reloadable {
return new ZPermissionsHandler();
case VAULT:
return new VaultHandler(server);
case B_PERMISSIONS:
return new BPermissionsHandler();
default:
throw new IllegalStateException("Unhandled permission type '" + type + "'");
}
@ -154,7 +153,7 @@ public class PermissionsManager implements Reloadable {
this.handler = null;
// 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) {
// Check if any known permissions system is enabling
if (PermissionsSystemType.isPermissionSystem(pluginName)) {
ConsoleLogger.info(pluginName + " plugin enabled, dynamically updating permissions hooks!");
logger.info(pluginName + " plugin enabled, dynamically updating permissions hooks!");
setup();
}
}
@ -190,7 +189,7 @@ public class PermissionsManager implements Reloadable {
public void onPluginDisable(String pluginName) {
// Check if any known permission system is being disabled
if (PermissionsSystemType.isPermissionSystem(pluginName)) {
ConsoleLogger.info(pluginName + " plugin disabled, updating hooks!");
logger.info(pluginName + " plugin disabled, updating hooks!");
setup();
}
}
@ -457,7 +456,7 @@ public class PermissionsManager implements Reloadable {
try {
loadUserData(offlinePlayer.getUniqueId());
} 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 true;

View File

@ -15,11 +15,6 @@ public enum PermissionsSystemType {
*/
PERMISSIONS_EX("PermissionsEx", "PermissionsEx"),
/**
* bPermissions.
*/
B_PERMISSIONS("bPermissions", "bPermissions"),
/**
* 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;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsSystemType;
import me.lucko.luckperms.LuckPerms;
@ -31,6 +32,7 @@ import java.util.stream.Collectors;
*/
public class LuckPermsHandler implements PermissionHandler {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(LuckPermsHandler.class);
private LuckPermsApi luckPermsApi;
public LuckPermsHandler() throws PermissionHandlerException {
@ -79,7 +81,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean hasPermissionOffline(String name, PermissionNode node) {
User user = luckPermsApi.getUser(name);
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!");
return false;
}
@ -96,7 +98,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean isInGroup(OfflinePlayer player, String group) {
User user = luckPermsApi.getUser(player.getName());
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!");
return false;
}
@ -112,7 +114,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean removeFromGroup(OfflinePlayer player, String group) {
User user = luckPermsApi.getUser(player.getName());
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!");
return false;
}
@ -133,7 +135,7 @@ public class LuckPermsHandler implements PermissionHandler {
public boolean setGroup(OfflinePlayer player, String group) {
User user = luckPermsApi.getUser(player.getName());
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!");
return false;
}
@ -157,7 +159,7 @@ public class LuckPermsHandler implements PermissionHandler {
public List<String> getGroups(OfflinePlayer player) {
User user = luckPermsApi.getUser(player.getName());
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!");
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.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.security.PasswordSecurity;
@ -17,6 +18,8 @@ import org.bukkit.entity.Player;
import javax.inject.Inject;
public class AsyncChangePassword implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsyncChangePassword.class);
@Inject
private DataSource dataSource;
@ -58,7 +61,7 @@ public class AsyncChangePassword implements AsynchronousProcess {
playerCache.updatePlayer(auth);
commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS);
ConsoleLogger.info(player.getName() + " changed his password");
logger.info(player.getName() + " changed his password");
} else {
commonService.send(player, MessageKey.WRONG_PASSWORD);
}
@ -75,7 +78,7 @@ public class AsyncChangePassword implements AsynchronousProcess {
final String lowerCaseName = playerName.toLowerCase();
if (!(playerCache.isAuthenticated(lowerCaseName) || dataSource.isAuthAvailable(lowerCaseName))) {
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 {
commonService.send(sender, MessageKey.UNKNOWN_USER);
}
@ -87,15 +90,15 @@ public class AsyncChangePassword implements AsynchronousProcess {
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_PASSWORD, lowerCaseName);
if (sender != null) {
commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
ConsoleLogger.info(sender.getName() + " changed password of " + lowerCaseName);
logger.info(sender.getName() + " changed password of " + lowerCaseName);
} else {
ConsoleLogger.info("Changed password of " + lowerCaseName);
logger.info("Changed password of " + lowerCaseName);
}
} else {
if (sender != null) {
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.datasource.DataSource;
import fr.xephi.authme.events.EmailChangedEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.service.BukkitService;
@ -22,6 +23,8 @@ import javax.inject.Inject;
*/
public class AsyncAddEmail implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsyncAddEmail.class);
@Inject
private CommonService service;
@ -65,7 +68,7 @@ public class AsyncAddEmail implements AsynchronousProcess {
EmailChangedEvent event = bukkitService.createAndCallEvent(isAsync
-> new EmailChangedEvent(player, null, email, isAsync));
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);
return;
}
@ -75,7 +78,7 @@ public class AsyncAddEmail implements AsynchronousProcess {
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_EMAIL, playerName);
service.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
} else {
ConsoleLogger.warning("Could not save email for player '" + player + "'");
logger.warning("Could not save email for player '" + player + "'");
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.datasource.DataSource;
import fr.xephi.authme.events.EmailChangedEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.service.BukkitService;
@ -20,6 +21,8 @@ import javax.inject.Inject;
* Async task for changing the email.
*/
public class AsyncChangeEmail implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsyncChangeEmail.class);
@Inject
private CommonService service;
@ -83,7 +86,7 @@ public class AsyncChangeEmail implements AsynchronousProcess {
EmailChangedEvent event = bukkitService.createAndCallEvent(isAsync
-> new EmailChangedEvent(player, oldEmail, newEmail, isAsync));
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);
return;
}

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.AsynchronousProcess;
@ -35,6 +36,8 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_IN
* Asynchronous process for when a player joins.
*/
public class AsynchronousJoin implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsynchronousJoin.class);
@Inject
private Server server;
@ -112,7 +115,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
isAsync -> new ProtectInventoryEvent(player, isAsync));
if (ev.isCancelled()) {
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.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.events.FailedLoginEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.AdminPermission;
@ -44,6 +45,8 @@ import java.util.List;
* Asynchronous task for a player login.
*/
public class AsynchronousLogin implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsynchronousLogin.class);
@Inject
private DataSource dataSource;
@ -199,7 +202,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
* @param ip the ip address of the player
*/
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));
if (tempbanManager.shouldTempban(ip)) {
@ -256,7 +259,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
}
ConsoleLogger.fine(player.getName() + " logged in!");
logger.fine(player.getName() + " logged in!");
// makes player loggedin
playerCache.updatePlayer(auth);
@ -270,7 +273,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
// processed in other order.
syncProcessManager.processSyncPlayerLogin(player, isFirstLogin, auths);
} 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) + ".";
ConsoleLogger.fine("The user " + player.getName() + " has " + auths.size() + " accounts:");
ConsoleLogger.fine(message);
logger.fine("The user " + player.getName() + " has " + auths.size() + " accounts:");
logger.fine(message);
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
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.data.limbo.LimboService;
import fr.xephi.authme.events.LogoutEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.message.MessageKey;
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 {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProcessSyncPlayerLogout.class);
@Inject
private CommonService service;
@ -61,7 +64,7 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
bukkitService.callEvent(new LogoutEvent(player));
service.send(player, MessageKey.LOGOUT_SUCCESS);
ConsoleLogger.info(player.getName() + " logged out");
logger.info(player.getName() + " logged out");
}
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.data.limbo.LimboService;
import fr.xephi.authme.events.RegisterEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService;
@ -16,6 +17,8 @@ import javax.inject.Inject;
* Performs synchronous tasks after a successful {@link RegistrationType#EMAIL email registration}.
*/
public class ProcessSyncEmailRegister implements SynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProcessSyncEmailRegister.class);
@Inject
private BukkitService bukkitService;
@ -40,7 +43,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
player.saveData();
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.data.limbo.LimboService;
import fr.xephi.authme.events.RegisterEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService;
@ -21,6 +22,8 @@ import javax.inject.Inject;
*/
public class ProcessSyncPasswordRegister implements SynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(ProcessSyncPasswordRegister.class);
@Inject
private BungeeSender bungeeSender;
@ -66,7 +69,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
player.saveData();
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
if (service.getProperty(RegistrationSettings.FORCE_KICK_AFTER_REGISTER)) {

View File

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

View File

@ -7,6 +7,7 @@ import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.UnregisterByAdminEvent;
import fr.xephi.authme.events.UnregisterByPlayerEvent;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.security.PasswordSecurity;
@ -28,6 +29,8 @@ import javax.inject.Inject;
import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
public class AsynchronousUnregister implements AsynchronousProcess {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AsynchronousUnregister.class);
@Inject
private DataSource dataSource;
@ -72,7 +75,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
if (passwordSecurity.comparePassword(password, cachedAuth.getPassword(), name)) {
if (dataSource.removeAuth(name)) {
performPostUnregisterActions(name, player);
ConsoleLogger.info(name + " unregistered himself");
logger.info(name + " unregistered himself");
bukkitService.createAndCallEvent(isAsync -> new UnregisterByPlayerEvent(player, isAsync));
} else {
service.send(player, MessageKey.ERROR);
@ -97,9 +100,9 @@ public class AsynchronousUnregister implements AsynchronousProcess {
bukkitService.createAndCallEvent(isAsync -> new UnregisterByAdminEvent(player, name, isAsync, initiator));
if (initiator == null) {
ConsoleLogger.info(name + " was unregistered");
logger.info(name + " was unregistered");
} else {
ConsoleLogger.info(name + " was unregistered by " + initiator.getName());
logger.info(name + " was unregistered by " + initiator.getName());
service.send(initiator, MessageKey.UNREGISTERED_SUCCESS);
}
} 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.Argon2Factory;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType;
@ -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
public class Argon2 extends UnsaltedMethod {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(Argon2.class);
private de.mkammerer.argon2.Argon2 argon2;
public Argon2() {
@ -30,7 +33,7 @@ public class Argon2 extends UnsaltedMethod {
System.loadLibrary("argon2");
return true;
} catch (UnsatisfiedLinkError e) {
ConsoleLogger.logException(
logger.logException(
"Cannot find argon2 library: https://github.com/AuthMe/AuthMeReloaded/wiki/Argon2-as-Password-Hash", e);
}
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.PBKDF2Parameters;
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.Usage;
import fr.xephi.authme.settings.Settings;
@ -16,6 +17,7 @@ import javax.inject.Inject;
public class Pbkdf2 extends HexSaltedMethod {
private static final int DEFAULT_ROUNDS = 10_000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Pbkdf2.class);
private int numberOfRounds;
@Inject
@ -41,7 +43,7 @@ public class Pbkdf2 extends HexSaltedMethod {
}
Integer iterations = Ints.tryParse(line[1]);
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;
}

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.PBKDF2Parameters;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.AsciiRestricted;
import java.util.Base64;
@ -12,6 +13,7 @@ import java.util.Base64;
public class Pbkdf2Django extends HexSaltedMethod {
private static final int DEFAULT_ITERATIONS = 24000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Pbkdf2Django.class);
@Override
public String computeHash(String password, String salt, String name) {
@ -30,7 +32,7 @@ public class Pbkdf2Django extends HexSaltedMethod {
}
Integer iterations = Ints.tryParse(line[1]);
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;
}

View File

@ -5,6 +5,7 @@ import com.google.common.io.BaseEncoding;
import com.google.common.net.UrlEscapers;
import com.google.common.primitives.Ints;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType;
@ -34,6 +35,8 @@ public class TwoFactor extends UnsaltedMethod {
private static final int TIME_PRECISION = 3;
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.
@ -71,7 +74,7 @@ public class TwoFactor extends UnsaltedMethod {
try {
return checkPassword(hashedPassword.getHash(), password);
} catch (Exception e) {
ConsoleLogger.logException("Failed to verify two auth code:", e);
logger.logException("Failed to verify two auth code:", e);
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.IllegalBCryptFormatException;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType;
@ -19,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
@HasSalt(value = SaltType.TEXT, length = SALT_LENGTH_ENCODED)
public class Wbb4 implements EncryptionMethod {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Wbb4.class);
private BCryptHasher bCryptHasher = new BCryptHasher(BCrypt.Version.VERSION_2A, 8);
private SecureRandom random = new SecureRandom();
@ -44,7 +46,7 @@ public class Wbb4 implements EncryptionMethod {
String computedHash = hashInternal(password, salt);
return isEqual(hashedPassword.getHash(), computedHash);
} catch (IllegalBCryptFormatException | IllegalArgumentException e) {
ConsoleLogger.logException("Invalid WBB4 hash:", e);
logger.logException("Invalid WBB4 hash:", e);
}
return false;
}

View File

@ -59,7 +59,7 @@ public class GenerateTotpService implements HasCleanup {
*/
public boolean isTotpCodeCorrectForGeneratedTotpKey(Player player, String totpCode) {
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

View File

@ -1,28 +1,37 @@
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.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
import com.warrenstrange.googleauth.IGoogleAuthenticator;
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 javax.inject.Inject;
import static fr.xephi.authme.util.Utils.MILLIS_PER_MINUTE;
/**
* 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 BukkitService bukkitService;
private final Settings settings;
private final Table<String, Integer, Long> usedCodes = HashBasedTable.create();
@Inject
TotpAuthenticator(BukkitService bukkitService) {
TotpAuthenticator(Settings settings) {
this.authenticator = createGoogleAuthenticator();
this.bukkitService = bukkitService;
this.settings = settings;
}
/**
@ -33,28 +42,41 @@ public class TotpAuthenticator {
}
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.
*
* @param playerName the player name
* @param totpKey the key to check with
* @param inputCode the input code to verify
* @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);
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) {
GoogleAuthenticatorKey credentials = authenticator.createCredentials();
String qrCodeUrl = GoogleAuthenticatorQRGenerator.getOtpAuthURL(
bukkitService.getIp(), player.getName(), credentials);
settings.getProperty(PluginSettings.SERVER_NAME), player.getName(), credentials);
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 {
private final String totpKey;
private final String authenticatorQrCodeUrl;

View File

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

View File

@ -19,7 +19,6 @@ import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.Optional;
@ -37,7 +36,6 @@ public class BukkitService implements SettingsDependent {
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
private final AuthMe authMe;
private Method getOnlinePlayers;
private boolean useAsyncTasks;
@Inject
@ -235,8 +233,9 @@ public class BukkitService implements SettingsDependent {
*
* @return collection of online players
*/
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
@SuppressWarnings("unchecked")
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 fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.InternetProtocolUtils;
@ -61,6 +62,7 @@ public class GeoIpService {
// 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 final ConsoleLogger logger = ConsoleLoggerFactory.get(GeoIpService.class);
private final Path dataFile;
private final BukkitService bukkitService;
@ -109,10 +111,10 @@ public class GeoIpService {
// don't fire the update task - we are up to date
return true;
} 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) {
ConsoleLogger.logException("Failed to load GeoLiteAPI database", ioEx);
logger.logException("Failed to load GeoLiteAPI database", ioEx);
return false;
}
}
@ -130,7 +132,7 @@ public class GeoIpService {
* Tries to update the database by downloading a new version from the website.
*/
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");
Path tempFile = null;
@ -138,7 +140,7 @@ public class GeoIpService {
// download database to temporarily location
tempFile = Files.createTempFile(ARCHIVE_FILE, null);
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();
return;
}
@ -151,10 +153,10 @@ public class GeoIpService {
extractDatabase(tempFile, dataFile);
//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();
} catch (IOException ioEx) {
ConsoleLogger.logException("Could not download GeoLiteAPI database", ioEx);
logger.logException("Could not download GeoLiteAPI database", ioEx);
} finally {
// clean up
if (tempFile != null) {
@ -165,7 +167,7 @@ public class GeoIpService {
private void startReading() throws IOException {
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
downloading = false;
@ -315,7 +317,7 @@ public class GeoIpService {
// Ignore invalid ip addresses
// Legacy GEO IP Database returned a unknown country object with Country-Code: '--' and Country-Name: 'N/A'
} 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();

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.HelpSection;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.message.MessagePathHelper;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
@ -49,7 +50,7 @@ public class HelpTranslationGenerator {
*/
public File updateHelpFile() throws IOException {
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();
String helpEntriesYaml = exportToYaml(helpEntries);

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.service;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.security.crypts.Sha256;
@ -15,6 +16,8 @@ import java.util.List;
* Migrations to perform during the initialization of AuthMe.
*/
public final class MigrationService {
private static ConsoleLogger logger = ConsoleLoggerFactory.get(MigrationService.class);
private MigrationService() {
}
@ -29,14 +32,14 @@ public final class MigrationService {
public static void changePlainTextToSha256(Settings settings, DataSource dataSource,
Sha256 authmeSha256) {
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");
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();
for (PlayerAuth auth : allAuths) {
String hash = auth.getPassword().getHash();
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 {
HashedPassword hashedPassword = authmeSha256.computeHash(hash, auth.getNickname());
auth.setPassword(hashedPassword);
@ -45,7 +48,7 @@ public final class MigrationService {
}
settings.setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
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.initialization.HasCleanup;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
@ -27,6 +28,8 @@ import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWOR
* Manager for password recovery.
*/
public class PasswordRecoveryService implements Reloadable, HasCleanup {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(PasswordRecoveryService.class);
@Inject
private CommonService commonService;
@ -95,7 +98,7 @@ public class PasswordRecoveryService implements Reloadable, HasCleanup {
String thePass = RandomStringUtils.generate(commonService.getProperty(RECOVERY_PASSWORD_LENGTH));
HashedPassword hashNew = passwordSecurity.computeHash(thePass, name);
ConsoleLogger.info("Generating new password for '" + name + "'");
logger.info("Generating new password for '" + name + "'");
dataSource.updatePassword(name, hashNew);
boolean couldSendMail = emailService.sendPasswordMail(name, email, thePass);

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