Revert "Packet based movement freeze (#1879)" (#1882)

This reverts commit db3acce70c.
This commit is contained in:
Gabriele C 2019-08-07 10:49:23 +02:00 committed by GitHub
parent db3acce70c
commit 48357831cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1145 additions and 234 deletions

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Mon Aug 05 18:57:10 CEST 2019. 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,
@ -501,7 +501,7 @@ Security:
# Minutes after which a verification code will expire
verificationCodeExpiration: 10
# Before a user logs in, various properties are temporarily removed from the player,
# such as OP status and the ability to fly.
# such as OP status, ability to fly, and walk/fly speed.
# Once the user is logged in, we add back the properties we previously saved.
# In this section, you may define how these properties should be handled.
# Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players
@ -509,7 +509,7 @@ limbo:
persistence:
# Besides storing the data in memory, you can define if/how the data should be persisted
# on disk. This is useful in case of a server crash, so next time the server starts we can
# properly restore things like OP status and the ability to fly
# properly restore things like OP status, ability to fly, and walk/fly speed.
# DISABLED: no disk storage,
# INDIVIDUAL_FILES: each player data in its own file,
# DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below
@ -528,6 +528,15 @@ limbo:
# RESTORE sets back the old property from the player. NOTHING will prevent AuthMe
# from modifying the 'allow flight' property on the player.
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
# Restore walk speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.
# See above for a description of the values.
restoreWalkSpeed: RESTORE_NO_ZERO
BackupSystem:
# General configuration for backups: if false, no backups are possible
ActivateBackup: false
@ -569,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 Aug 05 18:57:10 CEST 2019
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

570
samples/NewConfig.yml Normal file
View File

@ -0,0 +1,570 @@
# =======================================================================================================
# _____ __ .__ _____ __________ .__ .___ .___
# / _ \ __ ___/ |_| |__ / \ ____\______ \ ____ | | _________ __| _/____ __| _/
# / /_\ \| | \ __| | \ / \ / \_/ __ \| __/ __ \| | / _ \__ \ / __ _/ __ \ / __ |
# / | | | /| | | Y / Y \ ___/| | \ ___/| |_( <_> / __ \/ /_/ \ ___// /_/ |
# \____|__ |____/ |__| |___| \____|__ /\___ |____|_ /\___ |____/\____(____ \____ |\___ \____ |
# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
#
# =======================================================================================================
#
# Authme Main Configuration File.
#
# =======================================================================================================
# Plugin infos (overwritten on start, just a simple way to find out your plugin version).
authors: ${pluginAuthors}
version: ${project.version}
buildNumber: ${buildNumber}
# Set this setting to true when you have configured the plugin,
# when false the server will be stopped with a warning message.
enabled: false
# Database settings.
data_source:
# ===========================
# Database general settings.
# ===========================
# Database backend (sqlite, mysql).
backend: sqlite
# Enable database queries caching, should improve performance.
caching: true
# ===========================
# SqLite db parameters.
# ===========================
sqlite:
# The name of the database storage file.
filename: 'authme.db'
# ===========================
# MySql db parameters.
# ===========================
mysql:
# Connection parameters.
host: '127.0.0.1'
port: 3306
username: 'change_me'
password: 'change_me'
database: 'my_minecraft_server'
tablename: 'authme'
# Column names.
column_names:
id: id
# Column for storing nicknames (ignore case nickname).
name: username
# Column for storing the realname (case sensitive nickname).
real_name: realname
# Column for storing passwords.
password: password
# Column for storing email addresses.
email: email
# Column for storing the authentication status (logged or not).
login_status: isLogged
# Column for storing player IPs.
ip: ip
# Column for storing lastlogins date and time.
last_login_timestamp: lastlogin
# Latest logout location of the players.
last_location:
world: world
x: x
y: y
z: z
# Enabled only if the bungeecord integration is activated.
server: world
# Support for registrations via WebInterfaces/CSM.
# Disable some backend caching parameters.
disableAggressiveCaching: false
# Main settings
settings:
# ===========================
# Bungeecord integration
# ===========================
bungeecord:
# Enable bungeecord integration features
enabled: true
# Server name (must be unique, please use the name in the bungeecord configuration).
# Use 'auto' for auto configuration (requires the bungeecord module).
serverName: LoginLobby1
# Keep the auth status when the player moves between servers.
# Required if you're using the bungeecord module.
keepAuthBetweenServers: true
# Target server after login
send_after_login:
enabled: false
message: ''
delay: 5
# Server name ("ServerName") or group ("G:GroupName")
# Groups are avariable only when the bungeecord module is avariable.
# If the server change fails the player will be kicked.
target: Lobby1
failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
# Target server after logout
send_after_logout:
enabled: false
message: ''
delay: 5
# Server name ("ServerName") or group ("G:GroupName")
# Groups are avariable only when the bungeecord module is avariable.
# If the server change fails the player will be kicked.
target: LoginLobby1
failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
# Variables:
# %p playername
bungee_commands:
player_command_after_register:
enabled: false
cmd: ''
console_command_after_register:
enabled: false
cmd: 'alert %p joined for the first time the network!'
player_command_after_login:
enabled: false
cmd: 'glist'
console_command_after_login:
enabled: false
cmd: 'alert %p logged in correctly!'
player_command_after_join:
enabled: false
cmd: ''
console_command_after_join:
enabled: false
cmd: 'alert %p joined the network!'
player_command_first_join:
enabled: false
cmd: ''
console_command_first_join:
enabled: false
cmd: 'alert %p joined for the first time the network!'
# ===========================
# Sessions configuration.
# ===========================
sessions:
# Enable sessions.
# When a player is authenticated, his IP and his nickname is saved.
# The next time the player will join the server, if his IP is the same
# of the last time, and the timeout time hasn't expired, he will be
# automatically authenticated.
enabled: false
# Session timeout.
# 0 for unlimited time (Very dangerous, use it at your own risk!)
# Consider that if player's ip has changed but the timeout hasn't
# expired, player will be kicked out of the sever!
timeout: 10
# When enabled a player's session will expire if someone tries to
# login with a different IP Address.
expire_on_ip_change: true
# ===========================
# Registration settings.
# ===========================
registration:
# After how many time unregistered players should be kicked?
# Set to 0 to disable. (default: 30)
timeout: 30
nickname:
min_length: 4
max_lenght: 16
# Regex syntax.
allowed_characters: '[a-zA-Z0-9_]*'
password:
# Enable double check of password on registration:
# /register <password> <confirmPassword>
double_check: true
# Minimum password lenght.
min_length: 5
# Regex syntax.
allowed_characters: '[\x21-\x7E]*'
# Denied unsafe passwords.
unsafePasswords:
- '123456'
- 'password'
- 'qwerty'
- '12345'
- '54321'
# ===========================
# Login settings.
# ===========================
login:
# After how many time unlogged players should be kicked?
# Set to 0 to disable. (default: 30)
timeout: 30
# ===========================
# Encryption parameters.
# ===========================
password_encryption:
# The hashing algorithm.
# Possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB, MYBB, IPB3,
# PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, DOUBLEMD5,
# PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (developpers only).
encryption_algorithm: SHA256
# The salt length for the SALTED2MD5 and MD5(MD5(password)+salt) algorithms.
md5_salt_length: 8
# If password check fails try all the other hash algorithm.
# AuthMe will update the password to the new passwordHash.
enable_convertion: false
# ===========================
# Unlogged user restrictions.
# ===========================
unlogged_restrictions:
# Deny chat messages send for unlogged users.
deny_chat: true
# Hide chat to unlogged users.
# Only player messages, plugins will be able to send messages to the player anyway.
hide_chat: false
# Deny any command message not in the whitelist below.
deny_commands: true
command_whitelist:
- /login
- /register
- /l
- /reg
- /email
- /captcha
movements:
# Restrict player movements.
restrict: true
# Allowed radius.
allowed_radius: 0
# Should unlogged players have speed = 0?
# After the login the walking/flying speeed will be reset to the default value.
removeSpeed: true
# End is there atm xD
# This option will save the quit location of the players.
SaveQuitLocation: false
# Should not logged in players be teleported to the spawn?
# After the authentication, if SaveQuitLocation is enabled,
# they will be teleported back to their normal position.
teleportUnAuthedToSpawn: false
# If enabled, after the login, if the ForceSpawnOnTheseWorlds setting contains
# the player's world, he will be teleported to the world spawnpoint.
# The quit location of the player will be overwritten.
# This is different from "teleportUnAuthedToSpawn" that teleports player
# back to his quit location after the authentication.
ForceSpawnLocOnJoinEnabled: false
# WorldNames where we need to force the spawn location
# Warning: This setting is Case Sensitive!
ForceSpawnOnTheseWorlds:
- world
- world_nether
- world_the_end
# this is very important options,
# every time player join the server,
# if they are registered, AuthMe will switch him
# to unLoggedInGroup, this
# should prevent all major exploit.
# So you can set up on your Permission Plugin
# this special group with 0 permissions, or permissions to chat,
# or permission to
# send private message or all other perms that you want,
# the better way is to set up
# this group with few permissions,
# so if player try to exploit some account,
# they can
# do anything except what you set in perm Group.
# After a correct logged-in player will be
# moved to his correct permissions group!
# Pay attention group name is case sensitive,
# so Admin is different from admin,
# otherwise your group will be wiped,
# and player join in default group []!
# Example unLoggedinGroup: NotLogged
unLoggedinGroup: unLoggedinGroup
# ===========================
# Address restrictions
# ===========================
# Max number of registrations per IP (default: 1)
maxRegPerIp: 1
# Maximum allowed number of Logins per IP, 0 to disable (default: 0)
maxLoginPerIp: 0
# Maximum allowed number of Joins per IP, 0 to disable (default: 0)
maxJoinPerIp: 0
# When this setting is enabled, online players can't be kicked out
# due to "Logged in from another Location"
# This setting will prevent potetial security exploits.
ForceSingleSession: true
# To activate the restricted user feature you need
# to enable this option and configure the
# AllowedRestrctedUser field.
AllowRestrictedUser: false
# The restricted user feature will kick players listed below
# if they dont match of the defined ip address.
# Example:
# AllowedRestrictedUser:
# - playername;127.0.0.1
AllowedRestrictedUser:
- playername;127.0.0.
# Ban ip when the ip is not the ip registered in database
banUnsafedIP: false
# ===============================
# Other restrictions
# ===============================
# Should we protect the player inventory before logging in?
# Warning: Requires the latest version of ProtocolLib!
ProtectInventoryBeforeLogIn: true
# Should unregistered players be kicked immediately?
kickNonRegistered: false
# Should players be kicked on wrong password?
kickOnWrongPassword: false
# Should we display all other accounts of a player when he joins?
# Required permission: authme.admin.accounts
displayOtherAccounts: true
# ===============================
# Restrictions compatibility
# ===============================
# Spawn Priority. Avariable values : authme, essentials, multiverse, default
spawnPriority: authme,essentials,multiverse,default
# AuthMe will NEVER teleport players!
noTeleport: false
GameMode:
# Do you want to set player's gamemode to survival when he joins?
# This enables also the settings below.
ForceSurvivalMode: false
# Do you want to reset player's inventory if player joins with creative mode?
ResetInventoryIfCreative: false
# Do you want to force the survival mode ONLY after the /login process?
ForceOnlyAfterLogin: false
# sgdc3: Ok, our configuration is shit.... xD Today I will stop there
registration:
# enable registration on the server?
enabled: true
# Send every X seconds a message to a player to
# remind him that he has to login/register
messageInterval: 5
# Only registered and logged in players can play.
# See restrictions for exceptions
force: true
# Does we replace password registration by an Email registration method ?
enableEmailRegistrationSystem: false
# Enable double check of email when you register
# when it's true, registration require that kind of command:
# /register <email> <confirmEmail>
doubleEmailCheck: false
# Do we force kicking player after a successful registration ?
# Do not use with login feature below
forceKickAfterRegister: false
# Does AuthMe need to enforce a /login after a successful registration ?
forceLoginAfterRegister: false
unrestrictions:
# below you can list all your account name, that
# AuthMe will ignore for registration or login, configure it
# at your own risk!! Remember that if you are going to add
# nickname with [], you have to delimit name with ' '.
# this option add compatibility with BuildCraft and some
# other mods.
# It is CaseSensitive!
UnrestrictedName: []
# Message language, available : en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt
messagesLanguage: en
# Force these commands after /login, without any '/', use %p for replace with player name
forceCommands: []
# Force these commands after /login as a server console, without any '/', use %p for replace with player name
forceCommandsAsConsole: []
# Force these commands after /register, without any '/', use %p for replace with player name
forceRegisterCommands: []
# Force these commands after /register as a server console, without any '/', use %p for replace with player name
forceRegisterCommandsAsConsole: []
# Do we need to display the welcome message (welcome.txt) after a register or a login?
# You can use colors in this welcome.txt + some replaced strings :
# {PLAYER} : player name, {ONLINE} : display number of online players, {MAXPLAYERS} : display server slots,
# {IP} : player ip, {LOGINS} : number of players logged, {WORLD} : player current world, {SERVER} : server name
# {VERSION} : get current bukkit version, {COUNTRY} : player country
useWelcomeMessage: true
# Do we need to broadcast the welcome message to all server or only to the player? set true for server or false for player
broadcastWelcomeMessage: false
# Do we need to delay the join/leave message to be displayed only when the player is authenticated ?
delayJoinMessage: false
removeJoinMessage: false
removeLeaveMessage: false
# Do we need to add potion effect Blinding before login/register ?
applyBlindEffect: false
ExternalBoardOptions:
# MySQL column for the salt , needed for some forum/cms support
mySQLColumnSalt: ''
# MySQL column for the group, needed for some forum/cms support
mySQLColumnGroup: ''
# -1 mean disabled. If u want that only
# activated player can login in your server
# u can put in this options the group number
# of unactivated user, needed for some forum/cms support
nonActivedUserGroup: -1
# Other MySQL columns where we need to put the Username (case sensitive)
mySQLOtherUsernameColumns: []
# How much Log to Round needed in BCrypt(do not change it if you do not know what's your doing)
bCryptLog2Round: 10
# phpBB prefix defined during phpbb installation process
phpbbTablePrefix: 'phpbb_'
# phpBB activated group id , 2 is default registered group defined by phpbb
phpbbActivatedGroupId: 2
# WordPress prefix defined during WordPress installation process
wordpressTablePrefix: 'wp_'
permission:
# Take care with this options, if you dont want
# to use Vault and Group Switching of
# AuthMe for unloggedIn players put true
# below, default is false.
EnablePermissionCheck: false
BackupSystem:
# Enable or Disable Automatic Backup
ActivateBackup: false
# set Backup at every start of Server
OnServerStart: false
# set Backup at every stop of Server
OnServerStop: true
# Windows only mysql installation Path
MysqlWindowsPath: 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\'
Security:
SQLProblem:
# Stop the server if we can't contact the sql database
# Take care with this, if you set that to false,
# AuthMe automatically disable and the server is not protected!
stopServer: true
ReloadCommand:
# /reload support
useReloadCommandSupport: true
console:
# Remove spam console
noConsoleSpam: false
captcha:
# Player need to put a captcha when he fails too lot the password
useCaptcha: false
# Max allowed tries before request a captcha
maxLoginTry: 5
# Captcha length
captchaLength: 5
Converter:
Rakamak:
# Rakamak file name
fileName: users.rak
# Rakamak use ip ?
useIP: false
# IP file name for rakamak
ipFileName: UsersIp.rak
CrazyLogin:
# CrazyLogin database file
fileName: accounts.db
Email:
# Email SMTP server host
mailSMTP: smtp.gmail.com
# Email SMTP server port
mailPort: 465
# Email account that send the mail
mailAccount: ''
# Email account password
mailPassword: ''
# Custom SenderName, that replace the mailAccount name in the email
mailSenderName: ''
# Random password length
RecoveryPasswordLength: 8
# Email subject of password get
mailSubject: 'Your new AuthMe Password'
# Email text here
mailText: 'Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword'
# Like maxRegPerIp but with email
maxRegPerEmail: 1
# Recall players to add an email ?
recallPlayers: false
# Delay in minute for the recall scheduler
delayRecall: 5
# Blacklist these domains for emails
emailBlacklisted:
- 10minutemail.com
# WhiteList only these domains for emails
emailWhitelisted: []
# Do we need to send new password draw in an image ?
generateImage: false
Hooks:
# Do we need to hook with multiverse for spawn checking?
multiverse: true
# Do we need to hook with BungeeCord for get the real Player ip ?
bungeecord: false
# Do we need to disable Essentials SocialSpy on join ?
disableSocialSpy: true
# Do we need to force /motd Essentials command on join ?
useEssentialsMotd: false
# Do we need to cache custom Attributes ?
customAttributes: false
Purge:
# On Enable , does AuthMe need to purge automatically old accounts unused ?
useAutoPurge: false
# Number of Days an account become Unused
daysBeforeRemovePlayer: 60
# Do we need to remove the player.dat file during purge process ?
removePlayerDat: false
# Do we need to remove the Essentials/users/player.yml file during purge process ?
removeEssentialsFile: false
# World where are players.dat stores
defaultWorld: 'world'
# Do we need to remove LimitedCreative/inventories/player.yml , player_creative.yml files during purge process ?
removeLimitedCreativesInventories: false
# Do we need to remove the AntiXRayData/PlayerData/player file during purge process ?
removeAntiXRayFile: false
# Do we need to remove permissions ?
removePermissions: false
Protection:
# Enable some servers protection ( country based login, antibot )
enableProtection: false
# Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes
countries:
- US
- GB
# Countries blacklisted automatically ( without any needed to enable protection )
countriesBlacklist:
- A1
# Do we need to enable automatic antibot system?
enableAntiBot: false
# Max number of player allowed to login in 5 secs before enable AntiBot system automatically
antiBotSensibility: 5
# Duration in minutes of the antibot automatic system
antiBotDuration: 10
VeryGames:
# These features are only available on VeryGames Server Provider
enableIpCheck: false

199
samples/NewPlugin.yml Normal file
View File

@ -0,0 +1,199 @@
name: ${pluginName}
authors: [${pluginAuthors}]
website: ${project.url}
description: ${project.description}
main: ${mainClass}
version: ${project.version}-b${buildNumber}
softdepend:
- Vault
- PermissionsBukkit
- PermissionsEX
- EssentialsGroupManager
- Multiverse-Core
- Essentials
- EssentialsSpawn
- ProtocolLib
commands:
authme:
description: AuthMe admin commands
usage: '/authme reload|register playername password|changepassword playername password|unregister playername|version|converter datatype'
permission: authme.admin
register:
description: Register an account
usage: /register password confirmpassword
aliases: [reg]
permission: authme.player.register
login:
description: Login into a account
usage: /login password
aliases: [l,log]
permission: authme.player.login
changepassword:
description: Change password of a account
usage: /changepassword oldPassword newPassword
permission: authme.player.changepassword
logout:
description: Logout from the server
usage: /logout
permission: authme.player.logout
unregister:
description: unregister your account
usage: /unregister password
permission: authme.player.unregister
email:
description: Add Email or recover password
usage: '/email add your@email.com your@email.com|change oldEmail newEmail|recovery your@email.com'
permission: authme.player.email
captcha:
description: Captcha command
usage: /captcha theCaptcha
permission: authme.player.captcha
permissions:
authme.canbeforced:
description: Allow the user to be forced-logged via API
default: true
authme.player:
description: Gives access to all authme player commands
default: true
children:
authme.player.login: true
authme.player.logout: true
authme.player.register: true
authme.player.unregister: true
authme.player.changepassword: true
authme.player.captcha: true
authme.player.email: true
authme.player.register:
description: Register your account
default: false
authme.player.unregister:
description: Unregister your account
default: false
authme.player.login:
description: Login into your account
default: false
authme.player.logout:
description: Logout from your account
default: false
authme.player.changepassword:
description: Change password of your account
default: false
authme.player.email:
description: Gives access to player's email commands
default: false
children:
authme.player.email.add: true
authme.player.email.change: true
authme.player.email.recover: true
authme.player.email.add:
description: Add an email to your account
default: false
authme.player.email.change:
description: Change email of your account
default: false
authme.player.email.recover:
description: Recover your account
default: false
authme.player.captcha:
description: Captcha command
default: false
authme.admin:
description: Gives access to all authme admin commands
default: op
children:
authme.admin.forcelogin: true
authme.admin.forcelogout: true
authme.admin.register: true
authme.admin.unregister: true
authme.admin.changemail: true
authme.admin.changepassword: true
authme.admin.lastlogin: true
authme.admin.accounts: true
authme.admin.getemail: true
authme.admin.getip: true
authme.admin.setspawn: true
authme.admin.spawn: true
authme.admin.setfirstspawn: true
authme.admin.firstspawn: true
authme.admin.purge: true
authme.admin.purgebannedplayers: true
authme.admin.purgelastpos: true
authme.admin.converter: true
authme.admin.reload: true
authme.admin.switchantibot: true
authme.admin.seeotheraccounts: true
authme.admin.register:
description: Register an account
default: false
authme.admin.unregister:
description: Unregister an account
default: false
authme.admin.forcelogin:
description: Force login for that player
default: false
authme.admin.forcelogout:
description: Force logout for that player
default: false
authme.admin.changepassword:
description: Change the password of an account
default: false
authme.admin.getemail:
description: Get last email about a player
default: false
authme.admin.changeemail:
description: Change a player email
default: false
authme.admin.accounts:
description: Display Players Accounts
default: false
authme.admin.seeotheraccounts:
description: Display other accounts about a player when he logs in
default: false
authme.admin.lastlogin:
description: Get last login date about a player
default: false
authme.admin.getip:
description: Get IP from a player (fake and real)
default: false
authme.admin.setspawn:
description: Set the AuthMe spawn point
default: false
authme.admin.spawn:
description: Teleport to AuthMe spawn point
default: false
authme.admin.setfirstspawn:
description: Set the AuthMe First Spawn Point
default: false
authme.admin.firstspawn:
description: Teleport to AuthMe First Spawn Point
default: false
authme.admin.switchantibot:
description: Switch AntiBot mode on/off
default: false
authme.admin.purge:
description: Database purge command
default: false
authme.admin.purgebannedplayers:
description: Purge banned players
default: false
authme.admin.purgelastpos:
description: Purge last position of a player/players
default: false
authme.admin.converter:
description: Allow the /authme converter command
default: false
authme.admin.reload:
description: Reload the plugin
default: false
authme.vip:
description: Allow vip slot when the server is full
default: false
authme.bypassantibot:
description: Bypass the AntiBot check
default: false
authme.allowmultipleaccounts:
description: Allow more accounts for same ip
default: false
authme.bypassforcesurvival:
description: Bypass all ForceSurvival features
default: false

View File

@ -68,7 +68,9 @@ class LimboPlayerViewer implements DebugSection {
sender.sendMessage(ChatColor.BLUE + "Player / limbo / disk limbo info for '" + arguments.get(0) + "'");
new InfoDisplayer(sender, player, memoryLimbo, diskLimbo)
.sendEntry("Is op", Player::isOp, LimboPlayer::isOperator)
.sendEntry("Walk speed", Player::getWalkSpeed, LimboPlayer::getWalkSpeed)
.sendEntry("Can fly", Player::getAllowFlight, LimboPlayer::isCanFly)
.sendEntry("Fly speed", Player::getFlySpeed, LimboPlayer::getFlySpeed)
.sendEntry("Location", p -> formatLocation(p.getLocation()), l -> formatLocation(l.getLocation()))
.sendEntry("Prim. group",
p -> permissionsManager.hasGroupSupport() ? permissionsManager.getPrimaryGroup(p) : "N/A",

View File

@ -12,19 +12,27 @@ import java.util.Collection;
*/
public class LimboPlayer {
public static final float DEFAULT_WALK_SPEED = 0.2f;
public static final float DEFAULT_FLY_SPEED = 0.1f;
private final boolean canFly;
private final boolean operator;
private final Collection<String> groups;
private final Location loc;
private final float walkSpeed;
private final float flySpeed;
private BukkitTask timeoutTask = null;
private MessageTask messageTask = null;
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly) {
public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly, float walkSpeed,
float flySpeed) {
this.loc = loc;
this.operator = operator;
this.groups = groups;
this.canFly = fly;
this.walkSpeed = walkSpeed;
this.flySpeed = flySpeed;
}
/**
@ -58,6 +66,14 @@ public class LimboPlayer {
return canFly;
}
public float getWalkSpeed() {
return walkSpeed;
}
public float getFlySpeed() {
return flySpeed;
}
/**
* Return the timeout task, which kicks the player if he hasn't registered or logged in
* after a configurable amount of time.

View File

@ -14,6 +14,8 @@ import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import static fr.xephi.authme.settings.properties.LimboSettings.RESTORE_ALLOW_FLIGHT;
import static fr.xephi.authme.settings.properties.LimboSettings.RESTORE_FLY_SPEED;
import static fr.xephi.authme.settings.properties.LimboSettings.RESTORE_WALK_SPEED;
/**
* Service for managing players that are in "limbo," a temporary state players are
@ -117,6 +119,8 @@ public class LimboService {
} 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();
logger.debug("Restored LimboPlayer stats for `{0}`", lowerName);
persistence.removeLimboPlayer(player);

View File

@ -5,6 +5,7 @@ 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;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -39,11 +40,13 @@ class LimboServiceHelper {
// For safety reasons an unregistered player should not have OP status after registration
boolean isOperator = isRegistered && player.isOp();
boolean flyEnabled = player.getAllowFlight();
float walkSpeed = player.getWalkSpeed();
float flySpeed = player.getFlySpeed();
Collection<String> playerGroups = permissionsManager.hasGroupSupport()
? permissionsManager.getGroups(player) : Collections.emptyList();
logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups));
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled);
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed);
}
/**
@ -58,12 +61,18 @@ class LimboServiceHelper {
player.setOp(false);
settings.getProperty(LimboSettings.RESTORE_ALLOW_FLIGHT)
.processPlayer(player);
if (!settings.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)) {
player.setFlySpeed(0.0f);
player.setWalkSpeed(0.0f);
}
}
/**
* Merges two existing LimboPlayer instances of a player. Merging is done the following way:
* <ul>
* <li><code>isOperator, allowFlight</code>: true if either limbo has true</li>
* <li><code>flySpeed, walkSpeed</code>: maximum value of either limbo player</li>
* <li><code>groups, location</code>: from old limbo if not empty/null, otherwise from new limbo</li>
* </ul>
*
@ -80,10 +89,12 @@ class LimboServiceHelper {
boolean isOperator = newLimbo.isOperator() || oldLimbo.isOperator();
boolean canFly = newLimbo.isCanFly() || oldLimbo.isCanFly();
float flySpeed = Math.max(newLimbo.getFlySpeed(), oldLimbo.getFlySpeed());
float walkSpeed = Math.max(newLimbo.getWalkSpeed(), oldLimbo.getWalkSpeed());
Collection<String> groups = getLimboGroups(oldLimbo.getGroups(), newLimbo.getGroups());
Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation());
return new LimboPlayer(location, isOperator, groups, canFly);
return new LimboPlayer(location, isOperator, groups, canFly, walkSpeed, flySpeed);
}
private static Location firstNotNull(Location first, Location second) {

View File

@ -0,0 +1,123 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.entity.Player;
/**
* Possible types to restore the walk and fly speed from LimboPlayer
* back to Bukkit Player.
*/
public enum WalkFlySpeedRestoreType {
/**
* Restores from LimboPlayer to Player.
*/
RESTORE {
@Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) {
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) {
logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + " to "
+ limbo.getWalkSpeed() + " (RESTORE mode)");
player.setWalkSpeed(limbo.getWalkSpeed());
}
},
/**
* Restores from LimboPlayer, using the default speed if the speed on LimboPlayer is 0.
*/
RESTORE_NO_ZERO {
@Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) {
float limboFlySpeed = limbo.getFlySpeed();
if (limboFlySpeed > 0.01f) {
logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName() + " to "
+ limboFlySpeed + " (RESTORE_NO_ZERO mode)");
player.setFlySpeed(limboFlySpeed);
} else {
logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName()
+ " to DEFAULT, it was 0! (RESTORE_NO_ZERO mode)");
player.setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
}
}
@Override
public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
float limboWalkSpeed = limbo.getWalkSpeed();
if (limboWalkSpeed > 0.01f) {
logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + " to "
+ limboWalkSpeed + " (RESTORE_NO_ZERO mode)");
player.setWalkSpeed(limboWalkSpeed);
} else {
logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + ""
+ " to DEFAULT, it was 0! (RESTORE_NO_ZERO mode)");
player.setWalkSpeed(LimboPlayer.DEFAULT_WALK_SPEED);
}
}
},
/**
* Uses the max speed of Player (current speed) and the LimboPlayer.
*/
MAX_RESTORE {
@Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) {
float newSpeed = Math.max(player.getFlySpeed(), limbo.getFlySpeed());
logger.debug(() -> "Restoring fly speed for LimboPlayer " + player.getName() + " to " + newSpeed
+ " (Current: " + player.getFlySpeed() + ", Limbo: " + limbo.getFlySpeed() + ") (MAX_RESTORE mode)");
player.setFlySpeed(newSpeed);
}
@Override
public void restoreWalkSpeed(Player player, LimboPlayer limbo) {
float newSpeed = Math.max(player.getWalkSpeed(), limbo.getWalkSpeed());
logger.debug(() -> "Restoring walk speed for LimboPlayer " + player.getName() + " to " + newSpeed
+ " (Current: " + player.getWalkSpeed() + ", Limbo: " + limbo.getWalkSpeed() + ") (MAX_RESTORE mode)");
player.setWalkSpeed(newSpeed);
}
},
/**
* Always sets the default speed to the player.
*/
DEFAULT {
@Override
public void restoreFlySpeed(Player player, LimboPlayer limbo) {
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) {
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.
*
* @param player the player to modify
* @param limbo the limbo player to read from
*/
public abstract void restoreFlySpeed(Player player, LimboPlayer limbo);
/**
* Restores the walk speed from Limbo to Player according to the restoration type.
*
* @param player the player to modify
* @param limbo the limbo player to read from
*/
public abstract void restoreWalkSpeed(Player player, LimboPlayer limbo);
}

View File

@ -18,6 +18,7 @@ import java.util.List;
import java.util.function.Function;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.CAN_FLY;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.FLY_SPEED;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.GROUPS;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.IS_OP;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOCATION;
@ -27,6 +28,7 @@ import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_X
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_Y;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_YAW;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_Z;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.WALK_SPEED;
import static java.util.Optional.ofNullable;
/**
@ -54,8 +56,10 @@ class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {
Collection<String> groups = getLimboGroups(jsonObject);
boolean canFly = getBoolean(jsonObject, CAN_FLY);
float walkSpeed = getFloat(jsonObject, WALK_SPEED, LimboPlayer.DEFAULT_WALK_SPEED);
float flySpeed = getFloat(jsonObject, FLY_SPEED, LimboPlayer.DEFAULT_FLY_SPEED);
return new LimboPlayer(loc, operator, groups, canFly);
return new LimboPlayer(loc, operator, groups, canFly, walkSpeed, flySpeed);
}
private Location deserializeLocation(JsonObject jsonObject) {

View File

@ -26,6 +26,8 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
static final String GROUPS = "groups";
static final String IS_OP = "operator";
static final String CAN_FLY = "can-fly";
static final String WALK_SPEED = "walk-speed";
static final String FLY_SPEED = "fly-speed";
private static final Gson GSON = new Gson();
@ -47,6 +49,8 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
obj.addProperty(IS_OP, limboPlayer.isOperator());
obj.addProperty(CAN_FLY, limboPlayer.isCanFly());
obj.addProperty(WALK_SPEED, limboPlayer.getWalkSpeed());
obj.addProperty(FLY_SPEED, limboPlayer.getFlySpeed());
return obj;
}
}

View File

@ -1,128 +0,0 @@
/*
* Copyright (C) 2015 AuthMe-Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.xephi.authme.listener.protocollib;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedAttribute;
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.entity.Player;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
class FreezePacketAdapter extends PacketAdapter {
private static final String ATTRIBUTE_MOVEMENT_SPEED = "generic.movementSpeed";
private static final String ATTRIBUTE_FLYING_SPEED = "generic.flyingSpeed";
private final ConsoleLogger logger = ConsoleLoggerFactory.get(FreezePacketAdapter.class);
private final PlayerCache playerCache;
private final DataSource dataSource;
FreezePacketAdapter(AuthMe plugin, PlayerCache playerCache, DataSource dataSource) {
super(plugin, PacketType.Play.Server.UPDATE_ATTRIBUTES);
this.playerCache = playerCache;
this.dataSource = dataSource;
}
@Override
public void onPacketSending(PacketEvent packetEvent) {
Player player = packetEvent.getPlayer();
PacketContainer packet = packetEvent.getPacket();
int entityId = packet.getIntegers().read(0);
if (entityId != player.getEntityId()) {
return;
}
if (!shouldFreeze(player.getName())) {
return;
}
List<WrappedAttribute> newAttributes = new ArrayList<>();
for (WrappedAttribute attribute : packet.getAttributeCollectionModifier().read(0)) {
if (ATTRIBUTE_MOVEMENT_SPEED.equals(attribute.getAttributeKey())
|| ATTRIBUTE_FLYING_SPEED.equals(attribute.getAttributeKey())) {
newAttributes.add(WrappedAttribute.newBuilder(attribute)
.baseValue(0.0f).modifiers(Collections.emptyList()).build());
} else {
newAttributes.add(attribute);
}
}
packet.getAttributeCollectionModifier().write(0, newAttributes);
}
protected void register(BukkitService bukkitService) {
ProtocolLibrary.getProtocolManager().addPacketListener(this);
bukkitService.getOnlinePlayers().stream()
.filter(player -> shouldFreeze(player.getName()))
.forEach(this::sendFreezePacket);
}
private boolean shouldFreeze(String playerName) {
return !playerCache.isAuthenticated(playerName) && dataSource.isAuthAvailable(playerName);
}
public void unregister() {
ProtocolLibrary.getProtocolManager().removePacketListener(this);
}
protected void sendFreezePacket(Player player) {
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer attributesPacket = protocolManager.createPacket(PacketType.Play.Server.UPDATE_ATTRIBUTES);
attributesPacket.getIntegers().write(0, player.getEntityId());
attributesPacket.getAttributeCollectionModifier().write(0, Arrays.asList(
WrappedAttribute.newBuilder()
.packet(attributesPacket)
.attributeKey(ATTRIBUTE_MOVEMENT_SPEED)
.baseValue(0.0f)
.build(),
WrappedAttribute.newBuilder()
.packet(attributesPacket)
.attributeKey(ATTRIBUTE_FLYING_SPEED)
.baseValue(0.0f)
.build()
));
try {
protocolManager.sendServerPacket(player, attributesPacket, false);
} catch (InvocationTargetException invocationExc) {
logger.logException("Error during sending freeze packet", invocationExc);
}
}
public void sendUnFreezePacket(Player player) {
player.setWalkSpeed(player.getWalkSpeed());
player.setFlySpeed(player.getFlySpeed());
}
}

View File

@ -22,12 +22,10 @@ public class ProtocolLibService implements SettingsDependent {
/* Packet Adapters */
private InventoryPacketAdapter inventoryPacketAdapter;
private TabCompletePacketAdapter tabCompletePacketAdapter;
private FreezePacketAdapter freezePacketAdapter;
/* Settings */
private boolean protectInvBeforeLogin;
private boolean denyTabCompleteBeforeLogin;
private boolean freezePlayerBeforeLogin;
/* Service */
private boolean isEnabled;
@ -60,11 +58,6 @@ public class ProtocolLibService implements SettingsDependent {
logger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it...");
}
if (freezePlayerBeforeLogin) {
logger.warning("WARNING! In oder to prevent player movements in a nicer way consider"
+ " installing ProtocolLib!");
}
this.isEnabled = false;
return;
}
@ -91,16 +84,6 @@ public class ProtocolLibService implements SettingsDependent {
tabCompletePacketAdapter = null;
}
if (freezePlayerBeforeLogin) {
if (freezePacketAdapter == null) {
freezePacketAdapter = new FreezePacketAdapter(plugin, playerCache, dataSource);
freezePacketAdapter.register(bukkitService);
}
} else if (freezePacketAdapter != null) {
freezePacketAdapter.unregister();
freezePacketAdapter = null;
}
this.isEnabled = true;
}
@ -118,10 +101,6 @@ public class ProtocolLibService implements SettingsDependent {
tabCompletePacketAdapter.unregister();
tabCompletePacketAdapter = null;
}
if (freezePacketAdapter != null) {
freezePacketAdapter.unregister();
freezePacketAdapter = null;
}
}
/**
@ -135,36 +114,12 @@ public class ProtocolLibService implements SettingsDependent {
}
}
/**
* Send a packet to the player to freeze any movement.
*
* @param player The player to send the packet to.
*/
public void sendFreezePacket(Player player) {
if (isEnabled && freezePacketAdapter != null) {
freezePacketAdapter.sendFreezePacket(player);
}
}
/**
* Send a packet to the player to unfreeze movements.
*
* @param player The player to send the packet to.
*/
public void sendUnFreezePacket(Player player) {
if (isEnabled && freezePacketAdapter != null) {
freezePacketAdapter.sendUnFreezePacket(player);
}
}
@Override
public void reload(Settings settings) {
final boolean oldProtectInventory = this.protectInvBeforeLogin;
final boolean oldFreezePlayer = this.freezePlayerBeforeLogin;
boolean oldProtectInventory = this.protectInvBeforeLogin;
this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
this.denyTabCompleteBeforeLogin = settings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN);
this.freezePlayerBeforeLogin = !settings.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT);
//it was true and will be deactivated now, so we need to restore the inventory for every player
if (oldProtectInventory && !protectInvBeforeLogin && inventoryPacketAdapter != null) {
@ -175,14 +130,6 @@ public class ProtocolLibService implements SettingsDependent {
}
}
}
if (oldFreezePlayer && !freezePlayerBeforeLogin && freezePacketAdapter != null) {
freezePacketAdapter.unregister();
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
if (!playerCache.isAuthenticated(onlinePlayer.getName())) {
freezePacketAdapter.sendUnFreezePacket(onlinePlayer);
}
}
}
setup();
}

View File

@ -6,7 +6,6 @@ import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.LoginEvent;
import fr.xephi.authme.events.RestoreInventoryEvent;
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.SynchronousProcess;
@ -24,7 +23,6 @@ import org.bukkit.potion.PotionEffectType;
import javax.inject.Inject;
import java.util.List;
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT;
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
public class ProcessSyncPlayerLogin implements SynchronousProcess {
@ -59,9 +57,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
@Inject
private PermissionsManager permissionsManager;
@Inject
private ProtocolLibService protocolLibService;
ProcessSyncPlayerLogin() {
}
@ -92,9 +87,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
if (commonService.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
restoreInventory(player);
}
if (!commonService.getProperty(ALLOW_UNAUTHED_MOVEMENT)) {
protocolLibService.sendUnFreezePacket(player);
}
final PlayerAuth auth = dataSource.getAuth(name);
teleportationService.teleportOnLogin(player, auth, limbo);

View File

@ -56,9 +56,6 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
if (service.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
protocolLibService.sendBlankInventoryPacket(player);
}
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)){
protocolLibService.sendFreezePacket(player);
}
applyLogoutEffect(player);
commandManager.runCommandsOnLogout(player);

View File

@ -5,6 +5,7 @@ import ch.jalu.configme.SettingsHolder;
import ch.jalu.configme.configurationdata.CommentsConfiguration;
import ch.jalu.configme.properties.Property;
import fr.xephi.authme.data.limbo.AllowFlightRestoreType;
import fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType;
import fr.xephi.authme.data.limbo.persistence.LimboPersistenceType;
import fr.xephi.authme.data.limbo.persistence.SegmentSize;
@ -18,7 +19,7 @@ public final class LimboSettings implements SettingsHolder {
@Comment({
"Besides storing the data in memory, you can define if/how the data should be persisted",
"on disk. This is useful in case of a server crash, so next time the server starts we can",
"properly restore things like OP status and the ability to fly",
"properly restore things like OP status, ability to fly, and walk/fly speed.",
"DISABLED: no disk storage,",
"INDIVIDUAL_FILES: each player data in its own file,",
"DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below"
@ -48,6 +49,23 @@ public final class LimboSettings implements SettingsHolder {
public static final Property<AllowFlightRestoreType> RESTORE_ALLOW_FLIGHT =
newProperty(AllowFlightRestoreType.class, "limbo.restoreAllowFlight", AllowFlightRestoreType.RESTORE);
@Comment({
"Restore fly speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.",
"RESTORE: restore the speed the player had;",
"DEFAULT: always set to default speed;",
"MAX_RESTORE: take the maximum of the player's current speed and the previous one",
"RESTORE_NO_ZERO: Like 'restore' but sets speed to default if the player's speed was 0"
})
public static final Property<WalkFlySpeedRestoreType> RESTORE_FLY_SPEED =
newProperty(WalkFlySpeedRestoreType.class, "limbo.restoreFlySpeed", WalkFlySpeedRestoreType.RESTORE_NO_ZERO);
@Comment({
"Restore walk speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.",
"See above for a description of the values."
})
public static final Property<WalkFlySpeedRestoreType> RESTORE_WALK_SPEED =
newProperty(WalkFlySpeedRestoreType.class, "limbo.restoreWalkSpeed", WalkFlySpeedRestoreType.RESTORE_NO_ZERO);
private LimboSettings() {
}
@ -55,7 +73,7 @@ public final class LimboSettings implements SettingsHolder {
public void registerComments(CommentsConfiguration conf) {
String[] limboExplanation = {
"Before a user logs in, various properties are temporarily removed from the player,",
"such as OP status and the ability to fly.",
"such as OP status, ability to fly, and walk/fly speed.",
"Once the user is logged in, we add back the properties we previously saved.",
"In this section, you may define how these properties should be handled.",
"Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players"

View File

@ -22,28 +22,32 @@ public final class LimboPlayerMatchers {
public static Matcher<LimboPlayer> isLimbo(LimboPlayer limbo) {
String[] groups = limbo.getGroups().toArray(new String[limbo.getGroups().size()]);
return isLimbo(limbo.isOperator(), limbo.isCanFly(), groups);
return isLimbo(limbo.isOperator(), limbo.isCanFly(), limbo.getWalkSpeed(), limbo.getFlySpeed(), groups);
}
public static Matcher<LimboPlayer> isLimbo(boolean isOp, boolean canFly, String... groups) {
public static Matcher<LimboPlayer> isLimbo(boolean isOp, boolean canFly, float walkSpeed, float flySpeed,
String... groups) {
return new TypeSafeMatcher<LimboPlayer>() {
@Override
protected boolean matchesSafely(LimboPlayer item) {
return item.isOperator() == isOp
&& collectionContains(item.getGroups(), groups)
&& item.isCanFly() == canFly;
&& item.isCanFly() == canFly
&& walkSpeed == item.getWalkSpeed()
&& flySpeed == item.getFlySpeed();
}
@Override
public void describeTo(Description description) {
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s",
isOp, String.join(" ,", groups), canFly));
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s, walkSpeed=%f, flySpeed=%f",
isOp, String.join(" ,", groups), canFly, walkSpeed, flySpeed));
}
@Override
public void describeMismatchSafely(LimboPlayer item, Description description) {
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s",
item.isOperator(), String.join(" ,", item.getGroups()), item.isCanFly()));
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s, walkSpeed=%f, flySpeed=%f",
item.isOperator(), String.join(" ,", item.getGroups()), item.isCanFly(),
item.getWalkSpeed(), item.getFlySpeed()));
}
};
}

View File

@ -106,7 +106,7 @@ public class LimboPlayerTaskManagerTest {
String name = "rats";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false, 0.1f, 0.0f);
MessageTask existingMessageTask = mock(MessageTask.class);
limboPlayer.setMessageTask(existingMessageTask);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8);
@ -129,7 +129,7 @@ public class LimboPlayerTaskManagerTest {
String name = "race";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false, 0.1f, 0.0f);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(12);
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(true);
String captcha = "M032";
@ -180,7 +180,7 @@ public class LimboPlayerTaskManagerTest {
public void shouldCancelExistingTimeoutTask() {
// given
Player player = mock(Player.class);
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true);
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true, 0.3f, 0.1f);
BukkitTask existingTask = mock(BukkitTask.class);
limboPlayer.setTimeoutTask(existingTask);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);

View File

@ -37,9 +37,9 @@ public class LimboServiceHelperTest {
public void shouldMergeLimboPlayers() {
// given
Location newLocation = mock(Location.class);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), false);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), false, 0.0f, 0.0f);
Location oldLocation = mock(Location.class);
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList("grp-old"), true);
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList("grp-old"), true, 0.1f, 0.8f);
// when
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
@ -49,14 +49,16 @@ public class LimboServiceHelperTest {
assertThat(result.isOperator(), equalTo(true));
assertThat(result.getGroups(), contains("grp-old"));
assertThat(result.isCanFly(), equalTo(true));
assertThat(result.getWalkSpeed(), equalTo(0.1f));
assertThat(result.getFlySpeed(), equalTo(0.8f));
}
@Test
public void shouldFallBackToNewLimboForMissingData() {
// given
Location newLocation = mock(Location.class);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), true);
LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), true, 0.3f, 0.0f);
LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false, 0.1f, 0.1f);
// when
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
@ -66,6 +68,8 @@ public class LimboServiceHelperTest {
assertThat(result.isOperator(), equalTo(false));
assertThat(result.getGroups(), contains("grp-new"));
assertThat(result.isCanFly(), equalTo(true));
assertThat(result.getWalkSpeed(), equalTo(0.3f));
assertThat(result.getFlySpeed(), equalTo(0.1f));
}
@Test

View File

@ -79,7 +79,7 @@ public class LimboServiceTest {
@Test
public void shouldCreateLimboPlayer() {
// given
Player player = newPlayer("Bobby", true, false);
Player player = newPlayer("Bobby", true, 0.3f, false, 0.2f);
Location playerLoc = mock(Location.class);
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
given(permissionsManager.hasGroupSupport()).willReturn(true);
@ -93,13 +93,17 @@ public class LimboServiceTest {
verify(taskManager).registerMessageTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.LOG_IN));
verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
verify(player).setAllowFlight(false);
verify(player).setFlySpeed(0.0f);
verify(player).setWalkSpeed(0.0f);
assertThat(limboService.hasLimboPlayer("Bobby"), equalTo(true));
LimboPlayer limbo = limboService.getLimboPlayer("Bobby");
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.REGISTERED_UNAUTHENTICATED);
assertThat(limbo, not(nullValue()));
assertThat(limbo.isOperator(), equalTo(true));
assertThat(limbo.getWalkSpeed(), equalTo(0.3f));
assertThat(limbo.isCanFly(), equalTo(false));
assertThat(limbo.getFlySpeed(), equalTo(0.2f));
assertThat(limbo.getLocation(), equalTo(playerLoc));
assertThat(limbo.getGroups(), equalTo(Collections.singletonList("permgrwp")));
}
@ -107,7 +111,7 @@ public class LimboServiceTest {
@Test
public void shouldNotKeepOpStatusForUnregisteredPlayer() {
// given
Player player = newPlayer("CharleS", true, true);
Player player = newPlayer("CharleS", true, 0.1f, true, 0.4f);
Location playerLoc = mock(Location.class);
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
given(permissionsManager.hasGroupSupport()).willReturn(false);
@ -121,12 +125,16 @@ public class LimboServiceTest {
verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
verify(permissionsManager, only()).hasGroupSupport();
verify(player).setAllowFlight(false);
verify(player).setFlySpeed(0.0f);
verify(player).setWalkSpeed(0.0f);
LimboPlayer limbo = limboService.getLimboPlayer("charles");
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.UNREGISTERED);
assertThat(limbo, not(nullValue()));
assertThat(limbo.isOperator(), equalTo(false));
assertThat(limbo.getWalkSpeed(), equalTo(0.1f));
assertThat(limbo.isCanFly(), equalTo(true));
assertThat(limbo.getFlySpeed(), equalTo(0.4f));
assertThat(limbo.getLocation(), equalTo(playerLoc));
assertThat(limbo.getGroups(), equalTo(Collections.emptyList()));
}
@ -154,18 +162,22 @@ public class LimboServiceTest {
public void shouldRestoreData() {
// given
LimboPlayer limbo = Mockito.spy(convertToLimboPlayer(
newPlayer("John", true, false), null, Collections.emptyList()));
newPlayer("John", true, 0.4f, false, 0.0f), null, Collections.emptyList()));
getLimboMap().put("john", limbo);
Player player = newPlayer("John", false, false);
Player player = newPlayer("John", false, 0.2f, false, 0.7f);
given(settings.getProperty(LimboSettings.RESTORE_ALLOW_FLIGHT)).willReturn(AllowFlightRestoreType.ENABLE);
given(settings.getProperty(LimboSettings.RESTORE_WALK_SPEED)).willReturn(WalkFlySpeedRestoreType.RESTORE);
given(settings.getProperty(LimboSettings.RESTORE_FLY_SPEED)).willReturn(WalkFlySpeedRestoreType.RESTORE_NO_ZERO);
// when
limboService.restoreData(player);
// then
verify(player).setOp(true);
verify(player).setWalkSpeed(0.4f);
verify(player).setAllowFlight(true);
verify(player).setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
verify(limbo).clearTasks();
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.LOGGED_IN);
assertThat(limboService.hasLimboPlayer("John"), equalTo(false));
@ -220,15 +232,18 @@ public class LimboServiceTest {
return player;
}
private static Player newPlayer(String name, boolean isOp, boolean canFly) {
private static Player newPlayer(String name, boolean isOp, float walkSpeed, boolean canFly, float flySpeed) {
Player player = newPlayer(name);
given(player.isOp()).willReturn(isOp);
given(player.getWalkSpeed()).willReturn(walkSpeed);
given(player.getAllowFlight()).willReturn(canFly);
given(player.getFlySpeed()).willReturn(flySpeed);
return player;
}
private static LimboPlayer convertToLimboPlayer(Player player, Location location, Collection<String> groups) {
return new LimboPlayer(location, player.isOp(), groups, player.getAllowFlight());
return new LimboPlayer(location, player.isOp(), groups, player.getAllowFlight(),
player.getWalkSpeed(), player.getFlySpeed());
}
private Map<String, LimboPlayer> getLimboMap() {

View File

@ -0,0 +1,108 @@
package fr.xephi.authme.data.limbo;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static fr.xephi.authme.data.limbo.LimboPlayer.DEFAULT_FLY_SPEED;
import static fr.xephi.authme.data.limbo.LimboPlayer.DEFAULT_WALK_SPEED;
import static fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType.DEFAULT;
import static fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType.MAX_RESTORE;
import static fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType.RESTORE;
import static fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType.RESTORE_NO_ZERO;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Test for {@link WalkFlySpeedRestoreType}.
*/
@RunWith(Parameterized.class)
public class WalkFlySpeedRestoreTypeTest {
private final TestParameters parameters;
public WalkFlySpeedRestoreTypeTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void shouldRestoreToExpectedValue() {
// given
LimboPlayer limbo = mock(LimboPlayer.class);
given(limbo.getWalkSpeed()).willReturn(parameters.givenLimboWalkSpeed);
given(limbo.getFlySpeed()).willReturn(parameters.givenLimboFlySpeed);
Player player = mock(Player.class);
given(player.getWalkSpeed()).willReturn(parameters.givenPlayerWalkSpeed);
given(player.getFlySpeed()).willReturn(parameters.givenPlayerFlySpeed);
// when
parameters.testedType.restoreWalkSpeed(player, limbo);
parameters.testedType.restoreFlySpeed(player, limbo);
// then
verify(player).setWalkSpeed(parameters.expectedWalkSpeed);
verify(player).setFlySpeed(parameters.expectedFlySpeed);
}
@Parameterized.Parameters(name = "{0}")
public static List<Object[]> buildParams() {
List<TestParameters> parameters = Arrays.asList(
create(RESTORE).withLimbo(0.1f, 0.4f).withPlayer(0.3f, 0.9f).expect(0.1f, 0.4f),
create(RESTORE).withLimbo(0.9f, 0.2f).withPlayer(0.3f, 0.0f).expect(0.9f, 0.2f),
create(MAX_RESTORE).withLimbo(0.3f, 0.8f).withPlayer(0.5f, 0.2f).expect(0.5f, 0.8f),
create(MAX_RESTORE).withLimbo(0.4f, 0.2f).withPlayer(0.1f, 0.4f).expect(0.4f, 0.4f),
create(RESTORE_NO_ZERO).withLimbo(0.1f, 0.2f).withPlayer(0.5f, 0.1f).expect(0.1f, 0.2f),
create(RESTORE_NO_ZERO).withLimbo(0.0f, 0.005f).withPlayer(0.4f, 0.8f).expect(DEFAULT_WALK_SPEED, DEFAULT_FLY_SPEED),
create(DEFAULT).withLimbo(0.1f, 0.7f).withPlayer(0.4f, 0.0f).expect(DEFAULT_WALK_SPEED, DEFAULT_FLY_SPEED)
);
// Convert List<TestParameters> to List<Object[]>
return parameters.stream().map(p -> new Object[]{p}).collect(Collectors.toList());
}
private static TestParameters create(WalkFlySpeedRestoreType testedType) {
TestParameters params = new TestParameters();
params.testedType = testedType;
return params;
}
private static final class TestParameters {
private WalkFlySpeedRestoreType testedType;
private float givenLimboWalkSpeed;
private float givenLimboFlySpeed;
private float givenPlayerWalkSpeed;
private float givenPlayerFlySpeed;
private float expectedWalkSpeed;
private float expectedFlySpeed;
TestParameters withLimbo(float walkSpeed, float flySpeed) {
this.givenLimboWalkSpeed = walkSpeed;
this.givenLimboFlySpeed = flySpeed;
return this;
}
TestParameters withPlayer(float walkSpeed, float flySpeed) {
this.givenPlayerWalkSpeed = walkSpeed;
this.givenPlayerFlySpeed = flySpeed;
return this;
}
TestParameters expect(float walkSpeed, float flySpeed) {
this.expectedWalkSpeed = walkSpeed;
this.expectedFlySpeed = flySpeed;
return this;
}
@Override
public String toString() {
return testedType + " {" + expectedWalkSpeed + ", " + expectedFlySpeed + "}";
}
}
}

View File

@ -48,22 +48,22 @@ public class DistributedFilesPersistenceHandlerTest {
/** Player is in seg32-10110 and should be migrated into seg16-f. */
private static final UUID MIGRATED_UUID = fromString("f6a97c88-7c8f-c12e-4931-6206d4ca067d");
private static final Matcher<LimboPlayer> MIGRATED_LIMBO_MATCHER =
isLimbo(false, true, "noob");
isLimbo(false, true, 0.2f, 0.1f, "noob");
/** Existing player in seg16-f. */
private static final UUID UUID_FAB69 = fromString("fab69c88-2cd0-1fed-f00d-dead14ca067d");
private static final Matcher<LimboPlayer> FAB69_MATCHER =
isLimbo(false, false, "");
isLimbo(false, false, 0.2f, 0.1f, "");
/** Player in seg16-8. */
private static final UUID UUID_STAFF = fromString("88897c88-7c8f-c12e-4931-6206d4ca067d");
private static final Matcher<LimboPlayer> STAFF_MATCHER =
isLimbo(true, false, "staff", "mod");
isLimbo(true, false, 0.3f, 0.1f, "staff", "mod");
/** Player in seg16-8. */
private static final UUID UUID_8C679 = fromString("8c679491-1234-abcd-9102-1fa6e0cc3f81");
private static final Matcher<LimboPlayer> SC679_MATCHER =
isLimbo(false, true, "primary");
isLimbo(false, true, 0.1f, 0.0f, "primary");
/** UUID for which no data is stored (belongs to a segment file that does not exist, seg16-4). */
private static final UUID UNKNOWN_UUID = fromString("42d1cc0b-8f12-d04a-e7ba-a067d05cdc39");
@ -156,10 +156,10 @@ public class DistributedFilesPersistenceHandlerTest {
// given
Player uuidToAdd1 = mockPlayerWithUuid(UNKNOWN_UUID);
Location location1 = mockLocation("1world");
LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList("group-1"), true);
LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList("group-1"), true, 0.1f, 0.2f);
Player uuidToAdd2 = mockPlayerWithUuid(UNKNOWN_UUID2);
Location location2 = mockLocation("2world");
LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false);
LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false, 0.0f, 0.25f);
// when
persistenceHandler.saveLimboPlayer(uuidToAdd1, limbo1);

View File

@ -78,6 +78,8 @@ public class IndividualFilesPersistenceHandlerTest {
assertThat(data, not(nullValue()));
assertThat(data.isOperator(), equalTo(true));
assertThat(data.isCanFly(), equalTo(true));
assertThat(data.getWalkSpeed(), equalTo(0.2f));
assertThat(data.getFlySpeed(), equalTo(0.1f));
assertThat(data.getGroups(), contains("players"));
Location location = data.getLocation();
assertThat(location.getX(), equalTo(-113.219));
@ -112,7 +114,7 @@ public class IndividualFilesPersistenceHandlerTest {
World world = mock(World.class);
given(world.getName()).willReturn("player-world");
Location location = new Location(world, 0.2, 102.25, -89.28, 3.02f, 90.13f);
LimboPlayer limbo = new LimboPlayer(location, true, Collections.singletonList("primary-grp"), true);
LimboPlayer limbo = new LimboPlayer(location, true, Collections.singletonList("primary-grp"), true, 1.2f, 0.8f);
// when
handler.saveLimboPlayer(player, limbo);

View File

@ -9,5 +9,7 @@
},
"operator": true,
"can-fly": true,
"walk-speed": 0.2,
"fly-speed": 0.1,
"group": "players"
}

View File

@ -13,7 +13,9 @@
"mod"
],
"operator": true,
"can-fly": false
"can-fly": false,
"walk-speed": 0.3,
"fly-speed": 0.1
},
"8c679491-1234-abcd-9102-1fa6e0cc3f81": {
"location": {
@ -26,6 +28,8 @@
},
"group": "primary",
"operator": false,
"can-fly": true
"can-fly": true,
"walk-speed": 0.1,
"fly-speed": 0.0
}
}

View File

@ -10,6 +10,8 @@
},
"group": "",
"operator": false,
"can-fly": false
"can-fly": false,
"walk-speed": 0.2,
"fly-speed": 0.1
}
}

View File

@ -10,6 +10,8 @@
},
"group": "noob",
"operator": false,
"can-fly": true
"can-fly": true,
"walk-speed": 0.2,
"fly-speed": 0.1
}
}