Packet based movement freeze (#1879)
* Remove unused files * Remove walk/fly speed from limbo player * Implement packet based movement freeze
This commit is contained in:
parent
fadda43d13
commit
db3acce70c
@ -1,5 +1,5 @@
|
|||||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||||
<!-- File auto-generated on Tue Apr 23 17:17:02 CEST 2019. See docs/config/config.tpl.md -->
|
<!-- File auto-generated on Mon Aug 05 18:57:10 CEST 2019. See docs/config/config.tpl.md -->
|
||||||
|
|
||||||
## AuthMe Configuration
|
## AuthMe Configuration
|
||||||
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
|
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
|
||||||
@ -501,7 +501,7 @@ Security:
|
|||||||
# Minutes after which a verification code will expire
|
# Minutes after which a verification code will expire
|
||||||
verificationCodeExpiration: 10
|
verificationCodeExpiration: 10
|
||||||
# Before a user logs in, various properties are temporarily removed from the player,
|
# Before a user logs in, various properties are temporarily removed from the player,
|
||||||
# such as OP status, ability to fly, and walk/fly speed.
|
# such as OP status and the ability to fly.
|
||||||
# Once the user is logged in, we add back the properties we previously saved.
|
# 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.
|
# In this section, you may define how these properties should be handled.
|
||||||
# Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players
|
# Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players
|
||||||
@ -509,7 +509,7 @@ limbo:
|
|||||||
persistence:
|
persistence:
|
||||||
# Besides storing the data in memory, you can define if/how the data should be persisted
|
# 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
|
# 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, ability to fly, and walk/fly speed.
|
# properly restore things like OP status and the ability to fly
|
||||||
# DISABLED: no disk storage,
|
# DISABLED: no disk storage,
|
||||||
# INDIVIDUAL_FILES: each player data in its own file,
|
# INDIVIDUAL_FILES: each player data in its own file,
|
||||||
# DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below
|
# DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below
|
||||||
@ -528,15 +528,6 @@ limbo:
|
|||||||
# RESTORE sets back the old property from the player. NOTHING will prevent AuthMe
|
# RESTORE sets back the old property from the player. NOTHING will prevent AuthMe
|
||||||
# from modifying the 'allow flight' property on the player.
|
# from modifying the 'allow flight' property on the player.
|
||||||
restoreAllowFlight: RESTORE
|
restoreAllowFlight: RESTORE
|
||||||
# Restore fly speed: RESTORE, DEFAULT, MAX_RESTORE, RESTORE_NO_ZERO.
|
|
||||||
# RESTORE: 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:
|
BackupSystem:
|
||||||
# General configuration for backups: if false, no backups are possible
|
# General configuration for backups: if false, no backups are possible
|
||||||
ActivateBackup: false
|
ActivateBackup: false
|
||||||
@ -578,4 +569,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 Tue Apr 23 17:17:02 CEST 2019
|
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
|
||||||
|
|||||||
@ -1,570 +0,0 @@
|
|||||||
# =======================================================================================================
|
|
||||||
# _____ __ .__ _____ __________ .__ .___ .___
|
|
||||||
# / _ \ __ ___/ |_| |__ / \ ____\______ \ ____ | | _________ __| _/____ __| _/
|
|
||||||
# / /_\ \| | \ __| | \ / \ / \_/ __ \| __/ __ \| | / _ \__ \ / __ _/ __ \ / __ |
|
|
||||||
# / | | | /| | | Y / Y \ ___/| | \ ___/| |_( <_> / __ \/ /_/ \ ___// /_/ |
|
|
||||||
# \____|__ |____/ |__| |___| \____|__ /\___ |____|_ /\___ |____/\____(____ \____ |\___ \____ |
|
|
||||||
# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
|
|
||||||
#
|
|
||||||
# =======================================================================================================
|
|
||||||
#
|
|
||||||
# Authme Main Configuration File.
|
|
||||||
#
|
|
||||||
# =======================================================================================================
|
|
||||||
|
|
||||||
# Plugin infos (overwritten on start, just a simple way to find out your plugin version).
|
|
||||||
authors: ${pluginAuthors}
|
|
||||||
version: ${project.version}
|
|
||||||
buildNumber: ${buildNumber}
|
|
||||||
|
|
||||||
# Set this setting to true when you have configured the plugin,
|
|
||||||
# when false the server will be stopped with a warning message.
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Database settings.
|
|
||||||
data_source:
|
|
||||||
# ===========================
|
|
||||||
# Database general settings.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
# Database backend (sqlite, mysql).
|
|
||||||
backend: sqlite
|
|
||||||
# Enable database queries caching, should improve performance.
|
|
||||||
caching: true
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# SqLite db parameters.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
sqlite:
|
|
||||||
# The name of the database storage file.
|
|
||||||
filename: 'authme.db'
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# MySql db parameters.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
mysql:
|
|
||||||
# Connection parameters.
|
|
||||||
host: '127.0.0.1'
|
|
||||||
port: 3306
|
|
||||||
username: 'change_me'
|
|
||||||
password: 'change_me'
|
|
||||||
database: 'my_minecraft_server'
|
|
||||||
tablename: 'authme'
|
|
||||||
|
|
||||||
# Column names.
|
|
||||||
column_names:
|
|
||||||
id: id
|
|
||||||
# Column for storing nicknames (ignore case nickname).
|
|
||||||
name: username
|
|
||||||
# Column for storing the realname (case sensitive nickname).
|
|
||||||
real_name: realname
|
|
||||||
# Column for storing passwords.
|
|
||||||
password: password
|
|
||||||
# Column for storing email addresses.
|
|
||||||
email: email
|
|
||||||
# Column for storing the authentication status (logged or not).
|
|
||||||
login_status: isLogged
|
|
||||||
# Column for storing player IPs.
|
|
||||||
ip: ip
|
|
||||||
# Column for storing lastlogins date and time.
|
|
||||||
last_login_timestamp: lastlogin
|
|
||||||
# Latest logout location of the players.
|
|
||||||
last_location:
|
|
||||||
world: world
|
|
||||||
x: x
|
|
||||||
y: y
|
|
||||||
z: z
|
|
||||||
# Enabled only if the bungeecord integration is activated.
|
|
||||||
server: world
|
|
||||||
|
|
||||||
# Support for registrations via WebInterfaces/CSM.
|
|
||||||
# Disable some backend caching parameters.
|
|
||||||
disableAggressiveCaching: false
|
|
||||||
|
|
||||||
# Main settings
|
|
||||||
settings:
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Bungeecord integration
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
bungeecord:
|
|
||||||
# Enable bungeecord integration features
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Server name (must be unique, please use the name in the bungeecord configuration).
|
|
||||||
# Use 'auto' for auto configuration (requires the bungeecord module).
|
|
||||||
serverName: LoginLobby1
|
|
||||||
# Keep the auth status when the player moves between servers.
|
|
||||||
# Required if you're using the bungeecord module.
|
|
||||||
keepAuthBetweenServers: true
|
|
||||||
|
|
||||||
# Target server after login
|
|
||||||
send_after_login:
|
|
||||||
enabled: false
|
|
||||||
message: ''
|
|
||||||
delay: 5
|
|
||||||
# Server name ("ServerName") or group ("G:GroupName")
|
|
||||||
# Groups are avariable only when the bungeecord module is avariable.
|
|
||||||
# If the server change fails the player will be kicked.
|
|
||||||
target: Lobby1
|
|
||||||
failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
|
|
||||||
# Target server after logout
|
|
||||||
send_after_logout:
|
|
||||||
enabled: false
|
|
||||||
message: ''
|
|
||||||
delay: 5
|
|
||||||
# Server name ("ServerName") or group ("G:GroupName")
|
|
||||||
# Groups are avariable only when the bungeecord module is avariable.
|
|
||||||
# If the server change fails the player will be kicked.
|
|
||||||
target: LoginLobby1
|
|
||||||
failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
|
|
||||||
|
|
||||||
# Variables:
|
|
||||||
# %p playername
|
|
||||||
bungee_commands:
|
|
||||||
player_command_after_register:
|
|
||||||
enabled: false
|
|
||||||
cmd: ''
|
|
||||||
console_command_after_register:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p joined for the first time the network!'
|
|
||||||
player_command_after_login:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'glist'
|
|
||||||
console_command_after_login:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p logged in correctly!'
|
|
||||||
player_command_after_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: ''
|
|
||||||
console_command_after_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p joined the network!'
|
|
||||||
player_command_first_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: ''
|
|
||||||
console_command_first_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p joined for the first time the network!'
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Sessions configuration.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
sessions:
|
|
||||||
# Enable sessions.
|
|
||||||
# When a player is authenticated, his IP and his nickname is saved.
|
|
||||||
# The next time the player will join the server, if his IP is the same
|
|
||||||
# of the last time, and the timeout time hasn't expired, he will be
|
|
||||||
# automatically authenticated.
|
|
||||||
enabled: false
|
|
||||||
# Session timeout.
|
|
||||||
# 0 for unlimited time (Very dangerous, use it at your own risk!)
|
|
||||||
# Consider that if player's ip has changed but the timeout hasn't
|
|
||||||
# expired, player will be kicked out of the sever!
|
|
||||||
timeout: 10
|
|
||||||
# When enabled a player's session will expire if someone tries to
|
|
||||||
# login with a different IP Address.
|
|
||||||
expire_on_ip_change: true
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Registration settings.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
registration:
|
|
||||||
# After how many time unregistered players should be kicked?
|
|
||||||
# Set to 0 to disable. (default: 30)
|
|
||||||
timeout: 30
|
|
||||||
|
|
||||||
nickname:
|
|
||||||
min_length: 4
|
|
||||||
max_lenght: 16
|
|
||||||
# Regex syntax.
|
|
||||||
allowed_characters: '[a-zA-Z0-9_]*'
|
|
||||||
|
|
||||||
password:
|
|
||||||
# Enable double check of password on registration:
|
|
||||||
# /register <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
|
|
||||||
@ -1,199 +0,0 @@
|
|||||||
name: ${pluginName}
|
|
||||||
authors: [${pluginAuthors}]
|
|
||||||
website: ${project.url}
|
|
||||||
description: ${project.description}
|
|
||||||
main: ${mainClass}
|
|
||||||
version: ${project.version}-b${buildNumber}
|
|
||||||
softdepend:
|
|
||||||
- Vault
|
|
||||||
- PermissionsBukkit
|
|
||||||
- PermissionsEX
|
|
||||||
- EssentialsGroupManager
|
|
||||||
- Multiverse-Core
|
|
||||||
- Essentials
|
|
||||||
- EssentialsSpawn
|
|
||||||
- ProtocolLib
|
|
||||||
commands:
|
|
||||||
authme:
|
|
||||||
description: AuthMe admin commands
|
|
||||||
usage: '/authme reload|register playername password|changepassword playername password|unregister playername|version|converter datatype'
|
|
||||||
permission: authme.admin
|
|
||||||
register:
|
|
||||||
description: Register an account
|
|
||||||
usage: /register password confirmpassword
|
|
||||||
aliases: [reg]
|
|
||||||
permission: authme.player.register
|
|
||||||
login:
|
|
||||||
description: Login into a account
|
|
||||||
usage: /login password
|
|
||||||
aliases: [l,log]
|
|
||||||
permission: authme.player.login
|
|
||||||
changepassword:
|
|
||||||
description: Change password of a account
|
|
||||||
usage: /changepassword oldPassword newPassword
|
|
||||||
permission: authme.player.changepassword
|
|
||||||
logout:
|
|
||||||
description: Logout from the server
|
|
||||||
usage: /logout
|
|
||||||
permission: authme.player.logout
|
|
||||||
unregister:
|
|
||||||
description: unregister your account
|
|
||||||
usage: /unregister password
|
|
||||||
permission: authme.player.unregister
|
|
||||||
email:
|
|
||||||
description: Add Email or recover password
|
|
||||||
usage: '/email add your@email.com your@email.com|change oldEmail newEmail|recovery your@email.com'
|
|
||||||
permission: authme.player.email
|
|
||||||
captcha:
|
|
||||||
description: Captcha command
|
|
||||||
usage: /captcha theCaptcha
|
|
||||||
permission: authme.player.captcha
|
|
||||||
permissions:
|
|
||||||
authme.canbeforced:
|
|
||||||
description: Allow the user to be forced-logged via API
|
|
||||||
default: true
|
|
||||||
authme.player:
|
|
||||||
description: Gives access to all authme player commands
|
|
||||||
default: true
|
|
||||||
children:
|
|
||||||
authme.player.login: true
|
|
||||||
authme.player.logout: true
|
|
||||||
authme.player.register: true
|
|
||||||
authme.player.unregister: true
|
|
||||||
authme.player.changepassword: true
|
|
||||||
authme.player.captcha: true
|
|
||||||
authme.player.email: true
|
|
||||||
authme.player.register:
|
|
||||||
description: Register your account
|
|
||||||
default: false
|
|
||||||
authme.player.unregister:
|
|
||||||
description: Unregister your account
|
|
||||||
default: false
|
|
||||||
authme.player.login:
|
|
||||||
description: Login into your account
|
|
||||||
default: false
|
|
||||||
authme.player.logout:
|
|
||||||
description: Logout from your account
|
|
||||||
default: false
|
|
||||||
authme.player.changepassword:
|
|
||||||
description: Change password of your account
|
|
||||||
default: false
|
|
||||||
authme.player.email:
|
|
||||||
description: Gives access to player's email commands
|
|
||||||
default: false
|
|
||||||
children:
|
|
||||||
authme.player.email.add: true
|
|
||||||
authme.player.email.change: true
|
|
||||||
authme.player.email.recover: true
|
|
||||||
authme.player.email.add:
|
|
||||||
description: Add an email to your account
|
|
||||||
default: false
|
|
||||||
authme.player.email.change:
|
|
||||||
description: Change email of your account
|
|
||||||
default: false
|
|
||||||
authme.player.email.recover:
|
|
||||||
description: Recover your account
|
|
||||||
default: false
|
|
||||||
authme.player.captcha:
|
|
||||||
description: Captcha command
|
|
||||||
default: false
|
|
||||||
authme.admin:
|
|
||||||
description: Gives access to all authme admin commands
|
|
||||||
default: op
|
|
||||||
children:
|
|
||||||
authme.admin.forcelogin: true
|
|
||||||
authme.admin.forcelogout: true
|
|
||||||
authme.admin.register: true
|
|
||||||
authme.admin.unregister: true
|
|
||||||
authme.admin.changemail: true
|
|
||||||
authme.admin.changepassword: true
|
|
||||||
authme.admin.lastlogin: true
|
|
||||||
authme.admin.accounts: true
|
|
||||||
authme.admin.getemail: true
|
|
||||||
authme.admin.getip: true
|
|
||||||
authme.admin.setspawn: true
|
|
||||||
authme.admin.spawn: true
|
|
||||||
authme.admin.setfirstspawn: true
|
|
||||||
authme.admin.firstspawn: true
|
|
||||||
authme.admin.purge: true
|
|
||||||
authme.admin.purgebannedplayers: true
|
|
||||||
authme.admin.purgelastpos: true
|
|
||||||
authme.admin.converter: true
|
|
||||||
authme.admin.reload: true
|
|
||||||
authme.admin.switchantibot: true
|
|
||||||
authme.admin.seeotheraccounts: true
|
|
||||||
authme.admin.register:
|
|
||||||
description: Register an account
|
|
||||||
default: false
|
|
||||||
authme.admin.unregister:
|
|
||||||
description: Unregister an account
|
|
||||||
default: false
|
|
||||||
authme.admin.forcelogin:
|
|
||||||
description: Force login for that player
|
|
||||||
default: false
|
|
||||||
authme.admin.forcelogout:
|
|
||||||
description: Force logout for that player
|
|
||||||
default: false
|
|
||||||
authme.admin.changepassword:
|
|
||||||
description: Change the password of an account
|
|
||||||
default: false
|
|
||||||
authme.admin.getemail:
|
|
||||||
description: Get last email about a player
|
|
||||||
default: false
|
|
||||||
authme.admin.changeemail:
|
|
||||||
description: Change a player email
|
|
||||||
default: false
|
|
||||||
authme.admin.accounts:
|
|
||||||
description: Display Players Accounts
|
|
||||||
default: false
|
|
||||||
authme.admin.seeotheraccounts:
|
|
||||||
description: Display other accounts about a player when he logs in
|
|
||||||
default: false
|
|
||||||
authme.admin.lastlogin:
|
|
||||||
description: Get last login date about a player
|
|
||||||
default: false
|
|
||||||
authme.admin.getip:
|
|
||||||
description: Get IP from a player (fake and real)
|
|
||||||
default: false
|
|
||||||
authme.admin.setspawn:
|
|
||||||
description: Set the AuthMe spawn point
|
|
||||||
default: false
|
|
||||||
authme.admin.spawn:
|
|
||||||
description: Teleport to AuthMe spawn point
|
|
||||||
default: false
|
|
||||||
authme.admin.setfirstspawn:
|
|
||||||
description: Set the AuthMe First Spawn Point
|
|
||||||
default: false
|
|
||||||
authme.admin.firstspawn:
|
|
||||||
description: Teleport to AuthMe First Spawn Point
|
|
||||||
default: false
|
|
||||||
authme.admin.switchantibot:
|
|
||||||
description: Switch AntiBot mode on/off
|
|
||||||
default: false
|
|
||||||
authme.admin.purge:
|
|
||||||
description: Database purge command
|
|
||||||
default: false
|
|
||||||
authme.admin.purgebannedplayers:
|
|
||||||
description: Purge banned players
|
|
||||||
default: false
|
|
||||||
authme.admin.purgelastpos:
|
|
||||||
description: Purge last position of a player/players
|
|
||||||
default: false
|
|
||||||
authme.admin.converter:
|
|
||||||
description: Allow the /authme converter command
|
|
||||||
default: false
|
|
||||||
authme.admin.reload:
|
|
||||||
description: Reload the plugin
|
|
||||||
default: false
|
|
||||||
authme.vip:
|
|
||||||
description: Allow vip slot when the server is full
|
|
||||||
default: false
|
|
||||||
authme.bypassantibot:
|
|
||||||
description: Bypass the AntiBot check
|
|
||||||
default: false
|
|
||||||
authme.allowmultipleaccounts:
|
|
||||||
description: Allow more accounts for same ip
|
|
||||||
default: false
|
|
||||||
authme.bypassforcesurvival:
|
|
||||||
description: Bypass all ForceSurvival features
|
|
||||||
default: false
|
|
||||||
@ -68,9 +68,7 @@ class LimboPlayerViewer implements DebugSection {
|
|||||||
sender.sendMessage(ChatColor.BLUE + "Player / limbo / disk limbo info for '" + arguments.get(0) + "'");
|
sender.sendMessage(ChatColor.BLUE + "Player / limbo / disk limbo info for '" + arguments.get(0) + "'");
|
||||||
new InfoDisplayer(sender, player, memoryLimbo, diskLimbo)
|
new InfoDisplayer(sender, player, memoryLimbo, diskLimbo)
|
||||||
.sendEntry("Is op", Player::isOp, LimboPlayer::isOperator)
|
.sendEntry("Is op", Player::isOp, LimboPlayer::isOperator)
|
||||||
.sendEntry("Walk speed", Player::getWalkSpeed, LimboPlayer::getWalkSpeed)
|
|
||||||
.sendEntry("Can fly", Player::getAllowFlight, LimboPlayer::isCanFly)
|
.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("Location", p -> formatLocation(p.getLocation()), l -> formatLocation(l.getLocation()))
|
||||||
.sendEntry("Prim. group",
|
.sendEntry("Prim. group",
|
||||||
p -> permissionsManager.hasGroupSupport() ? permissionsManager.getPrimaryGroup(p) : "N/A",
|
p -> permissionsManager.hasGroupSupport() ? permissionsManager.getPrimaryGroup(p) : "N/A",
|
||||||
|
|||||||
@ -12,27 +12,19 @@ import java.util.Collection;
|
|||||||
*/
|
*/
|
||||||
public class LimboPlayer {
|
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 canFly;
|
||||||
private final boolean operator;
|
private final boolean operator;
|
||||||
private final Collection<String> groups;
|
private final Collection<String> groups;
|
||||||
private final Location loc;
|
private final Location loc;
|
||||||
private final float walkSpeed;
|
|
||||||
private final float flySpeed;
|
|
||||||
private BukkitTask timeoutTask = null;
|
private BukkitTask timeoutTask = null;
|
||||||
private MessageTask messageTask = null;
|
private MessageTask messageTask = null;
|
||||||
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
|
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
|
||||||
|
|
||||||
public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly, float walkSpeed,
|
public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly) {
|
||||||
float flySpeed) {
|
|
||||||
this.loc = loc;
|
this.loc = loc;
|
||||||
this.operator = operator;
|
this.operator = operator;
|
||||||
this.groups = groups;
|
this.groups = groups;
|
||||||
this.canFly = fly;
|
this.canFly = fly;
|
||||||
this.walkSpeed = walkSpeed;
|
|
||||||
this.flySpeed = flySpeed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,14 +58,6 @@ public class LimboPlayer {
|
|||||||
return canFly;
|
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
|
* Return the timeout task, which kicks the player if he hasn't registered or logged in
|
||||||
* after a configurable amount of time.
|
* after a configurable amount of time.
|
||||||
|
|||||||
@ -14,8 +14,6 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
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_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
|
* Service for managing players that are in "limbo," a temporary state players are
|
||||||
@ -119,8 +117,6 @@ public class LimboService {
|
|||||||
} else {
|
} else {
|
||||||
player.setOp(limbo.isOperator());
|
player.setOp(limbo.isOperator());
|
||||||
settings.getProperty(RESTORE_ALLOW_FLIGHT).restoreAllowFlight(player, limbo);
|
settings.getProperty(RESTORE_ALLOW_FLIGHT).restoreAllowFlight(player, limbo);
|
||||||
settings.getProperty(RESTORE_FLY_SPEED).restoreFlySpeed(player, limbo);
|
|
||||||
settings.getProperty(RESTORE_WALK_SPEED).restoreWalkSpeed(player, limbo);
|
|
||||||
limbo.clearTasks();
|
limbo.clearTasks();
|
||||||
logger.debug("Restored LimboPlayer stats for `{0}`", lowerName);
|
logger.debug("Restored LimboPlayer stats for `{0}`", lowerName);
|
||||||
persistence.removeLimboPlayer(player);
|
persistence.removeLimboPlayer(player);
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.LimboSettings;
|
import fr.xephi.authme.settings.properties.LimboSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@ -40,13 +39,11 @@ class LimboServiceHelper {
|
|||||||
// For safety reasons an unregistered player should not have OP status after registration
|
// For safety reasons an unregistered player should not have OP status after registration
|
||||||
boolean isOperator = isRegistered && player.isOp();
|
boolean isOperator = isRegistered && player.isOp();
|
||||||
boolean flyEnabled = player.getAllowFlight();
|
boolean flyEnabled = player.getAllowFlight();
|
||||||
float walkSpeed = player.getWalkSpeed();
|
|
||||||
float flySpeed = player.getFlySpeed();
|
|
||||||
Collection<String> playerGroups = permissionsManager.hasGroupSupport()
|
Collection<String> playerGroups = permissionsManager.hasGroupSupport()
|
||||||
? permissionsManager.getGroups(player) : Collections.emptyList();
|
? permissionsManager.getGroups(player) : Collections.emptyList();
|
||||||
logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups));
|
logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups));
|
||||||
|
|
||||||
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed);
|
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,18 +58,12 @@ class LimboServiceHelper {
|
|||||||
player.setOp(false);
|
player.setOp(false);
|
||||||
settings.getProperty(LimboSettings.RESTORE_ALLOW_FLIGHT)
|
settings.getProperty(LimboSettings.RESTORE_ALLOW_FLIGHT)
|
||||||
.processPlayer(player);
|
.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:
|
* Merges two existing LimboPlayer instances of a player. Merging is done the following way:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><code>isOperator, allowFlight</code>: true if either limbo has true</li>
|
* <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>
|
* <li><code>groups, location</code>: from old limbo if not empty/null, otherwise from new limbo</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
@ -89,12 +80,10 @@ class LimboServiceHelper {
|
|||||||
|
|
||||||
boolean isOperator = newLimbo.isOperator() || oldLimbo.isOperator();
|
boolean isOperator = newLimbo.isOperator() || oldLimbo.isOperator();
|
||||||
boolean canFly = newLimbo.isCanFly() || oldLimbo.isCanFly();
|
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());
|
Collection<String> groups = getLimboGroups(oldLimbo.getGroups(), newLimbo.getGroups());
|
||||||
Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation());
|
Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation());
|
||||||
|
|
||||||
return new LimboPlayer(location, isOperator, groups, canFly, walkSpeed, flySpeed);
|
return new LimboPlayer(location, isOperator, groups, canFly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Location firstNotNull(Location first, Location second) {
|
private static Location firstNotNull(Location first, Location second) {
|
||||||
|
|||||||
@ -1,123 +0,0 @@
|
|||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -18,7 +18,6 @@ import java.util.List;
|
|||||||
import java.util.function.Function;
|
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.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.GROUPS;
|
||||||
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.IS_OP;
|
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.IS_OP;
|
||||||
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOCATION;
|
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOCATION;
|
||||||
@ -28,7 +27,6 @@ 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_Y;
|
||||||
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_YAW;
|
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.LOC_Z;
|
||||||
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.WALK_SPEED;
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,10 +54,8 @@ class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {
|
|||||||
|
|
||||||
Collection<String> groups = getLimboGroups(jsonObject);
|
Collection<String> groups = getLimboGroups(jsonObject);
|
||||||
boolean canFly = getBoolean(jsonObject, CAN_FLY);
|
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, walkSpeed, flySpeed);
|
return new LimboPlayer(loc, operator, groups, canFly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Location deserializeLocation(JsonObject jsonObject) {
|
private Location deserializeLocation(JsonObject jsonObject) {
|
||||||
|
|||||||
@ -26,8 +26,6 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
|
|||||||
static final String GROUPS = "groups";
|
static final String GROUPS = "groups";
|
||||||
static final String IS_OP = "operator";
|
static final String IS_OP = "operator";
|
||||||
static final String CAN_FLY = "can-fly";
|
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();
|
private static final Gson GSON = new Gson();
|
||||||
|
|
||||||
@ -49,8 +47,6 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
|
|||||||
|
|
||||||
obj.addProperty(IS_OP, limboPlayer.isOperator());
|
obj.addProperty(IS_OP, limboPlayer.isOperator());
|
||||||
obj.addProperty(CAN_FLY, limboPlayer.isCanFly());
|
obj.addProperty(CAN_FLY, limboPlayer.isCanFly());
|
||||||
obj.addProperty(WALK_SPEED, limboPlayer.getWalkSpeed());
|
|
||||||
obj.addProperty(FLY_SPEED, limboPlayer.getFlySpeed());
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,10 +22,12 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
/* Packet Adapters */
|
/* Packet Adapters */
|
||||||
private InventoryPacketAdapter inventoryPacketAdapter;
|
private InventoryPacketAdapter inventoryPacketAdapter;
|
||||||
private TabCompletePacketAdapter tabCompletePacketAdapter;
|
private TabCompletePacketAdapter tabCompletePacketAdapter;
|
||||||
|
private FreezePacketAdapter freezePacketAdapter;
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
private boolean protectInvBeforeLogin;
|
private boolean protectInvBeforeLogin;
|
||||||
private boolean denyTabCompleteBeforeLogin;
|
private boolean denyTabCompleteBeforeLogin;
|
||||||
|
private boolean freezePlayerBeforeLogin;
|
||||||
|
|
||||||
/* Service */
|
/* Service */
|
||||||
private boolean isEnabled;
|
private boolean isEnabled;
|
||||||
@ -58,6 +60,11 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
logger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it...");
|
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;
|
this.isEnabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -84,6 +91,16 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
tabCompletePacketAdapter = null;
|
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;
|
this.isEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +118,10 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
tabCompletePacketAdapter.unregister();
|
tabCompletePacketAdapter.unregister();
|
||||||
tabCompletePacketAdapter = null;
|
tabCompletePacketAdapter = null;
|
||||||
}
|
}
|
||||||
|
if (freezePacketAdapter != null) {
|
||||||
|
freezePacketAdapter.unregister();
|
||||||
|
freezePacketAdapter = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,12 +135,36 @@ 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
|
@Override
|
||||||
public void reload(Settings settings) {
|
public void reload(Settings settings) {
|
||||||
boolean oldProtectInventory = this.protectInvBeforeLogin;
|
final boolean oldProtectInventory = this.protectInvBeforeLogin;
|
||||||
|
final boolean oldFreezePlayer = this.freezePlayerBeforeLogin;
|
||||||
|
|
||||||
this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
||||||
this.denyTabCompleteBeforeLogin = settings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_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
|
//it was true and will be deactivated now, so we need to restore the inventory for every player
|
||||||
if (oldProtectInventory && !protectInvBeforeLogin && inventoryPacketAdapter != null) {
|
if (oldProtectInventory && !protectInvBeforeLogin && inventoryPacketAdapter != null) {
|
||||||
@ -130,6 +175,14 @@ 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();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import fr.xephi.authme.data.limbo.LimboService;
|
|||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.events.LoginEvent;
|
import fr.xephi.authme.events.LoginEvent;
|
||||||
import fr.xephi.authme.events.RestoreInventoryEvent;
|
import fr.xephi.authme.events.RestoreInventoryEvent;
|
||||||
|
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||||
import fr.xephi.authme.process.SynchronousProcess;
|
import fr.xephi.authme.process.SynchronousProcess;
|
||||||
@ -23,6 +24,7 @@ import org.bukkit.potion.PotionEffectType;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.List;
|
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;
|
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||||
|
|
||||||
public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
||||||
@ -57,6 +59,9 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private PermissionsManager permissionsManager;
|
private PermissionsManager permissionsManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ProtocolLibService protocolLibService;
|
||||||
|
|
||||||
ProcessSyncPlayerLogin() {
|
ProcessSyncPlayerLogin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +92,9 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
|||||||
if (commonService.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
if (commonService.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||||
restoreInventory(player);
|
restoreInventory(player);
|
||||||
}
|
}
|
||||||
|
if (!commonService.getProperty(ALLOW_UNAUTHED_MOVEMENT)) {
|
||||||
|
protocolLibService.sendUnFreezePacket(player);
|
||||||
|
}
|
||||||
|
|
||||||
final PlayerAuth auth = dataSource.getAuth(name);
|
final PlayerAuth auth = dataSource.getAuth(name);
|
||||||
teleportationService.teleportOnLogin(player, auth, limbo);
|
teleportationService.teleportOnLogin(player, auth, limbo);
|
||||||
|
|||||||
@ -56,6 +56,9 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
|
|||||||
if (service.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
if (service.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||||
protocolLibService.sendBlankInventoryPacket(player);
|
protocolLibService.sendBlankInventoryPacket(player);
|
||||||
}
|
}
|
||||||
|
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)){
|
||||||
|
protocolLibService.sendFreezePacket(player);
|
||||||
|
}
|
||||||
|
|
||||||
applyLogoutEffect(player);
|
applyLogoutEffect(player);
|
||||||
commandManager.runCommandsOnLogout(player);
|
commandManager.runCommandsOnLogout(player);
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import ch.jalu.configme.SettingsHolder;
|
|||||||
import ch.jalu.configme.configurationdata.CommentsConfiguration;
|
import ch.jalu.configme.configurationdata.CommentsConfiguration;
|
||||||
import ch.jalu.configme.properties.Property;
|
import ch.jalu.configme.properties.Property;
|
||||||
import fr.xephi.authme.data.limbo.AllowFlightRestoreType;
|
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.LimboPersistenceType;
|
||||||
import fr.xephi.authme.data.limbo.persistence.SegmentSize;
|
import fr.xephi.authme.data.limbo.persistence.SegmentSize;
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ public final class LimboSettings implements SettingsHolder {
|
|||||||
@Comment({
|
@Comment({
|
||||||
"Besides storing the data in memory, you can define if/how the data should be persisted",
|
"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",
|
"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, ability to fly, and walk/fly speed.",
|
"properly restore things like OP status and the ability to fly",
|
||||||
"DISABLED: no disk storage,",
|
"DISABLED: no disk storage,",
|
||||||
"INDIVIDUAL_FILES: each player data in its own file,",
|
"INDIVIDUAL_FILES: each player data in its own file,",
|
||||||
"DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below"
|
"DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below"
|
||||||
@ -49,23 +48,6 @@ public final class LimboSettings implements SettingsHolder {
|
|||||||
public static final Property<AllowFlightRestoreType> RESTORE_ALLOW_FLIGHT =
|
public static final Property<AllowFlightRestoreType> RESTORE_ALLOW_FLIGHT =
|
||||||
newProperty(AllowFlightRestoreType.class, "limbo.restoreAllowFlight", AllowFlightRestoreType.RESTORE);
|
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() {
|
private LimboSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +55,7 @@ public final class LimboSettings implements SettingsHolder {
|
|||||||
public void registerComments(CommentsConfiguration conf) {
|
public void registerComments(CommentsConfiguration conf) {
|
||||||
String[] limboExplanation = {
|
String[] limboExplanation = {
|
||||||
"Before a user logs in, various properties are temporarily removed from the player,",
|
"Before a user logs in, various properties are temporarily removed from the player,",
|
||||||
"such as OP status, ability to fly, and walk/fly speed.",
|
"such as OP status and the ability to fly.",
|
||||||
"Once the user is logged in, we add back the properties we previously saved.",
|
"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.",
|
"In this section, you may define how these properties should be handled.",
|
||||||
"Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players"
|
"Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players"
|
||||||
|
|||||||
@ -22,32 +22,28 @@ public final class LimboPlayerMatchers {
|
|||||||
|
|
||||||
public static Matcher<LimboPlayer> isLimbo(LimboPlayer limbo) {
|
public static Matcher<LimboPlayer> isLimbo(LimboPlayer limbo) {
|
||||||
String[] groups = limbo.getGroups().toArray(new String[limbo.getGroups().size()]);
|
String[] groups = limbo.getGroups().toArray(new String[limbo.getGroups().size()]);
|
||||||
return isLimbo(limbo.isOperator(), limbo.isCanFly(), limbo.getWalkSpeed(), limbo.getFlySpeed(), groups);
|
return isLimbo(limbo.isOperator(), limbo.isCanFly(), groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matcher<LimboPlayer> isLimbo(boolean isOp, boolean canFly, float walkSpeed, float flySpeed,
|
public static Matcher<LimboPlayer> isLimbo(boolean isOp, boolean canFly, String... groups) {
|
||||||
String... groups) {
|
|
||||||
return new TypeSafeMatcher<LimboPlayer>() {
|
return new TypeSafeMatcher<LimboPlayer>() {
|
||||||
@Override
|
@Override
|
||||||
protected boolean matchesSafely(LimboPlayer item) {
|
protected boolean matchesSafely(LimboPlayer item) {
|
||||||
return item.isOperator() == isOp
|
return item.isOperator() == isOp
|
||||||
&& collectionContains(item.getGroups(), groups)
|
&& collectionContains(item.getGroups(), groups)
|
||||||
&& item.isCanFly() == canFly
|
&& item.isCanFly() == canFly;
|
||||||
&& walkSpeed == item.getWalkSpeed()
|
|
||||||
&& flySpeed == item.getFlySpeed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void describeTo(Description description) {
|
public void describeTo(Description description) {
|
||||||
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s, walkSpeed=%f, flySpeed=%f",
|
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s",
|
||||||
isOp, String.join(" ,", groups), canFly, walkSpeed, flySpeed));
|
isOp, String.join(" ,", groups), canFly));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void describeMismatchSafely(LimboPlayer item, Description description) {
|
public void describeMismatchSafely(LimboPlayer item, Description description) {
|
||||||
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s, walkSpeed=%f, flySpeed=%f",
|
description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s",
|
||||||
item.isOperator(), String.join(" ,", item.getGroups()), item.isCanFly(),
|
item.isOperator(), String.join(" ,", item.getGroups()), item.isCanFly()));
|
||||||
item.getWalkSpeed(), item.getFlySpeed()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,7 +106,7 @@ public class LimboPlayerTaskManagerTest {
|
|||||||
String name = "rats";
|
String name = "rats";
|
||||||
Player player = mock(Player.class);
|
Player player = mock(Player.class);
|
||||||
given(player.getName()).willReturn(name);
|
given(player.getName()).willReturn(name);
|
||||||
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false, 0.1f, 0.0f);
|
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false);
|
||||||
MessageTask existingMessageTask = mock(MessageTask.class);
|
MessageTask existingMessageTask = mock(MessageTask.class);
|
||||||
limboPlayer.setMessageTask(existingMessageTask);
|
limboPlayer.setMessageTask(existingMessageTask);
|
||||||
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8);
|
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8);
|
||||||
@ -129,7 +129,7 @@ public class LimboPlayerTaskManagerTest {
|
|||||||
String name = "race";
|
String name = "race";
|
||||||
Player player = mock(Player.class);
|
Player player = mock(Player.class);
|
||||||
given(player.getName()).willReturn(name);
|
given(player.getName()).willReturn(name);
|
||||||
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false, 0.1f, 0.0f);
|
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false);
|
||||||
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(12);
|
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(12);
|
||||||
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(true);
|
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(true);
|
||||||
String captcha = "M032";
|
String captcha = "M032";
|
||||||
@ -180,7 +180,7 @@ public class LimboPlayerTaskManagerTest {
|
|||||||
public void shouldCancelExistingTimeoutTask() {
|
public void shouldCancelExistingTimeoutTask() {
|
||||||
// given
|
// given
|
||||||
Player player = mock(Player.class);
|
Player player = mock(Player.class);
|
||||||
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true, 0.3f, 0.1f);
|
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true);
|
||||||
BukkitTask existingTask = mock(BukkitTask.class);
|
BukkitTask existingTask = mock(BukkitTask.class);
|
||||||
limboPlayer.setTimeoutTask(existingTask);
|
limboPlayer.setTimeoutTask(existingTask);
|
||||||
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);
|
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);
|
||||||
|
|||||||
@ -37,9 +37,9 @@ public class LimboServiceHelperTest {
|
|||||||
public void shouldMergeLimboPlayers() {
|
public void shouldMergeLimboPlayers() {
|
||||||
// given
|
// given
|
||||||
Location newLocation = mock(Location.class);
|
Location newLocation = mock(Location.class);
|
||||||
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), false, 0.0f, 0.0f);
|
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), false);
|
||||||
Location oldLocation = mock(Location.class);
|
Location oldLocation = mock(Location.class);
|
||||||
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList("grp-old"), true, 0.1f, 0.8f);
|
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList("grp-old"), true);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
|
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
|
||||||
@ -49,16 +49,14 @@ public class LimboServiceHelperTest {
|
|||||||
assertThat(result.isOperator(), equalTo(true));
|
assertThat(result.isOperator(), equalTo(true));
|
||||||
assertThat(result.getGroups(), contains("grp-old"));
|
assertThat(result.getGroups(), contains("grp-old"));
|
||||||
assertThat(result.isCanFly(), equalTo(true));
|
assertThat(result.isCanFly(), equalTo(true));
|
||||||
assertThat(result.getWalkSpeed(), equalTo(0.1f));
|
|
||||||
assertThat(result.getFlySpeed(), equalTo(0.8f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldFallBackToNewLimboForMissingData() {
|
public void shouldFallBackToNewLimboForMissingData() {
|
||||||
// given
|
// given
|
||||||
Location newLocation = mock(Location.class);
|
Location newLocation = mock(Location.class);
|
||||||
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), true, 0.3f, 0.0f);
|
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), true);
|
||||||
LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false, 0.1f, 0.1f);
|
LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
|
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
|
||||||
@ -68,8 +66,6 @@ public class LimboServiceHelperTest {
|
|||||||
assertThat(result.isOperator(), equalTo(false));
|
assertThat(result.isOperator(), equalTo(false));
|
||||||
assertThat(result.getGroups(), contains("grp-new"));
|
assertThat(result.getGroups(), contains("grp-new"));
|
||||||
assertThat(result.isCanFly(), equalTo(true));
|
assertThat(result.isCanFly(), equalTo(true));
|
||||||
assertThat(result.getWalkSpeed(), equalTo(0.3f));
|
|
||||||
assertThat(result.getFlySpeed(), equalTo(0.1f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@ -79,7 +79,7 @@ public class LimboServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateLimboPlayer() {
|
public void shouldCreateLimboPlayer() {
|
||||||
// given
|
// given
|
||||||
Player player = newPlayer("Bobby", true, 0.3f, false, 0.2f);
|
Player player = newPlayer("Bobby", true, false);
|
||||||
Location playerLoc = mock(Location.class);
|
Location playerLoc = mock(Location.class);
|
||||||
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
|
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
|
||||||
given(permissionsManager.hasGroupSupport()).willReturn(true);
|
given(permissionsManager.hasGroupSupport()).willReturn(true);
|
||||||
@ -93,17 +93,13 @@ public class LimboServiceTest {
|
|||||||
verify(taskManager).registerMessageTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.LOG_IN));
|
verify(taskManager).registerMessageTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.LOG_IN));
|
||||||
verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
|
verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
|
||||||
verify(player).setAllowFlight(false);
|
verify(player).setAllowFlight(false);
|
||||||
verify(player).setFlySpeed(0.0f);
|
|
||||||
verify(player).setWalkSpeed(0.0f);
|
|
||||||
|
|
||||||
assertThat(limboService.hasLimboPlayer("Bobby"), equalTo(true));
|
assertThat(limboService.hasLimboPlayer("Bobby"), equalTo(true));
|
||||||
LimboPlayer limbo = limboService.getLimboPlayer("Bobby");
|
LimboPlayer limbo = limboService.getLimboPlayer("Bobby");
|
||||||
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.REGISTERED_UNAUTHENTICATED);
|
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.REGISTERED_UNAUTHENTICATED);
|
||||||
assertThat(limbo, not(nullValue()));
|
assertThat(limbo, not(nullValue()));
|
||||||
assertThat(limbo.isOperator(), equalTo(true));
|
assertThat(limbo.isOperator(), equalTo(true));
|
||||||
assertThat(limbo.getWalkSpeed(), equalTo(0.3f));
|
|
||||||
assertThat(limbo.isCanFly(), equalTo(false));
|
assertThat(limbo.isCanFly(), equalTo(false));
|
||||||
assertThat(limbo.getFlySpeed(), equalTo(0.2f));
|
|
||||||
assertThat(limbo.getLocation(), equalTo(playerLoc));
|
assertThat(limbo.getLocation(), equalTo(playerLoc));
|
||||||
assertThat(limbo.getGroups(), equalTo(Collections.singletonList("permgrwp")));
|
assertThat(limbo.getGroups(), equalTo(Collections.singletonList("permgrwp")));
|
||||||
}
|
}
|
||||||
@ -111,7 +107,7 @@ public class LimboServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldNotKeepOpStatusForUnregisteredPlayer() {
|
public void shouldNotKeepOpStatusForUnregisteredPlayer() {
|
||||||
// given
|
// given
|
||||||
Player player = newPlayer("CharleS", true, 0.1f, true, 0.4f);
|
Player player = newPlayer("CharleS", true, true);
|
||||||
Location playerLoc = mock(Location.class);
|
Location playerLoc = mock(Location.class);
|
||||||
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
|
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
|
||||||
given(permissionsManager.hasGroupSupport()).willReturn(false);
|
given(permissionsManager.hasGroupSupport()).willReturn(false);
|
||||||
@ -125,16 +121,12 @@ public class LimboServiceTest {
|
|||||||
verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
|
verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
|
||||||
verify(permissionsManager, only()).hasGroupSupport();
|
verify(permissionsManager, only()).hasGroupSupport();
|
||||||
verify(player).setAllowFlight(false);
|
verify(player).setAllowFlight(false);
|
||||||
verify(player).setFlySpeed(0.0f);
|
|
||||||
verify(player).setWalkSpeed(0.0f);
|
|
||||||
|
|
||||||
LimboPlayer limbo = limboService.getLimboPlayer("charles");
|
LimboPlayer limbo = limboService.getLimboPlayer("charles");
|
||||||
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.UNREGISTERED);
|
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.UNREGISTERED);
|
||||||
assertThat(limbo, not(nullValue()));
|
assertThat(limbo, not(nullValue()));
|
||||||
assertThat(limbo.isOperator(), equalTo(false));
|
assertThat(limbo.isOperator(), equalTo(false));
|
||||||
assertThat(limbo.getWalkSpeed(), equalTo(0.1f));
|
|
||||||
assertThat(limbo.isCanFly(), equalTo(true));
|
assertThat(limbo.isCanFly(), equalTo(true));
|
||||||
assertThat(limbo.getFlySpeed(), equalTo(0.4f));
|
|
||||||
assertThat(limbo.getLocation(), equalTo(playerLoc));
|
assertThat(limbo.getLocation(), equalTo(playerLoc));
|
||||||
assertThat(limbo.getGroups(), equalTo(Collections.emptyList()));
|
assertThat(limbo.getGroups(), equalTo(Collections.emptyList()));
|
||||||
}
|
}
|
||||||
@ -162,22 +154,18 @@ public class LimboServiceTest {
|
|||||||
public void shouldRestoreData() {
|
public void shouldRestoreData() {
|
||||||
// given
|
// given
|
||||||
LimboPlayer limbo = Mockito.spy(convertToLimboPlayer(
|
LimboPlayer limbo = Mockito.spy(convertToLimboPlayer(
|
||||||
newPlayer("John", true, 0.4f, false, 0.0f), null, Collections.emptyList()));
|
newPlayer("John", true, false), null, Collections.emptyList()));
|
||||||
getLimboMap().put("john", limbo);
|
getLimboMap().put("john", limbo);
|
||||||
Player player = newPlayer("John", false, 0.2f, false, 0.7f);
|
Player player = newPlayer("John", false, false);
|
||||||
|
|
||||||
given(settings.getProperty(LimboSettings.RESTORE_ALLOW_FLIGHT)).willReturn(AllowFlightRestoreType.ENABLE);
|
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
|
// when
|
||||||
limboService.restoreData(player);
|
limboService.restoreData(player);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(player).setOp(true);
|
verify(player).setOp(true);
|
||||||
verify(player).setWalkSpeed(0.4f);
|
|
||||||
verify(player).setAllowFlight(true);
|
verify(player).setAllowFlight(true);
|
||||||
verify(player).setFlySpeed(LimboPlayer.DEFAULT_FLY_SPEED);
|
|
||||||
verify(limbo).clearTasks();
|
verify(limbo).clearTasks();
|
||||||
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.LOGGED_IN);
|
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.LOGGED_IN);
|
||||||
assertThat(limboService.hasLimboPlayer("John"), equalTo(false));
|
assertThat(limboService.hasLimboPlayer("John"), equalTo(false));
|
||||||
@ -232,18 +220,15 @@ public class LimboServiceTest {
|
|||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Player newPlayer(String name, boolean isOp, float walkSpeed, boolean canFly, float flySpeed) {
|
private static Player newPlayer(String name, boolean isOp, boolean canFly) {
|
||||||
Player player = newPlayer(name);
|
Player player = newPlayer(name);
|
||||||
given(player.isOp()).willReturn(isOp);
|
given(player.isOp()).willReturn(isOp);
|
||||||
given(player.getWalkSpeed()).willReturn(walkSpeed);
|
|
||||||
given(player.getAllowFlight()).willReturn(canFly);
|
given(player.getAllowFlight()).willReturn(canFly);
|
||||||
given(player.getFlySpeed()).willReturn(flySpeed);
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LimboPlayer convertToLimboPlayer(Player player, Location location, Collection<String> groups) {
|
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() {
|
private Map<String, LimboPlayer> getLimboMap() {
|
||||||
|
|||||||
@ -1,108 +0,0 @@
|
|||||||
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 + "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -48,22 +48,22 @@ public class DistributedFilesPersistenceHandlerTest {
|
|||||||
/** Player is in seg32-10110 and should be migrated into seg16-f. */
|
/** 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 UUID MIGRATED_UUID = fromString("f6a97c88-7c8f-c12e-4931-6206d4ca067d");
|
||||||
private static final Matcher<LimboPlayer> MIGRATED_LIMBO_MATCHER =
|
private static final Matcher<LimboPlayer> MIGRATED_LIMBO_MATCHER =
|
||||||
isLimbo(false, true, 0.2f, 0.1f, "noob");
|
isLimbo(false, true, "noob");
|
||||||
|
|
||||||
/** Existing player in seg16-f. */
|
/** Existing player in seg16-f. */
|
||||||
private static final UUID UUID_FAB69 = fromString("fab69c88-2cd0-1fed-f00d-dead14ca067d");
|
private static final UUID UUID_FAB69 = fromString("fab69c88-2cd0-1fed-f00d-dead14ca067d");
|
||||||
private static final Matcher<LimboPlayer> FAB69_MATCHER =
|
private static final Matcher<LimboPlayer> FAB69_MATCHER =
|
||||||
isLimbo(false, false, 0.2f, 0.1f, "");
|
isLimbo(false, false, "");
|
||||||
|
|
||||||
/** Player in seg16-8. */
|
/** Player in seg16-8. */
|
||||||
private static final UUID UUID_STAFF = fromString("88897c88-7c8f-c12e-4931-6206d4ca067d");
|
private static final UUID UUID_STAFF = fromString("88897c88-7c8f-c12e-4931-6206d4ca067d");
|
||||||
private static final Matcher<LimboPlayer> STAFF_MATCHER =
|
private static final Matcher<LimboPlayer> STAFF_MATCHER =
|
||||||
isLimbo(true, false, 0.3f, 0.1f, "staff", "mod");
|
isLimbo(true, false, "staff", "mod");
|
||||||
|
|
||||||
/** Player in seg16-8. */
|
/** Player in seg16-8. */
|
||||||
private static final UUID UUID_8C679 = fromString("8c679491-1234-abcd-9102-1fa6e0cc3f81");
|
private static final UUID UUID_8C679 = fromString("8c679491-1234-abcd-9102-1fa6e0cc3f81");
|
||||||
private static final Matcher<LimboPlayer> SC679_MATCHER =
|
private static final Matcher<LimboPlayer> SC679_MATCHER =
|
||||||
isLimbo(false, true, 0.1f, 0.0f, "primary");
|
isLimbo(false, true, "primary");
|
||||||
|
|
||||||
/** UUID for which no data is stored (belongs to a segment file that does not exist, seg16-4). */
|
/** 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");
|
private static final UUID UNKNOWN_UUID = fromString("42d1cc0b-8f12-d04a-e7ba-a067d05cdc39");
|
||||||
@ -156,10 +156,10 @@ public class DistributedFilesPersistenceHandlerTest {
|
|||||||
// given
|
// given
|
||||||
Player uuidToAdd1 = mockPlayerWithUuid(UNKNOWN_UUID);
|
Player uuidToAdd1 = mockPlayerWithUuid(UNKNOWN_UUID);
|
||||||
Location location1 = mockLocation("1world");
|
Location location1 = mockLocation("1world");
|
||||||
LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList("group-1"), true, 0.1f, 0.2f);
|
LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList("group-1"), true);
|
||||||
Player uuidToAdd2 = mockPlayerWithUuid(UNKNOWN_UUID2);
|
Player uuidToAdd2 = mockPlayerWithUuid(UNKNOWN_UUID2);
|
||||||
Location location2 = mockLocation("2world");
|
Location location2 = mockLocation("2world");
|
||||||
LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false, 0.0f, 0.25f);
|
LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
persistenceHandler.saveLimboPlayer(uuidToAdd1, limbo1);
|
persistenceHandler.saveLimboPlayer(uuidToAdd1, limbo1);
|
||||||
|
|||||||
@ -78,8 +78,6 @@ public class IndividualFilesPersistenceHandlerTest {
|
|||||||
assertThat(data, not(nullValue()));
|
assertThat(data, not(nullValue()));
|
||||||
assertThat(data.isOperator(), equalTo(true));
|
assertThat(data.isOperator(), equalTo(true));
|
||||||
assertThat(data.isCanFly(), equalTo(true));
|
assertThat(data.isCanFly(), equalTo(true));
|
||||||
assertThat(data.getWalkSpeed(), equalTo(0.2f));
|
|
||||||
assertThat(data.getFlySpeed(), equalTo(0.1f));
|
|
||||||
assertThat(data.getGroups(), contains("players"));
|
assertThat(data.getGroups(), contains("players"));
|
||||||
Location location = data.getLocation();
|
Location location = data.getLocation();
|
||||||
assertThat(location.getX(), equalTo(-113.219));
|
assertThat(location.getX(), equalTo(-113.219));
|
||||||
@ -114,7 +112,7 @@ public class IndividualFilesPersistenceHandlerTest {
|
|||||||
World world = mock(World.class);
|
World world = mock(World.class);
|
||||||
given(world.getName()).willReturn("player-world");
|
given(world.getName()).willReturn("player-world");
|
||||||
Location location = new Location(world, 0.2, 102.25, -89.28, 3.02f, 90.13f);
|
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, 1.2f, 0.8f);
|
LimboPlayer limbo = new LimboPlayer(location, true, Collections.singletonList("primary-grp"), true);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
handler.saveLimboPlayer(player, limbo);
|
handler.saveLimboPlayer(player, limbo);
|
||||||
|
|||||||
@ -9,7 +9,5 @@
|
|||||||
},
|
},
|
||||||
"operator": true,
|
"operator": true,
|
||||||
"can-fly": true,
|
"can-fly": true,
|
||||||
"walk-speed": 0.2,
|
|
||||||
"fly-speed": 0.1,
|
|
||||||
"group": "players"
|
"group": "players"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,9 +13,7 @@
|
|||||||
"mod"
|
"mod"
|
||||||
],
|
],
|
||||||
"operator": true,
|
"operator": true,
|
||||||
"can-fly": false,
|
"can-fly": false
|
||||||
"walk-speed": 0.3,
|
|
||||||
"fly-speed": 0.1
|
|
||||||
},
|
},
|
||||||
"8c679491-1234-abcd-9102-1fa6e0cc3f81": {
|
"8c679491-1234-abcd-9102-1fa6e0cc3f81": {
|
||||||
"location": {
|
"location": {
|
||||||
@ -28,8 +26,6 @@
|
|||||||
},
|
},
|
||||||
"group": "primary",
|
"group": "primary",
|
||||||
"operator": false,
|
"operator": false,
|
||||||
"can-fly": true,
|
"can-fly": true
|
||||||
"walk-speed": 0.1,
|
|
||||||
"fly-speed": 0.0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
},
|
},
|
||||||
"group": "",
|
"group": "",
|
||||||
"operator": false,
|
"operator": false,
|
||||||
"can-fly": false,
|
"can-fly": false
|
||||||
"walk-speed": 0.2,
|
|
||||||
"fly-speed": 0.1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
},
|
},
|
||||||
"group": "noob",
|
"group": "noob",
|
||||||
"operator": false,
|
"operator": false,
|
||||||
"can-fly": true,
|
"can-fly": true
|
||||||
"walk-speed": 0.2,
|
|
||||||
"fly-speed": 0.1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user