commit
4016460c17
@ -3,13 +3,7 @@ sudo: false
|
||||
language: java
|
||||
jdk: oraclejdk7
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.m2/repository'
|
||||
|
||||
script:
|
||||
- mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false
|
||||
- mvn clean install -B -U
|
||||
script: mvn verify -B
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sun Feb 14 19:00:30 CET 2016. See commands/commands.tpl.md -->
|
||||
<!-- File auto-generated on Thu Apr 07 17:17:20 CEST 2016. See commands/commands.tpl.md -->
|
||||
|
||||
## AuthMe Commands
|
||||
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >`
|
||||
@ -7,74 +7,72 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
||||
|
||||
- **/authme**: The main AuthMeReloaded command. The root for all admin commands.
|
||||
- **/authme register** <player> <password>: Register the specified player with the specified password.
|
||||
<br />Requires `authme.admin.register`
|
||||
<br />Requires `authme.admin.register`
|
||||
- **/authme unregister** <player>: Unregister the specified player.
|
||||
<br />Requires `authme.admin.unregister`
|
||||
<br />Requires `authme.admin.unregister`
|
||||
- **/authme forcelogin** [player]: Enforce the specified player to login.
|
||||
<br />Requires `authme.player.canbeforced`
|
||||
<br />Requires `authme.admin.forcelogin`
|
||||
- **/authme password** <player> <pwd>: Change the password of a player.
|
||||
<br />Requires `authme.admin.changepassword`
|
||||
<br />Requires `authme.admin.changepassword`
|
||||
- **/authme lastlogin** [player]: View the date of the specified players last login.
|
||||
<br />Requires `authme.admin.lastlogin`
|
||||
<br />Requires `authme.admin.lastlogin`
|
||||
- **/authme accounts** [player]: Display all accounts of a player by his player name or IP.
|
||||
<br />Requires `authme.admin.accounts`
|
||||
<br />Requires `authme.admin.accounts`
|
||||
- **/authme email** [player]: Display the email address of the specified player if set.
|
||||
<br />Requires `authme.admin.getemail`
|
||||
<br />Requires `authme.admin.getemail`
|
||||
- **/authme setemail** <player> <email>: Change the email address of the specified player.
|
||||
<br />Requires `authme.admin.changemail`
|
||||
<br />Requires `authme.admin.changemail`
|
||||
- **/authme getip** <player>: Get the IP address of the specified online player.
|
||||
<br />Requires `authme.admin.getip`
|
||||
- **/authme spawn** <player>: Teleport to the spawn.
|
||||
<br />Requires `authme.admin.spawn`
|
||||
<br />Requires `authme.admin.getip`
|
||||
- **/authme spawn**: Teleport to the spawn.
|
||||
<br />Requires `authme.admin.spawn`
|
||||
- **/authme setspawn**: Change the player's spawn to your current position.
|
||||
<br />Requires `authme.admin.setspawn`
|
||||
<br />Requires `authme.admin.setspawn`
|
||||
- **/authme firstspawn**: Teleport to the first spawn.
|
||||
<br />Requires `authme.admin.firstspawn`
|
||||
<br />Requires `authme.admin.firstspawn`
|
||||
- **/authme setfirstspawn**: Change the first player's spawn to your current position.
|
||||
<br />Requires `authme.admin.setfirstspawn`
|
||||
<br />Requires `authme.admin.setfirstspawn`
|
||||
- **/authme purge** <days>: Purge old AuthMeReloaded data longer than the specified amount of days ago.
|
||||
<br />Requires `authme.admin.purge`
|
||||
<br />Requires `authme.admin.purge`
|
||||
- **/authme resetpos** <player/*>: Purge the last know position of the specified player or all of them.
|
||||
<br />Requires `authme.admin.purgelastpos`
|
||||
<br />Requires `authme.admin.purgelastpos`
|
||||
- **/authme purgebannedplayers**: Purge all AuthMeReloaded data for banned players.
|
||||
<br />Requires `authme.admin.purgebannedplayers`
|
||||
<br />Requires `authme.admin.purgebannedplayers`
|
||||
- **/authme switchantibot** [mode]: Switch or toggle the AntiBot mode to the specified state.
|
||||
<br />Requires `authme.admin.switchantibot`
|
||||
<br />Requires `authme.admin.switchantibot`
|
||||
- **/authme reload**: Reload the AuthMeReloaded plugin.
|
||||
<br />Requires `authme.admin.reload`
|
||||
<br />Requires `authme.admin.reload`
|
||||
- **/authme version**: Show detailed information about the installed AuthMeReloaded version, the developers, contributors, and license.
|
||||
- **/authme converter** <job>: Converter command for AuthMeReloaded.
|
||||
<br />Requires `authme.admin.converter`
|
||||
- **/authme help** [query]: View detailed help for /authme commands.
|
||||
- **/login** <password>: Command to log in using AuthMeReloaded.
|
||||
<br />Requires `authme.player.login`
|
||||
<br />Requires `authme.player.login`
|
||||
- **/login help** [query]: View detailed help for /login commands.
|
||||
- **/logout**: Command to logout using AuthMeReloaded.
|
||||
<br />Requires `authme.player.logout`
|
||||
<br />Requires `authme.player.logout`
|
||||
- **/logout help** [query]: View detailed help for /logout commands.
|
||||
- **/register** [password] [verifyPassword]: Command to register using AuthMeReloaded.
|
||||
<br />Requires `authme.player.register`
|
||||
<br />Requires `authme.player.register`
|
||||
- **/register help** [query]: View detailed help for /register commands.
|
||||
- **/unreg** <password>: Command to unregister using AuthMeReloaded.
|
||||
<br />Requires `authme.player.unregister`
|
||||
<br />Requires `authme.player.unregister`
|
||||
- **/unreg help** [query]: View detailed help for /unreg commands.
|
||||
- **/changepassword** <oldPassword> <newPassword>: Command to change your password using AuthMeReloaded.
|
||||
<br />Requires `authme.player.changepassword`
|
||||
<br />Requires `authme.player.changepassword`
|
||||
- **/changepassword help** [query]: View detailed help for /changepassword commands.
|
||||
- **/email**: The AuthMeReloaded Email command base.
|
||||
- **/email add** <email> <verifyEmail>: Add a new email address to your account.
|
||||
<br />Requires `authme.player.email.add`
|
||||
<br />Requires `authme.player.email.add`
|
||||
- **/email change** <oldEmail> <newEmail>: Change an email address of your account.
|
||||
<br />Requires `authme.player.email.change`
|
||||
<br />Requires `authme.player.email.change`
|
||||
- **/email recover** <email>: Recover your account using an Email address by sending a mail containing a new password.
|
||||
<br />Requires `authme.player.email.recover`
|
||||
<br />Requires `authme.player.email.recover`
|
||||
- **/email help** [query]: View detailed help for /email commands.
|
||||
- **/captcha** <captcha>: Captcha command for AuthMeReloaded.
|
||||
<br />Requires `authme.player.captcha`
|
||||
<br />Requires `authme.player.captcha`
|
||||
- **/captcha help** [query]: View detailed help for /captcha commands.
|
||||
- **/converter** <job>: Converter command for AuthMeReloaded.
|
||||
<br />Requires `authme.admin.converter`
|
||||
- **/converter help** [query]: View detailed help for /converter commands.
|
||||
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:30 CET 2016
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Thu Apr 07 17:17:20 CEST 2016
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sun Feb 14 19:00:32 CET 2016. See hashmethods/hash_algorithms.tpl.md -->
|
||||
<!-- File auto-generated on Thu Apr 07 17:17:22 CEST 2016. See hashmethods/hash_algorithms.tpl.md -->
|
||||
|
||||
## Hash Algorithms
|
||||
AuthMe supports the following hash algorithms for storing your passwords safely.
|
||||
@ -17,7 +17,7 @@ JOOMLA | Recommended | 65 | | | Text | 32 |
|
||||
MD5 | Do not use | 32 | | | None | |
|
||||
MD5VB | Acceptable | 56 | | | Text | 16 |
|
||||
MYBB | Acceptable | 32 | | | Text | 8 | Y
|
||||
PBKDF2 | Does not work | 330 | | | Text | 12 |
|
||||
PBKDF2 | Does not work | 328 | | | Text | 12 |
|
||||
PBKDF2DJANGO | Acceptable | 77 | Y | | Text | 12 |
|
||||
PHPBB | Acceptable | 34 | | | Text | 16 |
|
||||
PHPFUSION | Do not use | 64 | Y | | | | Y
|
||||
@ -82,4 +82,4 @@ or bad.
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:32 CET 2016
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Thu Apr 07 17:17:22 CEST 2016
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sun Feb 14 19:00:34 CET 2016. See permissions/permission_nodes.tpl.md -->
|
||||
<!-- File auto-generated on Thu Apr 07 17:17:24 CEST 2016. See permissions/permission_nodes.tpl.md -->
|
||||
|
||||
## AuthMe Permission Nodes
|
||||
The following are the permission nodes that are currently supported by the latest dev builds.
|
||||
@ -42,7 +42,6 @@ The following are the permission nodes that are currently supported by the lates
|
||||
- **authme.player.unregister** – Command permission to unregister.
|
||||
- **authme.vip** – Permission node to identify VIP users.
|
||||
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:34 CET 2016
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Thu Apr 07 17:17:24 CEST 2016
|
||||
|
||||
21
pom.xml
21
pom.xml
@ -6,11 +6,11 @@
|
||||
|
||||
<groupId>fr.xephi</groupId>
|
||||
<artifactId>authme</artifactId>
|
||||
<version>5.2-SNAPSHOT</version>
|
||||
<version>5.2-BETA2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>AuthMeReloaded</name>
|
||||
<description>Authentication plugin for CraftBukkit/Spigot!</description>
|
||||
<description>The first authentication plugin for the Bukkit API!</description>
|
||||
<inceptionYear>2013</inceptionYear>
|
||||
<url>http://dev.bukkit.org/bukkit-plugins/authme-reloaded/</url>
|
||||
<!-- See also: https://www.spigotmc.org/resources/authme-reloaded.6269/ -->
|
||||
@ -23,7 +23,7 @@
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/Xephi/AuthMeReloaded.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:Xephi/AuthMeReloaded.git</developerConnection>
|
||||
<url>http://github.com/Xephi/AuthMeReloaded</url>
|
||||
<url>https://github.com/Xephi/AuthMeReloaded</url>
|
||||
</scm>
|
||||
|
||||
<ciManagement>
|
||||
@ -40,6 +40,7 @@
|
||||
<license>
|
||||
<name>The GNU General Public Licence version 3 (GPLv3)</name>
|
||||
<url>http://www.gnu.org/licenses/gpl-3.0.html</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
@ -63,7 +64,7 @@
|
||||
<buildNumber>Unknown</buildNumber>
|
||||
|
||||
<!-- Change Bukkit Version HERE! -->
|
||||
<bukkitVersion>1.9-R0.1-SNAPSHOT</bukkitVersion>
|
||||
<bukkitVersion>1.9.2-R0.1-SNAPSHOT</bukkitVersion>
|
||||
</properties>
|
||||
|
||||
<!-- Jenkins profile (add the real buildNumber to the version string) -->
|
||||
@ -336,7 +337,7 @@
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.4.5</version>
|
||||
<version>2.4.6</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -349,7 +350,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.20</version>
|
||||
<version>1.7.21</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@ -428,6 +429,14 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--Spigot API-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.9.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Bukkit API, http://www.spigotmc.org/ or http://bukkit.org/ -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
|
||||
@ -1,8 +1,34 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.api.NewAPI;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.JsonCache;
|
||||
@ -28,6 +54,7 @@ import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener16;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener18;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener19;
|
||||
import fr.xephi.authme.listener.AuthMeServerListener;
|
||||
import fr.xephi.authme.listener.AuthMeTabCompletePacketAdapter;
|
||||
import fr.xephi.authme.listener.AuthMeTablistPacketAdapter;
|
||||
@ -62,32 +89,7 @@ import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import fr.xephi.authme.util.MigrationService;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
|
||||
/**
|
||||
* The AuthMe main class.
|
||||
@ -106,23 +108,25 @@ public class AuthMe extends JavaPlugin {
|
||||
private static Server server;
|
||||
/*
|
||||
* Maps and stuff
|
||||
* TODO: Clean up and Move into a manager
|
||||
*/
|
||||
// TODO #601: Integrate CaptchaManager
|
||||
public final ConcurrentHashMap<String, BukkitTask> sessions = new ConcurrentHashMap<>();
|
||||
public final ConcurrentHashMap<String, Integer> captcha = new ConcurrentHashMap<>();
|
||||
public final ConcurrentHashMap<String, String> cap = new ConcurrentHashMap<>();
|
||||
|
||||
/*
|
||||
* Public Instances
|
||||
* TODO #432: Encapsulation
|
||||
*/
|
||||
public NewAPI api;
|
||||
// TODO #655: Encapsulate mail
|
||||
public SendMailSSL mail;
|
||||
// TODO #656: Encapsulate data manager
|
||||
public DataManager dataManager;
|
||||
/*
|
||||
* Plugin Hooks
|
||||
* TODO: Move into modules
|
||||
* Private instances
|
||||
* TODO #432: Move instantiation and management of these services
|
||||
*/
|
||||
// TODO #604: Encapsulate ProtocolLib members
|
||||
public AuthMeInventoryPacketAdapter inventoryProtector;
|
||||
public AuthMeTabCompletePacketAdapter tabComplete;
|
||||
public AuthMeTablistPacketAdapter tablistHider;
|
||||
@ -134,11 +138,11 @@ public class AuthMe extends JavaPlugin {
|
||||
private JsonCache playerBackup;
|
||||
private PasswordSecurity passwordSecurity;
|
||||
private DataSource database;
|
||||
private IpAddressManager ipAddressManager;
|
||||
private PluginHooks pluginHooks;
|
||||
private SpawnLoader spawnLoader;
|
||||
private AntiBot antiBot;
|
||||
private boolean autoPurging;
|
||||
private BukkitService bukkitService;
|
||||
|
||||
/**
|
||||
* Get the plugin's instance.
|
||||
@ -248,24 +252,19 @@ public class AuthMe extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
bukkitService = new BukkitService(this);
|
||||
pluginHooks = new PluginHooks(server.getPluginManager());
|
||||
|
||||
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
|
||||
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager());
|
||||
ipAddressManager = new IpAddressManager(newSettings);
|
||||
|
||||
// Initialize spawn loader
|
||||
spawnLoader = new SpawnLoader(getDataFolder(), newSettings, pluginHooks);
|
||||
|
||||
|
||||
// Set up the permissions manager and command handler
|
||||
permsMan = initializePermissionsManager();
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager,
|
||||
pluginHooks, spawnLoader, antiBot);
|
||||
|
||||
// AntiBot delay
|
||||
BukkitService bukkitService = new BukkitService(this);
|
||||
antiBot = new AntiBot(newSettings, messages, permsMan, bukkitService);
|
||||
ValidationService validationService = new ValidationService(newSettings, database, permsMan);
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings,
|
||||
pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
|
||||
|
||||
// Set up Metrics
|
||||
MetricsStarter.setupMetrics(plugin, newSettings);
|
||||
@ -292,24 +291,25 @@ public class AuthMe extends JavaPlugin {
|
||||
playerBackup = new JsonCache();
|
||||
|
||||
// Set the DataManager
|
||||
dataManager = new DataManager(this, pluginHooks);
|
||||
dataManager = new DataManager(this, pluginHooks, bukkitService);
|
||||
|
||||
// Set up the new API
|
||||
setupApi();
|
||||
|
||||
// Set up the management
|
||||
ProcessService processService = new ProcessService(newSettings, messages, this, database, ipAddressManager,
|
||||
passwordSecurity, pluginHooks, spawnLoader);
|
||||
ProcessService processService = new ProcessService(newSettings, messages, this, database,
|
||||
passwordSecurity, pluginHooks, spawnLoader, validationService, bukkitService);
|
||||
management = new Management(this, processService, database, PlayerCache.getInstance());
|
||||
|
||||
// Set up the BungeeCord hook
|
||||
setupBungeeCordHook(newSettings, ipAddressManager);
|
||||
setupBungeeCordHook(newSettings);
|
||||
|
||||
// Reload support hook
|
||||
reloadSupportHook();
|
||||
|
||||
// Register event listeners
|
||||
registerEventListeners(messages, database, management, pluginHooks, spawnLoader, antiBot);
|
||||
registerEventListeners(
|
||||
messages, database, management, pluginHooks, spawnLoader, antiBot, bukkitService, validationService);
|
||||
// Start Email recall task if needed
|
||||
scheduleRecallEmailTask();
|
||||
|
||||
@ -317,7 +317,6 @@ public class AuthMe extends JavaPlugin {
|
||||
showSettingsWarnings();
|
||||
|
||||
// Sponsor messages
|
||||
ConsoleLogger.info("AuthMe hooks perfectly with the VeryGames server hosting!");
|
||||
ConsoleLogger.info("Development builds are available on our jenkins, thanks to f14stelt.");
|
||||
ConsoleLogger.info("Do you want a good game server? Look at our sponsor GameHosting.it leader in Italy as Game Server Provider!");
|
||||
|
||||
@ -341,7 +340,7 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
database.reload();
|
||||
messages.reload(newSettings.getMessagesFile());
|
||||
passwordSecurity.reload(newSettings);
|
||||
passwordSecurity.reload();
|
||||
spawnLoader.initialize(newSettings);
|
||||
}
|
||||
|
||||
@ -375,15 +374,18 @@ public class AuthMe extends JavaPlugin {
|
||||
* Register all event listeners.
|
||||
*/
|
||||
private void registerEventListeners(Messages messages, DataSource dataSource, Management management,
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot) {
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
|
||||
BukkitService bukkitService, ValidationService validationService) {
|
||||
// Get the plugin manager instance
|
||||
PluginManager pluginManager = server.getPluginManager();
|
||||
|
||||
// Register event listeners
|
||||
pluginManager.registerEvents(new AuthMePlayerListener(this, messages, dataSource, antiBot, management), this);
|
||||
pluginManager.registerEvents(new AuthMePlayerListener(
|
||||
this, newSettings, messages, dataSource, antiBot, management, bukkitService, validationService), this);
|
||||
pluginManager.registerEvents(new AuthMeBlockListener(), this);
|
||||
pluginManager.registerEvents(new AuthMeEntityListener(), this);
|
||||
pluginManager.registerEvents(new AuthMeServerListener(this, messages, pluginHooks, spawnLoader), this);
|
||||
pluginManager.registerEvents(new AuthMeServerListener(
|
||||
this, messages, newSettings, pluginHooks, spawnLoader, validationService), this);
|
||||
|
||||
// Try to register 1.6 player listeners
|
||||
try {
|
||||
@ -398,11 +400,18 @@ public class AuthMe extends JavaPlugin {
|
||||
pluginManager.registerEvents(new AuthMePlayerListener18(), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// Try to register 1.9 player listeners
|
||||
try {
|
||||
Class.forName("org.spigotmc.event.player.PlayerSpawnLocationEvent");
|
||||
pluginManager.registerEvents(new AuthMePlayerListener19(this), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadSupportHook() {
|
||||
if (database != null) {
|
||||
int playersOnline = Utils.getOnlinePlayers().size();
|
||||
int playersOnline = bukkitService.getOnlinePlayers().size();
|
||||
if (playersOnline < 1) {
|
||||
database.purgeLogged();
|
||||
} else if (Settings.reloadSupport) {
|
||||
@ -421,23 +430,23 @@ public class AuthMe extends JavaPlugin {
|
||||
/**
|
||||
* Set up the BungeeCord hook.
|
||||
*/
|
||||
private void setupBungeeCordHook(NewSetting settings, IpAddressManager ipAddressManager) {
|
||||
private void setupBungeeCordHook(NewSetting settings) {
|
||||
if (settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
Bukkit.getMessenger().registerIncomingPluginChannel(
|
||||
this, "BungeeCord", new BungeeCordMessage(this, ipAddressManager));
|
||||
this, "BungeeCord", new BungeeCordMessage(this));
|
||||
}
|
||||
}
|
||||
|
||||
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
|
||||
PasswordSecurity passwordSecurity, NewSetting settings,
|
||||
IpAddressManager ipAddressManager, PluginHooks pluginHooks,
|
||||
SpawnLoader spawnLoader, AntiBot antiBot) {
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
|
||||
ValidationService validationService, BukkitService bukkitService) {
|
||||
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
|
||||
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
|
||||
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
|
||||
CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity,
|
||||
permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot);
|
||||
permissionsManager, settings, pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
|
||||
return new CommandHandler(commandService);
|
||||
}
|
||||
|
||||
@ -501,9 +510,11 @@ public class AuthMe extends JavaPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Save player data
|
||||
Collection<? extends Player> players = Utils.getOnlinePlayers();
|
||||
for (Player player : players) {
|
||||
savePlayer(player);
|
||||
if (bukkitService != null) {
|
||||
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
|
||||
for (Player player : players) {
|
||||
savePlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
// Do backup on stop if enabled
|
||||
@ -616,7 +627,7 @@ public class AuthMe extends JavaPlugin {
|
||||
* Set up the permissions manager.
|
||||
*/
|
||||
private PermissionsManager initializePermissionsManager() {
|
||||
PermissionsManager manager = new PermissionsManager(Bukkit.getServer(), this, getLogger());
|
||||
PermissionsManager manager = new PermissionsManager(Bukkit.getServer(), getLogger());
|
||||
manager.setup();
|
||||
return manager;
|
||||
}
|
||||
@ -662,7 +673,7 @@ public class AuthMe extends JavaPlugin {
|
||||
tabComplete = null;
|
||||
}
|
||||
if (newSettings.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN) && tablistHider == null) {
|
||||
tablistHider = new AuthMeTablistPacketAdapter(this);
|
||||
tablistHider = new AuthMeTablistPacketAdapter(this, bukkitService);
|
||||
tablistHider.register();
|
||||
} else if (tablistHider != null) {
|
||||
tablistHider.unregister();
|
||||
@ -759,8 +770,8 @@ public class AuthMe extends JavaPlugin {
|
||||
public void run() {
|
||||
for (PlayerAuth auth : database.getLoggedPlayers()) {
|
||||
String email = auth.getEmail();
|
||||
if (StringUtils.isEmpty(email) || email.equalsIgnoreCase("your@email.com")) {
|
||||
Player player = Utils.getPlayer(auth.getRealName());
|
||||
if (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email)) {
|
||||
Player player = bukkitService.getPlayerExact(auth.getRealName());
|
||||
if (player != null) {
|
||||
messages.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
@ -771,8 +782,8 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
public String replaceAllInfo(String message, Player player) {
|
||||
String playersOnline = Integer.toString(Utils.getOnlinePlayers().size());
|
||||
String ipAddress = ipAddressManager.getPlayerIp(player);
|
||||
String playersOnline = Integer.toString(bukkitService.getOnlinePlayers().size());
|
||||
String ipAddress = Utils.getPlayerIp(player);
|
||||
return message
|
||||
.replace("&", "\u00a7")
|
||||
.replace("{PLAYER}", player.getName())
|
||||
@ -788,8 +799,8 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
public boolean isLoggedIp(String name, String ip) {
|
||||
int count = 0;
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(ipAddressManager.getPlayerIp(player))
|
||||
for (Player player : bukkitService.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(Utils.getPlayerIp(player))
|
||||
&& database.isLogged(player.getName().toLowerCase())
|
||||
&& !player.getName().equalsIgnoreCase(name)) {
|
||||
++count;
|
||||
|
||||
@ -3,10 +3,10 @@ package fr.xephi.authme;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.properties.PurgeSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@ -18,16 +18,15 @@ public class DataManager {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final BukkitService bukkitService;
|
||||
|
||||
/**
|
||||
* Constructor for DataManager.
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
* @param pluginHooks Plugin hooks instance
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public DataManager(AuthMe plugin, PluginHooks pluginHooks) {
|
||||
public DataManager(AuthMe plugin, PluginHooks pluginHooks, BukkitService bukkitService) {
|
||||
this.plugin = plugin;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
|
||||
private List<OfflinePlayer> getOfflinePlayers(List<String> names) {
|
||||
@ -64,6 +63,9 @@ public class DataManager {
|
||||
int i = 0;
|
||||
File dataFolder = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative"
|
||||
+ File.separator + "inventories");
|
||||
if (!dataFolder.exists() || !dataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
for (String file : dataFolder.list()) {
|
||||
String name = file;
|
||||
int idx;
|
||||
@ -123,6 +125,9 @@ public class DataManager {
|
||||
}
|
||||
|
||||
final File userDataFolder = new File(essentialsDataFolder, "userdata");
|
||||
if (!userDataFolder.exists() || !userDataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
|
||||
for (OfflinePlayer player : offlinePlayers) {
|
||||
File playerFile = new File(userDataFolder, Utils.getUUIDorName(player) + ".yml");
|
||||
@ -143,21 +148,9 @@ public class DataManager {
|
||||
ConsoleLogger.showError("Unable to access permissions manager instance!");
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
permsMan.removeAllGroups(getOnlinePlayerLower(name));
|
||||
i++;
|
||||
permsMan.removeAllGroups(bukkitService.getPlayerExact(name));
|
||||
}
|
||||
ConsoleLogger.info("AutoPurge: Removed permissions from " + i + " player(s).");
|
||||
}
|
||||
|
||||
private Player getOnlinePlayerLower(String name) {
|
||||
name = name.toLowerCase();
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
ConsoleLogger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s).");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
package fr.xephi.authme.cache;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Resources;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Stateful manager for looking up IP address appropriately, including caching.
|
||||
*/
|
||||
public class IpAddressManager {
|
||||
|
||||
/** Whether or not to use the VeryGames API for IP lookups. */
|
||||
private final boolean useVeryGamesIpCheck;
|
||||
/** Cache for lookups via the VeryGames API. */
|
||||
private final ConcurrentHashMap<String, String> ipCache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param settings The settings instance
|
||||
*/
|
||||
public IpAddressManager(NewSetting settings) {
|
||||
this.useVeryGamesIpCheck = settings.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK);
|
||||
this.ipCache = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the player's IP address. If enabled in the settings, the IP address returned by the
|
||||
* VeryGames API will be returned.
|
||||
*
|
||||
* @param player The player to look up
|
||||
* @return The IP address of the player
|
||||
*/
|
||||
public String getPlayerIp(Player player) {
|
||||
if (useVeryGamesIpCheck) {
|
||||
final String playerName = player.getName().toLowerCase();
|
||||
final String cachedValue = ipCache.get(playerName);
|
||||
if (cachedValue != null) {
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
final String plainIp = player.getAddress().getAddress().getHostAddress();
|
||||
String veryGamesResult = getVeryGamesIp(plainIp, player.getAddress().getPort());
|
||||
if (veryGamesResult != null) {
|
||||
ipCache.put(playerName, veryGamesResult);
|
||||
return veryGamesResult;
|
||||
}
|
||||
}
|
||||
return player.getAddress().getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a player to the IP address cache.
|
||||
*
|
||||
* @param player The player to add or update the cache entry for
|
||||
* @param ip The IP address to add
|
||||
*/
|
||||
public void addCache(String player, String ip) {
|
||||
if (useVeryGamesIpCheck) {
|
||||
ipCache.put(player.toLowerCase(), ip);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a player's cache entry.
|
||||
*
|
||||
* @param player The player to remove
|
||||
*/
|
||||
public void removeCache(String player) {
|
||||
if (useVeryGamesIpCheck) {
|
||||
ipCache.remove(player.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
// returns null if IP could not be looked up
|
||||
private String getVeryGamesIp(final String plainIp, final int port) {
|
||||
final String sUrl = String.format("http://monitor-1.verygames.net/api/?action=ipclean-real-ip"
|
||||
+ "&out=raw&ip=%s&port=%d", plainIp, port);
|
||||
|
||||
try {
|
||||
String result = Resources.toString(new URL(sUrl), Charsets.UTF_8);
|
||||
if (!StringUtils.isEmpty(result) && !result.contains("error")) {
|
||||
return result;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not fetch Very Games API with URL '" + sUrl + "':", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -10,8 +10,8 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
@ -24,7 +24,7 @@ public class JsonCache {
|
||||
private final File cacheDir;
|
||||
|
||||
public JsonCache() {
|
||||
cacheDir = Settings.CACHE_FOLDER;
|
||||
cacheDir = new File(AuthMe.getInstance().getDataFolder(), "cache");
|
||||
if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) {
|
||||
ConsoleLogger.showError("Failed to create cache directory.");
|
||||
}
|
||||
|
||||
@ -271,7 +271,7 @@ public final class CommandInitializer {
|
||||
CommandDescription.builder()
|
||||
.parent(AUTHME_BASE)
|
||||
.labels("converter", "convert", "conv")
|
||||
.description("Converter Command")
|
||||
.description("Converter command")
|
||||
.detailedDescription("Converter command for AuthMeReloaded.")
|
||||
.withArgument("job", "Conversion job: xauth / crazylogin / rakamak / " +
|
||||
"royalauth / vauth / sqlitetosql", false)
|
||||
|
||||
@ -5,7 +5,6 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
@ -15,8 +14,12 @@ import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -32,29 +35,19 @@ public class CommandService {
|
||||
private final PasswordSecurity passwordSecurity;
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final NewSetting settings;
|
||||
private final IpAddressManager ipAddressManager;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
private final AntiBot antiBot;
|
||||
private final ValidationService validationService;
|
||||
private final BukkitService bukkitService;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Constructor.
|
||||
*
|
||||
* @param authMe The plugin instance
|
||||
* @param commandMapper Command mapper
|
||||
* @param helpProvider Help provider
|
||||
* @param messages Messages instance
|
||||
* @param passwordSecurity The Password Security instance
|
||||
* @param permissionsManager The permissions manager
|
||||
* @param settings The settings manager
|
||||
* @param ipAddressManager The IP address manager
|
||||
* @param pluginHooks The plugin hooks instance
|
||||
* @param spawnLoader The spawn loader
|
||||
*/
|
||||
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages,
|
||||
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings,
|
||||
IpAddressManager ipAddressManager, PluginHooks pluginHooks, SpawnLoader spawnLoader,
|
||||
AntiBot antiBot) {
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
|
||||
ValidationService validationService, BukkitService bukkitService) {
|
||||
this.authMe = authMe;
|
||||
this.messages = messages;
|
||||
this.helpProvider = helpProvider;
|
||||
@ -62,10 +55,11 @@ public class CommandService {
|
||||
this.passwordSecurity = passwordSecurity;
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.settings = settings;
|
||||
this.ipAddressManager = ipAddressManager;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
this.antiBot = antiBot;
|
||||
this.validationService = validationService;
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,10 +193,6 @@ public class CommandService {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public IpAddressManager getIpAddressManager() {
|
||||
return ipAddressManager;
|
||||
}
|
||||
|
||||
public PlayerCache getPlayerCache() {
|
||||
return PlayerCache.getInstance();
|
||||
}
|
||||
@ -219,4 +209,35 @@ public class CommandService {
|
||||
return antiBot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether a password is valid according to the plugin settings.
|
||||
*
|
||||
* @param password the password to verify
|
||||
* @param username the username the password is associated with
|
||||
* @return message key with the password error, or {@code null} if password is valid
|
||||
*/
|
||||
public MessageKey validatePassword(String password, String username) {
|
||||
return validationService.validatePassword(password, username);
|
||||
}
|
||||
|
||||
public boolean validateEmail(String email) {
|
||||
return validationService.validateEmail(email);
|
||||
}
|
||||
|
||||
public boolean isEmailFreeForRegistration(String email, CommandSender sender) {
|
||||
return validationService.isEmailFreeForRegistration(email, sender);
|
||||
}
|
||||
|
||||
public Player getPlayer(String name) {
|
||||
return bukkitService.getPlayerExact(name);
|
||||
}
|
||||
|
||||
public Collection<? extends Player> getOnlinePlayers() {
|
||||
return bukkitService.getOnlinePlayers();
|
||||
}
|
||||
|
||||
public BukkitService getBukkitService() {
|
||||
return bukkitService;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,8 +7,6 @@ import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
@ -22,30 +20,16 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments,
|
||||
final CommandService commandService) {
|
||||
// Get the player and password
|
||||
String playerName = arguments.get(0);
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerPass = arguments.get(1);
|
||||
|
||||
// Validate the password
|
||||
String playerPassLowerCase = playerPass.toLowerCase();
|
||||
if (!playerPassLowerCase.matches(commandService.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX))) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
return;
|
||||
}
|
||||
if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
return;
|
||||
}
|
||||
if (playerPassLowerCase.length() < commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|
||||
|| playerPassLowerCase.length() > commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
|
||||
commandService.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
return;
|
||||
}
|
||||
// TODO #602 20160312: The UNSAFE_PASSWORDS should be all lowercase
|
||||
// -> introduce a lowercase String list property type
|
||||
if (commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(playerPassLowerCase)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
MessageKey passwordError = commandService.validatePassword(playerPass, playerName);
|
||||
if (passwordError != null) {
|
||||
commandService.send(sender, passwordError);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the password
|
||||
final String playerNameLowerCase = playerName.toLowerCase();
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
|
||||
@ -2,13 +2,13 @@ package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.permission.PlayerPermission.CAN_LOGIN_BE_FORCED;
|
||||
|
||||
/**
|
||||
* Forces the login of a player, i.e. logs the player in without the need of a (correct) password.
|
||||
*/
|
||||
@ -19,15 +19,14 @@ public class ForceLoginCommand implements ExecutableCommand {
|
||||
// Get the player query
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
Player player = Utils.getPlayer(playerName);
|
||||
Player player = commandService.getPlayer(playerName);
|
||||
if (player == null || !player.isOnline()) {
|
||||
sender.sendMessage("Player needs to be online!");
|
||||
} else if (!commandService.getPermissionsManager()
|
||||
.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)) {
|
||||
sender.sendMessage("You cannot force login for the player " + playerName + "!");
|
||||
} else if (!commandService.getPermissionsManager().hasPermission(player, CAN_LOGIN_BE_FORCED)) {
|
||||
sender.sendMessage("You cannot force login the player " + playerName + "!");
|
||||
} else {
|
||||
commandService.getManagement().performLogin(player, "dontneed", true);
|
||||
sender.sendMessage("Force Login for " + playerName + " performed!");
|
||||
sender.sendMessage("Force login for " + playerName + " performed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,6 @@ package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -14,9 +12,9 @@ public class GetIpCommand implements ExecutableCommand {
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// Get the player query
|
||||
String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
|
||||
String playerName = arguments.get(0);
|
||||
|
||||
Player player = Utils.getPlayer(playerName);
|
||||
Player player = commandService.getPlayer(playerName);
|
||||
if (player == null) {
|
||||
sender.sendMessage("The player is not online");
|
||||
return;
|
||||
@ -24,10 +22,5 @@ public class GetIpCommand implements ExecutableCommand {
|
||||
|
||||
sender.sendMessage(player.getName() + "'s IP is: " + player.getAddress().getAddress().getHostAddress()
|
||||
+ ":" + player.getAddress().getPort());
|
||||
|
||||
if (commandService.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK)) {
|
||||
sender.sendMessage(player.getName() + "'s real IP is: "
|
||||
+ commandService.getIpAddressManager().getPlayerIp(player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Admin command to register a user.
|
||||
@ -25,26 +24,14 @@ public class RegisterAdminCommand implements ExecutableCommand {
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerPass = arguments.get(1);
|
||||
final String playerNameLowerCase = playerName.toLowerCase();
|
||||
final String playerPassLowerCase = playerPass.toLowerCase();
|
||||
|
||||
// Command logic
|
||||
if (!playerPassLowerCase.matches(Settings.getPassRegex)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
return;
|
||||
}
|
||||
if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
return;
|
||||
}
|
||||
if (playerPassLowerCase.length() < commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|
||||
|| playerPassLowerCase.length() > commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
|
||||
commandService.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
return;
|
||||
}
|
||||
if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
MessageKey passwordError = commandService.validatePassword(playerPass, playerName);
|
||||
if (passwordError != null) {
|
||||
commandService.send(sender, passwordError);
|
||||
return;
|
||||
}
|
||||
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
|
||||
@Override
|
||||
@ -66,11 +53,18 @@ public class RegisterAdminCommand implements ExecutableCommand {
|
||||
return;
|
||||
}
|
||||
commandService.getDataSource().setUnlogged(playerNameLowerCase);
|
||||
if (Bukkit.getPlayerExact(playerName) != null) {
|
||||
Bukkit.getPlayerExact(playerName).kickPlayer("An admin just registered you, please log again");
|
||||
} else {
|
||||
commandService.send(sender, MessageKey.REGISTER_SUCCESS);
|
||||
ConsoleLogger.info(playerName + " registered");
|
||||
|
||||
commandService.send(sender, MessageKey.REGISTER_SUCCESS);
|
||||
ConsoleLogger.info(sender.getName() + " registered " + playerName);
|
||||
Player player = commandService.getPlayer(playerName);
|
||||
if (player != null) {
|
||||
final Player p = player;
|
||||
p.getServer().getScheduler().scheduleSyncDelayedTask(commandService.getAuthMe(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
p.kickPlayer("An admin just registered you, please log in again");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -4,12 +4,15 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Admin command for setting an email to an account.
|
||||
*/
|
||||
public class SetEmailCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
@ -20,7 +23,7 @@ public class SetEmailCommand implements ExecutableCommand {
|
||||
final String playerEmail = arguments.get(1);
|
||||
|
||||
// Validate the email address
|
||||
if (!Utils.isEmailCorrect(playerEmail, commandService.getSettings())) {
|
||||
if (!commandService.validateEmail(playerEmail)) {
|
||||
commandService.send(sender, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
@ -29,18 +32,19 @@ public class SetEmailCommand implements ExecutableCommand {
|
||||
@Override
|
||||
public void run() {
|
||||
// Validate the user
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
|
||||
DataSource dataSource = commandService.getDataSource();
|
||||
PlayerAuth auth = dataSource.getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
} else if (commandService.getDataSource().isEmailStored(playerEmail)) {
|
||||
} else if (!commandService.isEmailFreeForRegistration(playerEmail, sender)) {
|
||||
commandService.send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the email address
|
||||
auth.setEmail(playerEmail);
|
||||
if (!commandService.getDataSource().updateEmail(auth)) {
|
||||
if (!dataSource.updateEmail(auth)) {
|
||||
commandService.send(sender, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7,31 +7,29 @@ import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
|
||||
|
||||
/**
|
||||
* Admin command to unregister a player.
|
||||
*/
|
||||
public class UnregisterAdminCommand implements ExecutableCommand {
|
||||
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// AuthMe plugin instance
|
||||
final AuthMe plugin = AuthMe.getInstance();
|
||||
|
||||
// Get the player name
|
||||
String playerName = arguments.get(0);
|
||||
String playerNameLowerCase = playerName.toLowerCase();
|
||||
@ -49,32 +47,48 @@ public class UnregisterAdminCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
// Unregister the player
|
||||
Player target = Utils.getPlayer(playerNameLowerCase);
|
||||
Player target = commandService.getPlayer(playerNameLowerCase);
|
||||
PlayerCache.getInstance().removePlayer(playerNameLowerCase);
|
||||
Utils.setGroup(target, Utils.GroupType.UNREGISTERED);
|
||||
if (target != null && target.isOnline()) {
|
||||
Utils.teleportToSpawn(target);
|
||||
LimboCache.getInstance().addLimboPlayer(target);
|
||||
int timeOut = Settings.getRegistrationTimeout * 20;
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler scheduler = sender.getServer().getScheduler();
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, playerNameLowerCase, target), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTask(id);
|
||||
}
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTask(
|
||||
scheduler.runTask(
|
||||
plugin, new MessageTask(plugin, playerNameLowerCase, MessageKey.REGISTER_MESSAGE, interval)
|
||||
)
|
||||
);
|
||||
if (commandService.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
if (commandService.getProperty(RegistrationSettings.FORCE)) {
|
||||
applyUnregisteredEffectsAndTasks(target, commandService);
|
||||
}
|
||||
commandService.send(target, MessageKey.UNREGISTERED_SUCCESS);
|
||||
}
|
||||
|
||||
// Show a status message
|
||||
commandService.send(sender, MessageKey.UNREGISTERED_SUCCESS);
|
||||
ConsoleLogger.info(playerName + " unregistered");
|
||||
ConsoleLogger.info(sender.getName() + " unregistered " + playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* When registration is forced, applies the configured "unregistered effects" to the player as he
|
||||
* would encounter when joining the server before logging on - reminder task to log in,
|
||||
* timeout kick, blindness.
|
||||
*
|
||||
* @param target the player that was unregistered
|
||||
* @param service the command service
|
||||
*/
|
||||
private void applyUnregisteredEffectsAndTasks(Player target, CommandService service) {
|
||||
final AuthMe plugin = service.getAuthMe();
|
||||
final BukkitService bukkitService = service.getBukkitService();
|
||||
final String playerNameLowerCase = target.getName().toLowerCase();
|
||||
|
||||
Utils.teleportToSpawn(target);
|
||||
LimboCache.getInstance().addLimboPlayer(target);
|
||||
int timeOut = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = bukkitService.runTaskLater(new TimeoutTask(plugin, playerNameLowerCase, target), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTask(id);
|
||||
}
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTask(
|
||||
bukkitService.runTask(new MessageTask(service.getBukkitService(), plugin.getMessages(),
|
||||
playerNameLowerCase, MessageKey.REGISTER_MESSAGE, interval)));
|
||||
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,11 +3,11 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
@ -22,11 +22,12 @@ public class VersionCommand implements ExecutableCommand {
|
||||
sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName()
|
||||
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
|
||||
sender.sendMessage(ChatColor.GOLD + "Developers:");
|
||||
printDeveloper(sender, "Xephi", "xephi59", "Lead Developer");
|
||||
printDeveloper(sender, "DNx5", "DNx5", "Developer");
|
||||
printDeveloper(sender, "games647", "games647", "Developer");
|
||||
printDeveloper(sender, "Tim Visee", "timvisee", "Developer");
|
||||
printDeveloper(sender, "Sgdc3", "sgdc3", "Project manager, Contributor");
|
||||
Collection<? extends Player> onlinePlayers = commandService.getOnlinePlayers();
|
||||
printDeveloper(sender, "Xephi", "xephi59", "Lead Developer", onlinePlayers);
|
||||
printDeveloper(sender, "DNx5", "DNx5", "Developer", onlinePlayers);
|
||||
printDeveloper(sender, "games647", "games647", "Developer", onlinePlayers);
|
||||
printDeveloper(sender, "Tim Visee", "timvisee", "Developer", onlinePlayers);
|
||||
printDeveloper(sender, "Sgdc3", "sgdc3", "Project manager, Contributor", onlinePlayers);
|
||||
sender.sendMessage(ChatColor.GOLD + "Website: " + ChatColor.WHITE +
|
||||
"http://dev.bukkit.org/bukkit-plugins/authme-reloaded/");
|
||||
sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0"
|
||||
@ -38,12 +39,14 @@ public class VersionCommand implements ExecutableCommand {
|
||||
/**
|
||||
* Print a developer with proper styling.
|
||||
*
|
||||
* @param sender The command sender.
|
||||
* @param name The display name of the developer.
|
||||
* @param minecraftName The Minecraft username of the developer, if available.
|
||||
* @param function The function of the developer.
|
||||
* @param sender The command sender
|
||||
* @param name The display name of the developer
|
||||
* @param minecraftName The Minecraft username of the developer, if available
|
||||
* @param function The function of the developer
|
||||
* @param onlinePlayers The list of online players
|
||||
*/
|
||||
private static void printDeveloper(CommandSender sender, String name, String minecraftName, String function) {
|
||||
private static void printDeveloper(CommandSender sender, String name, String minecraftName, String function,
|
||||
Collection<? extends Player> onlinePlayers) {
|
||||
// Print the name
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append(" ")
|
||||
@ -55,7 +58,7 @@ public class VersionCommand implements ExecutableCommand {
|
||||
msg.append(ChatColor.GRAY).append(ChatColor.ITALIC).append(" (").append(function).append(")");
|
||||
|
||||
// Show the online status
|
||||
if (isPlayerOnline(minecraftName)) {
|
||||
if (isPlayerOnline(minecraftName, onlinePlayers)) {
|
||||
msg.append(ChatColor.GREEN).append(ChatColor.ITALIC).append(" (In-Game)");
|
||||
}
|
||||
|
||||
@ -66,12 +69,13 @@ public class VersionCommand implements ExecutableCommand {
|
||||
/**
|
||||
* Check whether a player is online.
|
||||
*
|
||||
* @param minecraftName The Minecraft player name.
|
||||
* @param minecraftName The Minecraft player name
|
||||
* @param onlinePlayers List of online players
|
||||
*
|
||||
* @return True if the player is online, false otherwise.
|
||||
* @return True if the player is online, false otherwise
|
||||
*/
|
||||
private static boolean isPlayerOnline(String minecraftName) {
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
private static boolean isPlayerOnline(String minecraftName, Collection<? extends Player> onlinePlayers) {
|
||||
for (Player player : onlinePlayers) {
|
||||
if (player.getName().equalsIgnoreCase(minecraftName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5,8 +5,6 @@ import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.ChangePasswordTask;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -30,22 +28,9 @@ public class ChangePasswordCommand extends PlayerCommand {
|
||||
}
|
||||
|
||||
// Make sure the password is allowed
|
||||
String playerPassLowerCase = newPassword.toLowerCase();
|
||||
if (!playerPassLowerCase.matches(commandService.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX))) {
|
||||
commandService.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
return;
|
||||
}
|
||||
if (playerPassLowerCase.equalsIgnoreCase(name)) {
|
||||
commandService.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
return;
|
||||
}
|
||||
if (playerPassLowerCase.length() < commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|
||||
|| playerPassLowerCase.length() > commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
|
||||
commandService.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
return;
|
||||
}
|
||||
if (commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(playerPassLowerCase)) {
|
||||
commandService.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
MessageKey passwordError = commandService.validatePassword(newPassword, name);
|
||||
if (passwordError != null) {
|
||||
commandService.send(player, passwordError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -3,11 +3,13 @@ package fr.xephi.authme.command.executable.email;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Command for setting an email to an account.
|
||||
*/
|
||||
public class AddEmailCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
@ -15,9 +17,8 @@ public class AddEmailCommand extends PlayerCommand {
|
||||
String email = arguments.get(0);
|
||||
String emailConfirmation = arguments.get(1);
|
||||
|
||||
if (!Utils.isEmailCorrect(email, commandService.getSettings())) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
} else if (email.equals(emailConfirmation)) {
|
||||
if (email.equals(emailConfirmation)) {
|
||||
// Closer inspection of the mail address handled by the async task
|
||||
commandService.getManagement().performAddEmail(player, email);
|
||||
} else {
|
||||
commandService.send(player, MessageKey.CONFIRM_EMAIL_MESSAGE);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package fr.xephi.authme.command.executable.email;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
@ -9,7 +10,7 @@ import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -19,13 +20,12 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
String playerMail = arguments.get(0);
|
||||
final String playerMail = arguments.get(0);
|
||||
final String playerName = player.getName();
|
||||
|
||||
// Command logic
|
||||
final AuthMe plugin = AuthMe.getInstance();
|
||||
final AuthMe plugin = commandService.getAuthMe();
|
||||
|
||||
if (plugin.mail == null) {
|
||||
ConsoleLogger.showError("Mail API is not set");
|
||||
commandService.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
@ -36,7 +36,7 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
String thePass = RandomString.generate(Settings.getRecoveryPassLength);
|
||||
String thePass = RandomString.generate(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH));
|
||||
HashedPassword hashNew = commandService.getPasswordSecurity().computeHash(thePass, playerName);
|
||||
PlayerAuth auth;
|
||||
if (PlayerCache.getInstance().isAuthenticated(playerName)) {
|
||||
@ -47,13 +47,14 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
commandService.send(player, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isEmpty(Settings.getmailAccount)) {
|
||||
if (StringUtils.isEmpty(commandService.getProperty(EmailSettings.MAIL_ACCOUNT))) {
|
||||
ConsoleLogger.showError("No mail account set in settings");
|
||||
commandService.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerMail.equalsIgnoreCase(auth.getEmail()) || playerMail.equalsIgnoreCase("your@email.com")
|
||||
|| auth.getEmail().equalsIgnoreCase("your@email.com")) {
|
||||
if (!playerMail.equalsIgnoreCase(auth.getEmail()) || "your@email.com".equalsIgnoreCase(playerMail)
|
||||
|| "your@email.com".equalsIgnoreCase(auth.getEmail())) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,19 +1,22 @@
|
||||
package fr.xephi.authme.command.executable.register;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.ENABLE_CONFIRM_EMAIL;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.USE_EMAIL_REGISTRATION;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ENABLE_PASSWORD_CONFIRMATION;
|
||||
|
||||
public class RegisterCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
@ -24,39 +27,62 @@ public class RegisterCommand extends PlayerCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.isEmpty() || Settings.enablePasswordConfirmation && arguments.size() < 2) {
|
||||
// Ensure that there is 1 argument, or 2 if confirmation is required
|
||||
final boolean useConfirmation = isConfirmationRequired(commandService);
|
||||
if (arguments.isEmpty() || useConfirmation && arguments.size() < 2) {
|
||||
commandService.send(player, MessageKey.USAGE_REGISTER);
|
||||
return;
|
||||
}
|
||||
|
||||
final Management management = commandService.getManagement();
|
||||
if (Settings.emailRegistration && !Settings.getmailAccount.isEmpty()) {
|
||||
if (Settings.doubleEmailCheck && arguments.size() < 2 || !arguments.get(0).equals(arguments.get(1))) {
|
||||
commandService.send(player, MessageKey.USAGE_REGISTER);
|
||||
return;
|
||||
}
|
||||
|
||||
final String email = arguments.get(0);
|
||||
if (!Utils.isEmailCorrect(email, commandService.getSettings())) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
final String thePass = RandomString.generate(Settings.getRecoveryPassLength);
|
||||
management.performRegister(player, thePass, email);
|
||||
return;
|
||||
if (commandService.getProperty(USE_EMAIL_REGISTRATION)) {
|
||||
handleEmailRegistration(player, arguments, commandService);
|
||||
} else {
|
||||
handlePasswordRegistration(player, arguments, commandService);
|
||||
}
|
||||
|
||||
if (arguments.size() > 1 && Settings.enablePasswordConfirmation && !arguments.get(0).equals(arguments.get(1))) {
|
||||
commandService.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
management.performRegister(player, arguments.get(0), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlternativeCommand() {
|
||||
protected String getAlternativeCommand() {
|
||||
return "/authme register <playername> <password>";
|
||||
}
|
||||
|
||||
private void handlePasswordRegistration(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION) && !arguments.get(0).equals(arguments.get(1))) {
|
||||
commandService.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
} else {
|
||||
commandService.getManagement().performRegister(player, arguments.get(0), "");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEmailRegistration(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (commandService.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
|
||||
player.sendMessage("Cannot register: no email address is set for the server. "
|
||||
+ "Please contact an administrator");
|
||||
ConsoleLogger.showError("Cannot register player '" + player.getName() + "': no email is set "
|
||||
+ "to send emails from. Please add one in your config at " + EmailSettings.MAIL_ACCOUNT.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
final String email = arguments.get(0);
|
||||
if (!commandService.validateEmail(email)) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
} else if (commandService.getProperty(ENABLE_CONFIRM_EMAIL) && !email.equals(arguments.get(1))) {
|
||||
commandService.send(player, MessageKey.USAGE_REGISTER);
|
||||
} else {
|
||||
String thePass = RandomString.generate(commandService.getProperty(RECOVERY_PASSWORD_LENGTH));
|
||||
commandService.getManagement().performRegister(player, thePass, email);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the password or email has to be confirmed.
|
||||
*
|
||||
* @param commandService The command service
|
||||
* @return True if the confirmation is needed, false otherwise
|
||||
*/
|
||||
private boolean isConfirmationRequired(CommandService commandService) {
|
||||
return commandService.getProperty(USE_EMAIL_REGISTRATION)
|
||||
? commandService.getProperty(ENABLE_CONFIRM_EMAIL)
|
||||
: commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
@ -25,22 +24,23 @@ public class RakamakConverter implements Converter {
|
||||
private final AuthMe instance;
|
||||
private final DataSource database;
|
||||
private final CommandSender sender;
|
||||
private final File pluginFolder;
|
||||
|
||||
public RakamakConverter(AuthMe instance, CommandSender sender) {
|
||||
this.instance = instance;
|
||||
this.database = instance.getDataSource();
|
||||
this.sender = sender;
|
||||
pluginFolder = instance.getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO ljacqu 20151229: Restructure this into smaller portions
|
||||
public void run() {
|
||||
HashAlgorithm hash = Settings.getPasswordHash;
|
||||
boolean useIP = Settings.rakamakUseIp;
|
||||
String fileName = Settings.rakamakUsers;
|
||||
String ipFileName = Settings.rakamakUsersIp;
|
||||
File source = new File(Settings.PLUGIN_FOLDER, fileName);
|
||||
File ipfiles = new File(Settings.PLUGIN_FOLDER, ipFileName);
|
||||
File source = new File(pluginFolder, fileName);
|
||||
File ipfiles = new File(pluginFolder, ipFileName);
|
||||
HashMap<String, String> playerIP = new HashMap<>();
|
||||
HashMap<String, HashedPassword> playerPSW = new HashMap<>();
|
||||
try {
|
||||
@ -64,7 +64,7 @@ public class RakamakConverter implements Converter {
|
||||
while ((line = users.readLine()) != null) {
|
||||
if (line.contains("=")) {
|
||||
String[] arguments = line.split("=");
|
||||
HashedPassword hashedPassword = passwordSecurity.computeHash(hash, arguments[1], arguments[0]);
|
||||
HashedPassword hashedPassword = passwordSecurity.computeHash(arguments[1], arguments[0]);
|
||||
playerPSW.put(arguments[0], hashedPassword);
|
||||
|
||||
}
|
||||
|
||||
@ -250,9 +250,4 @@ public class CacheDataSource implements DataSource {
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
return new ArrayList<>(PlayerCache.getInstance().getCache().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmailStored(String email) {
|
||||
return source.isEmailStored(email);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,70 +122,84 @@ public interface DataSource {
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Method purgeBanned.
|
||||
* Purge all given players, i.e. delete all players whose name is in the list.
|
||||
*
|
||||
* @param banned List of String
|
||||
* @param banned the list of players to delete
|
||||
*/
|
||||
void purgeBanned(List<String> banned);
|
||||
|
||||
/**
|
||||
* Method getType.
|
||||
* Return the data source type.
|
||||
*
|
||||
* @return DataSourceType
|
||||
* @return the data source type
|
||||
*/
|
||||
DataSourceType getType();
|
||||
|
||||
/**
|
||||
* Method isLogged.
|
||||
* Query the datasource whether the player is logged in or not.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @return boolean
|
||||
* @param user The name of the player to verify
|
||||
* @return True if logged in, false otherwise
|
||||
*/
|
||||
boolean isLogged(String user);
|
||||
|
||||
/**
|
||||
* Method setLogged.
|
||||
* Set a player as logged in.
|
||||
*
|
||||
* @param user String
|
||||
* @param user The name of the player to change
|
||||
*/
|
||||
void setLogged(String user);
|
||||
|
||||
/**
|
||||
* Method setUnlogged.
|
||||
* Set a player as unlogged (not logged in).
|
||||
*
|
||||
* @param user String
|
||||
* @param user The name of the player to change
|
||||
*/
|
||||
void setUnlogged(String user);
|
||||
|
||||
/**
|
||||
* Set all players who are marked as logged in as NOT logged in.
|
||||
*/
|
||||
void purgeLogged();
|
||||
|
||||
/**
|
||||
* Method getAccountsRegistered.
|
||||
* Return all players which are logged in.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int getAccountsRegistered();
|
||||
|
||||
boolean updateRealName(String user, String realName);
|
||||
|
||||
boolean updateIp(String user, String ip);
|
||||
|
||||
/**
|
||||
* Method getAllAuths.
|
||||
*
|
||||
* @return List of PlayerAuth
|
||||
*/
|
||||
List<PlayerAuth> getAllAuths();
|
||||
|
||||
/**
|
||||
* Method getLoggedPlayers.
|
||||
*
|
||||
* @return List of PlayerAuth
|
||||
* @return All logged in players
|
||||
*/
|
||||
List<PlayerAuth> getLoggedPlayers();
|
||||
|
||||
boolean isEmailStored(String email);
|
||||
/**
|
||||
* Return the number of registered accounts.
|
||||
*
|
||||
* @return Total number of accounts
|
||||
*/
|
||||
int getAccountsRegistered();
|
||||
|
||||
/**
|
||||
* Update a player's real name (capitalization).
|
||||
*
|
||||
* @param user The name of the user (lowercase)
|
||||
* @param realName The real name of the user (proper casing)
|
||||
* @return True upon success, false upon failure
|
||||
*/
|
||||
boolean updateRealName(String user, String realName);
|
||||
|
||||
/**
|
||||
* Update a player's IP address.
|
||||
*
|
||||
* @param user The name of the user (lowercase)
|
||||
* @param ip The IP address to save
|
||||
* @return True upon success, false upon failure
|
||||
*/
|
||||
boolean updateIp(String user, String ip);
|
||||
|
||||
/**
|
||||
* Return all players of the database.
|
||||
*
|
||||
* @return List of all players
|
||||
*/
|
||||
List<PlayerAuth> getAllAuths();
|
||||
|
||||
/**
|
||||
* Reload the data source.
|
||||
|
||||
@ -521,11 +521,6 @@ public class FlatFile implements DataSource {
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmailStored(String email) {
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
private static PlayerAuth buildAuthFromArray(String[] args) {
|
||||
// Format allows 2, 3, 4, 7, 8, 9 fields. Anything else is unknown
|
||||
if (args.length >= 2 && args.length <= 9 && args.length != 5 && args.length != 6) {
|
||||
|
||||
@ -274,20 +274,20 @@ public class MySQL implements DataSource {
|
||||
|
||||
@Override
|
||||
public HashedPassword getPassword(String user) {
|
||||
String sql = "SELECT " + col.PASSWORD + "," + col.SALT + " FROM " + tableName
|
||||
+ " WHERE " + col.NAME + "=?;";
|
||||
ResultSet rs = null;
|
||||
boolean useSalt = !col.SALT.isEmpty();
|
||||
String sql = "SELECT " + col.PASSWORD
|
||||
+ (useSalt ? ", " + col.SALT : "")
|
||||
+ " FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, user.toLowerCase());
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
return new HashedPassword(rs.getString(col.PASSWORD),
|
||||
!col.SALT.isEmpty() ? rs.getString(col.SALT) : null);
|
||||
try (ResultSet rs = pst.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return new HashedPassword(rs.getString(col.PASSWORD),
|
||||
useSalt ? rs.getString(col.SALT) : null);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(rs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -429,7 +429,7 @@ public class MySQL implements DataSource {
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
sql = "INSERT INTO " + wordpressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);";
|
||||
sql = "INSERT INTO " + wordpressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?)";
|
||||
pst2 = con.prepareStatement(sql);
|
||||
// First Name
|
||||
pst2.setInt(1, id);
|
||||
@ -478,12 +478,12 @@ public class MySQL implements DataSource {
|
||||
pst2.addBatch();
|
||||
// wp_capabilities
|
||||
pst2.setInt(1, id);
|
||||
pst2.setString(2, "wp_capabilities");
|
||||
pst2.setString(2, wordpressPrefix + "capabilities");
|
||||
pst2.setString(3, "a:1:{s:10:\"subscriber\";b:1;}");
|
||||
pst2.addBatch();
|
||||
// wp_user_level
|
||||
pst2.setInt(1, id);
|
||||
pst2.setString(2, "wp_user_level");
|
||||
pst2.setString(2, wordpressPrefix + "user_level");
|
||||
pst2.setString(3, "0");
|
||||
pst2.addBatch();
|
||||
// default_password_nag
|
||||
@ -908,20 +908,6 @@ public class MySQL implements DataSource {
|
||||
return auths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmailStored(String email) {
|
||||
String sql = "SELECT 1 FROM " + tableName + " WHERE UPPER(" + col.EMAIL + ") = UPPER(?)";
|
||||
try (Connection con = ds.getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, email);
|
||||
try (ResultSet rs = pst.executeQuery()) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logSqlException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException {
|
||||
String salt = col.SALT.isEmpty() ? null : row.getString(col.SALT);
|
||||
int group = col.GROUP.isEmpty() ? -1 : row.getInt(col.GROUP);
|
||||
|
||||
@ -154,22 +154,20 @@ public class SQLite implements DataSource {
|
||||
|
||||
@Override
|
||||
public HashedPassword getPassword(String user) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT " + col.PASSWORD + "," + col.SALT
|
||||
+ " FROM " + tableName + " WHERE " + col.NAME + "=?");
|
||||
boolean useSalt = !col.SALT.isEmpty();
|
||||
String sql = "SELECT " + col.PASSWORD
|
||||
+ (useSalt ? ", " + col.SALT : "")
|
||||
+ " FROM " + tableName + " WHERE " + col.NAME + "=?";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
return new HashedPassword(rs.getString(col.PASSWORD),
|
||||
!col.SALT.isEmpty() ? rs.getString(col.SALT) : null);
|
||||
try (ResultSet rs = pst.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return new HashedPassword(rs.getString(col.PASSWORD),
|
||||
useSalt ? rs.getString(col.SALT) : null);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -580,22 +578,6 @@ public class SQLite implements DataSource {
|
||||
return auths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmailStored(String email) {
|
||||
String sql = "SELECT 1 FROM " + tableName + " WHERE " + col.EMAIL + " = ? COLLATE NOCASE;";
|
||||
ResultSet rs = null;
|
||||
try (PreparedStatement ps = con.prepareStatement(sql)) {
|
||||
ps.setString(1, email);
|
||||
rs = ps.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
logSqlException(e);
|
||||
} finally {
|
||||
close(rs);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException {
|
||||
String salt = !col.SALT.isEmpty() ? row.getString(col.SALT) : null;
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
@ -17,17 +16,14 @@ import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
public class BungeeCordMessage implements PluginMessageListener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final IpAddressManager ipAddressManager;
|
||||
|
||||
/**
|
||||
* Constructor for BungeeCordMessage.
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
* @param ipAddressManager The IP address manager
|
||||
*/
|
||||
public BungeeCordMessage(AuthMe plugin, IpAddressManager ipAddressManager) {
|
||||
public BungeeCordMessage(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.ipAddressManager = ipAddressManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,11 +33,6 @@ public class BungeeCordMessage implements PluginMessageListener {
|
||||
}
|
||||
ByteArrayDataInput in = ByteStreams.newDataInput(message);
|
||||
String subChannel = in.readUTF();
|
||||
if ("IP".equals(subChannel)) { // We need only the IP channel
|
||||
String ip = in.readUTF();
|
||||
// Put the IP (only the ip not the port) in the hashMap
|
||||
ipAddressManager.addCache(player.getName(), ip);
|
||||
}
|
||||
if ("AuthMe".equalsIgnoreCase(subChannel)) {
|
||||
String str = in.readUTF();
|
||||
final String[] args = str.split(";");
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
package fr.xephi.authme.hooks;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import net.minelink.ctplus.CombatTagPlus;
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.io.File;
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import net.minelink.ctplus.CombatTagPlus;
|
||||
|
||||
/**
|
||||
* Hooks into third-party plugins and allows to perform actions on them.
|
||||
|
||||
@ -33,7 +33,7 @@ public class AuthMeEntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO #360: npc status can be used to bypass security!!!
|
||||
// Note #360: npc status can be used to bypass security!!!
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
|
||||
@ -22,7 +22,6 @@ 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.reflect.MethodUtils;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
@ -38,6 +37,8 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import org.apache.commons.lang.reflect.MethodUtils;
|
||||
|
||||
public class AuthMeInventoryPacketAdapter extends PacketAdapter {
|
||||
|
||||
private static final int PLAYER_INVENTORY = 0;
|
||||
@ -127,9 +128,11 @@ public class AuthMeInventoryPacketAdapter extends PacketAdapter {
|
||||
PacketContainer inventoryPacket = protocolManager.createPacket(PacketType.Play.Server.WINDOW_ITEMS);
|
||||
inventoryPacket.getIntegers().write(0, PLAYER_INVENTORY);
|
||||
int inventorySize = CRAFTING_SIZE + ARMOR_SIZE + MAIN_SIZE + HOTBAR_SIZE;
|
||||
|
||||
ItemStack[] blankInventory = new ItemStack[inventorySize];
|
||||
Arrays.fill(blankInventory, new ItemStack(Material.AIR));
|
||||
inventoryPacket.getItemArrayModifier().write(0, blankInventory);
|
||||
|
||||
try {
|
||||
protocolManager.sendServerPacket(player, inventoryPacket, false);
|
||||
} catch (InvocationTargetException invocationExc) {
|
||||
|
||||
@ -3,6 +3,7 @@ package fr.xephi.authme.listener;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import fr.xephi.authme.AntiBot;
|
||||
import fr.xephi.authme.AntiBot.AntiBotStatus;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
@ -15,9 +16,15 @@ import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -50,56 +57,65 @@ import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_MOVEMENT_RADIUS;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_ALL_COMMANDS_IF_REGISTRATION_IS_OPTIONAL;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT;
|
||||
|
||||
/**
|
||||
* Listener class for player's events
|
||||
* Listener class for player events.
|
||||
*/
|
||||
public class AuthMePlayerListener implements Listener {
|
||||
|
||||
public static final ConcurrentHashMap<String, String> joinMessage = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentHashMap<String, Boolean> causeByAuthMe = new ConcurrentHashMap<>();
|
||||
private final AuthMe plugin;
|
||||
private final NewSetting settings;
|
||||
private final Messages m;
|
||||
private final DataSource dataSource;
|
||||
private final AntiBot antiBot;
|
||||
private final Management management;
|
||||
private final BukkitService bukkitService;
|
||||
private final ValidationService validationService;
|
||||
|
||||
public AuthMePlayerListener(AuthMe plugin, Messages messages, DataSource dataSource, AntiBot antiBot,
|
||||
Management management) {
|
||||
public AuthMePlayerListener(AuthMe plugin, NewSetting settings, Messages messages, DataSource dataSource,
|
||||
AntiBot antiBot, Management management, BukkitService bukkitService,
|
||||
ValidationService validationService) {
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
this.m = messages;
|
||||
this.dataSource = dataSource;
|
||||
this.antiBot = antiBot;
|
||||
this.management = management;
|
||||
this.bukkitService = bukkitService;
|
||||
this.validationService = validationService;
|
||||
}
|
||||
|
||||
private void handleChat(AsyncPlayerChatEvent event) {
|
||||
if (Settings.isChatAllowed) {
|
||||
if (settings.getProperty(RestrictionSettings.ALLOW_CHAT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
if (Utils.checkAuth(player)) {
|
||||
for (Player p : Utils.getOnlinePlayers()) {
|
||||
if (shouldCancelEvent(player)) {
|
||||
event.setCancelled(true);
|
||||
sendLoginOrRegisterMessage(player);
|
||||
} else if (settings.getProperty(RestrictionSettings.HIDE_CHAT)) {
|
||||
for (Player p : bukkitService.getOnlinePlayers()) {
|
||||
if (!PlayerCache.getInstance().isAuthenticated(p.getName())) {
|
||||
event.getRecipients().remove(p); // TODO: it should be configurable
|
||||
event.getRecipients().remove(p);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
sendLoginOrRegisterMessage(player);
|
||||
}
|
||||
|
||||
private void sendLoginOrRegisterMessage(final Player player) {
|
||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (dataSource.isAuthAvailable(player.getName().toLowerCase())) {
|
||||
m.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else {
|
||||
if (Settings.emailRegistration) {
|
||||
if (settings.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)) {
|
||||
m.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
} else {
|
||||
m.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
@ -112,13 +128,14 @@ public class AuthMePlayerListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
String cmd = event.getMessage().split(" ")[0].toLowerCase();
|
||||
if (Settings.useEssentialsMotd && cmd.equals("/motd")) {
|
||||
if (settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD) && "/motd".equals(cmd)) {
|
||||
return;
|
||||
}
|
||||
if (!Settings.isForcedRegistrationEnabled && Settings.allowAllCommandsIfRegIsOptional) {
|
||||
if (!settings.getProperty(RegistrationSettings.FORCE)
|
||||
&& settings.getProperty(ALLOW_ALL_COMMANDS_IF_REGISTRATION_IS_OPTIONAL)) {
|
||||
return;
|
||||
}
|
||||
if (Settings.allowCommands.contains(cmd)) {
|
||||
if (settings.getProperty(RestrictionSettings.ALLOW_COMMANDS).contains(cmd)) {
|
||||
return;
|
||||
}
|
||||
if (Utils.checkAuth(event.getPlayer())) {
|
||||
@ -155,13 +172,17 @@ public class AuthMePlayerListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (Settings.isMovementAllowed && Settings.getMovementRadius <= 0) {
|
||||
if (settings.getProperty(ALLOW_UNAUTHED_MOVEMENT) && settings.getProperty(ALLOWED_MOVEMENT_RADIUS) <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Limit player X and Z movements to 1 block
|
||||
* Deny player Y+ movements (allows falling)
|
||||
*/
|
||||
if (event.getFrom().getBlockX() == event.getTo().getBlockX()
|
||||
&& event.getFrom().getBlockY() == event.getTo().getBlockY()
|
||||
&& event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
|
||||
&& event.getFrom().getBlockZ() == event.getTo().getBlockZ()
|
||||
&& event.getFrom().getY() - event.getTo().getY() >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -170,16 +191,17 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Settings.isMovementAllowed) {
|
||||
if (!settings.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)) {
|
||||
event.setTo(event.getFrom());
|
||||
if (Settings.isRemoveSpeedEnabled) {
|
||||
// sgdc3 TODO: remove this, maybe we should set the effect every x ticks, idk!
|
||||
if (settings.getProperty(RestrictionSettings.REMOVE_SPEED)) {
|
||||
player.setFlySpeed(0.0f);
|
||||
player.setWalkSpeed(0.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.noTeleport) {
|
||||
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -189,7 +211,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
player.teleport(spawn);
|
||||
return;
|
||||
}
|
||||
if (spawn.distance(player.getLocation()) > Settings.getMovementRadius) {
|
||||
if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) {
|
||||
player.teleport(spawn);
|
||||
}
|
||||
}
|
||||
@ -202,11 +224,11 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.removeJoinMessage) {
|
||||
if (settings.getProperty(RegistrationSettings.REMOVE_JOIN_MESSAGE)) {
|
||||
event.setJoinMessage(null);
|
||||
return;
|
||||
}
|
||||
if (!Settings.delayJoinMessage) {
|
||||
if (!settings.getProperty(RegistrationSettings.DELAY_JOIN_MESSAGE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -214,11 +236,10 @@ public class AuthMePlayerListener implements Listener {
|
||||
String joinMsg = event.getJoinMessage();
|
||||
|
||||
// Remove the join message while the player isn't logging in
|
||||
if (joinMsg == null) {
|
||||
return;
|
||||
if (joinMsg != null) {
|
||||
event.setJoinMessage(null);
|
||||
joinMessage.put(name, joinMsg);
|
||||
}
|
||||
event.setJoinMessage(null);
|
||||
joinMessage.put(name, joinMsg);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
@ -228,14 +249,14 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.isForceSurvivalModeEnabled
|
||||
if (settings.getProperty(RestrictionSettings.FORCE_SURVIVAL_MODE)
|
||||
&& !player.hasPermission(PlayerStatePermission.BYPASS_FORCE_SURVIVAL.getNode())) {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
}
|
||||
|
||||
// Shedule login task so works after the prelogin
|
||||
// (Fix found by Koolaid5000)
|
||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
||||
bukkitService.runTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
management.performJoin(player);
|
||||
@ -246,40 +267,32 @@ public class AuthMePlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
||||
PlayerAuth auth = dataSource.getAuth(event.getName());
|
||||
if (Settings.preventOtherCase && auth != null && auth.getRealName() != null) {
|
||||
if (settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE) && auth != null && auth.getRealName() != null) {
|
||||
String realName = auth.getRealName();
|
||||
if (!realName.isEmpty() && !realName.equals("Player") && !realName.equals(event.getName())) {
|
||||
if (!realName.isEmpty() && !"Player".equals(realName) && !realName.equals(event.getName())) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.INVALID_NAME_CASE, realName, event.getName()));
|
||||
return;
|
||||
}
|
||||
if (realName.isEmpty() || realName.equals("Player")) {
|
||||
if (realName.isEmpty() || "Player".equals(realName)) {
|
||||
dataSource.updateRealName(event.getName().toLowerCase(), event.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (auth == null) {
|
||||
if (!Settings.countriesBlacklist.isEmpty() || !Settings.countries.isEmpty()) {
|
||||
String playerIP = event.getAddress().getHostAddress();
|
||||
String countryCode = GeoLiteAPI.getCountryCode(playerIP);
|
||||
if (Settings.countriesBlacklist.contains(countryCode)) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
return;
|
||||
}
|
||||
if (Settings.enableProtection && !Settings.countries.contains(countryCode)) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
return;
|
||||
}
|
||||
if (auth == null && settings.getProperty(ProtectionSettings.ENABLE_PROTECTION)) {
|
||||
String playerIp = event.getAddress().getHostAddress();
|
||||
if (!validationService.isCountryAdmitted(playerIp)) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final String name = event.getName().toLowerCase();
|
||||
final Player player = Utils.getPlayer(name);
|
||||
final Player player = bukkitService.getPlayerExact(name);
|
||||
// Check if forceSingleSession is set to true, so kick player that has
|
||||
// joined with same nick of online player
|
||||
if (player != null && Settings.isForceSingleSessionEnabled) {
|
||||
if (player != null && settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR));
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
@ -302,11 +315,11 @@ public class AuthMePlayerListener implements Listener {
|
||||
|
||||
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL) {
|
||||
if (permsMan.hasPermission(player, PlayerStatePermission.IS_VIP)) {
|
||||
int playersOnline = Utils.getOnlinePlayers().size();
|
||||
int playersOnline = bukkitService.getOnlinePlayers().size();
|
||||
if (playersOnline > plugin.getServer().getMaxPlayers()) {
|
||||
event.allow();
|
||||
} else {
|
||||
Player pl = plugin.generateKickPlayer(Utils.getOnlinePlayers());
|
||||
Player pl = plugin.generateKickPlayer(bukkitService.getOnlinePlayers());
|
||||
if (pl != null) {
|
||||
pl.kickPlayer(m.retrieveSingle(MessageKey.KICK_FOR_VIP));
|
||||
event.allow();
|
||||
@ -330,16 +343,16 @@ public class AuthMePlayerListener implements Listener {
|
||||
final String name = player.getName().toLowerCase();
|
||||
boolean isAuthAvailable = dataSource.isAuthAvailable(name);
|
||||
|
||||
if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) {
|
||||
if (Settings.antiBotInAction) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
} else {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.MUST_REGISTER_MESSAGE));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
if (antiBot.getAntiBotStatus() == AntiBotStatus.ACTIVE && !isAuthAvailable) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED) && !isAuthAvailable) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.MUST_REGISTER_MESSAGE));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.length() > Settings.getMaxNickLength || name.length() < Settings.getMinNickLength) {
|
||||
@ -356,7 +369,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
|
||||
antiBot.checkAntiBot(player);
|
||||
|
||||
if (Settings.bungee) {
|
||||
if (settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("IP");
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
@ -371,7 +384,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.removeLeaveMessage) {
|
||||
if (settings.getProperty(RegistrationSettings.REMOVE_LEAVE_MESSAGE)) {
|
||||
event.setQuitMessage(null);
|
||||
}
|
||||
|
||||
@ -386,8 +399,8 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!Settings.isForceSingleSessionEnabled)
|
||||
&& (event.getReason().equals(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR)))) {
|
||||
if (!settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)
|
||||
&& event.getReason().equals(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.spigotmc.event.player.PlayerSpawnLocationEvent;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
/**
|
||||
* Listener of player events for events introduced in Minecraft 1.9.
|
||||
*/
|
||||
public class AuthMePlayerListener19 implements Listener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
|
||||
public AuthMePlayerListener19(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerSpawn(PlayerSpawnLocationEvent event) {
|
||||
event.setSpawnLocation(plugin.getSpawnLocation(event.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,9 +5,10 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -21,25 +22,26 @@ public class AuthMeServerListener implements Listener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final Messages messages;
|
||||
private final NewSetting settings;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
private final ValidationService validationService;
|
||||
|
||||
public AuthMeServerListener(AuthMe plugin, Messages messages, PluginHooks pluginHooks, SpawnLoader spawnLoader) {
|
||||
public AuthMeServerListener(AuthMe plugin, Messages messages, NewSetting settings, PluginHooks pluginHooks,
|
||||
SpawnLoader spawnLoader, ValidationService validationService) {
|
||||
this.plugin = plugin;
|
||||
this.messages = messages;
|
||||
this.settings = settings;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
this.validationService = validationService;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onServerPing(ServerListPingEvent event) {
|
||||
if (!Settings.countriesBlacklist.isEmpty() || !Settings.countries.isEmpty()){
|
||||
String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
|
||||
if( Settings.countriesBlacklist.contains(countryCode)) {
|
||||
event.setMotd(messages.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
return;
|
||||
}
|
||||
if (Settings.enableProtection && !Settings.countries.contains(countryCode)) {
|
||||
if (settings.getProperty(ProtectionSettings.ENABLE_PROTECTION)) {
|
||||
String playerIp = event.getAddress().getHostAddress();
|
||||
if (!validationService.isCountryAdmitted(playerIp)) {
|
||||
event.setMotd(messages.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
}
|
||||
}
|
||||
@ -52,6 +54,9 @@ public class AuthMeServerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call the onPluginDisable method in the permissions manager
|
||||
plugin.getPermissionsManager().onPluginDisable(event);
|
||||
|
||||
final String pluginName = event.getPlugin().getName();
|
||||
if ("Essentials".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.unhookEssentials();
|
||||
@ -82,6 +87,9 @@ public class AuthMeServerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call the onPluginEnable method in the permissions manager
|
||||
plugin.getPermissionsManager().onPluginEnable(event);
|
||||
|
||||
final String pluginName = event.getPlugin().getName();
|
||||
if ("Essentials".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.tryHookToEssentials();
|
||||
|
||||
@ -6,6 +6,7 @@ import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
|
||||
@ -2,40 +2,96 @@ package fr.xephi.authme.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class AuthMeTablistPacketAdapter extends PacketAdapter {
|
||||
|
||||
public AuthMeTablistPacketAdapter(AuthMe plugin) {
|
||||
private final BukkitService bukkitService;
|
||||
|
||||
public AuthMeTablistPacketAdapter(AuthMe plugin, BukkitService bukkitService) {
|
||||
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO);
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.PLAYER_INFO) {
|
||||
//this hides the tablist for the new joining players. Already playing users will see the new player
|
||||
try {
|
||||
if (!PlayerCache.getInstance().isAuthenticated(event.getPlayer().getName().toLowerCase())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} catch (FieldAccessException e) {
|
||||
ConsoleLogger.showError("Couldn't access field.");
|
||||
ConsoleLogger.logException("Couldn't access field", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix this in 1.9
|
||||
public void sendTablist(Player receiver) {
|
||||
WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(receiver);
|
||||
|
||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
NativeGameMode gamemode = NativeGameMode.fromBukkit(receiver.getGameMode());
|
||||
|
||||
WrappedChatComponent displayName = WrappedChatComponent.fromText(receiver.getDisplayName());
|
||||
PlayerInfoData playerInfoData = new PlayerInfoData(gameProfile, 0, gamemode, displayName);
|
||||
|
||||
//add info containing the skin data
|
||||
PacketContainer addInfo = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO);
|
||||
addInfo.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
|
||||
addInfo.getPlayerInfoDataLists().write(0, Arrays.asList(playerInfoData));
|
||||
|
||||
try {
|
||||
//adds the skin
|
||||
protocolManager.sendServerPacket(receiver, addInfo);
|
||||
} catch (InvocationTargetException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Exception sending instant skin change packet", ex);
|
||||
}
|
||||
|
||||
//triggers an update for others player to see them
|
||||
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
|
||||
if (onlinePlayer.equals(receiver) || !receiver.canSee(onlinePlayer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//removes the entity and display them
|
||||
receiver.hidePlayer(onlinePlayer);
|
||||
receiver.showPlayer(onlinePlayer);
|
||||
}
|
||||
}
|
||||
|
||||
public void register() {
|
||||
ConsoleLogger.showError("The hideTablistBeforeLogin feature is temporarily disabled due to issues with 1.9 clients.");
|
||||
//ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||
if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.BOUNTIFUL_UPDATE)) {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||
} else {
|
||||
ConsoleLogger.info("The hideTablist feature is not compatible with your minecraft version");
|
||||
ConsoleLogger.info("It requires 1.8+. Disabling the hideTablist feature...");
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
//ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
||||
ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
package fr.xephi.authme.modules;
|
||||
|
||||
/**
|
||||
*/
|
||||
public abstract class Module {
|
||||
|
||||
/**
|
||||
* Method getName.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Method getType.
|
||||
*
|
||||
* @return ModuleType
|
||||
*/
|
||||
public abstract ModuleType getType();
|
||||
|
||||
public void load() {
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
enum ModuleType {
|
||||
MANAGER,
|
||||
MYSQL,
|
||||
REDIS,
|
||||
ACTIONS,
|
||||
CONVERTERS,
|
||||
EMAILS,
|
||||
CUSTOM
|
||||
}
|
||||
}
|
||||
@ -1,184 +0,0 @@
|
||||
package fr.xephi.authme.modules;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ModuleManager {
|
||||
|
||||
private final List<Module> modules = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor for ModuleManager.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
*/
|
||||
public ModuleManager(AuthMe plugin) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isModuleEnabled.
|
||||
*
|
||||
* @param name String
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isModuleEnabled(String name) {
|
||||
for (Module m : modules) {
|
||||
if (m.getName().equalsIgnoreCase(name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isModuleEnabled.
|
||||
*
|
||||
* @param type Module.ModuleType
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isModuleEnabled(Module.ModuleType type) {
|
||||
for (Module m : modules) {
|
||||
if (m.getType() == type)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getModule.
|
||||
*
|
||||
* @param name String
|
||||
*
|
||||
* @return Module
|
||||
*/
|
||||
public Module getModule(String name) {
|
||||
for (Module m : modules) {
|
||||
if (m.getName().equalsIgnoreCase(name))
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getModule.
|
||||
*
|
||||
* @param type Module.ModuleType
|
||||
*
|
||||
* @return Module
|
||||
*/
|
||||
public Module getModule(Module.ModuleType type) {
|
||||
for (Module m : modules) {
|
||||
if (m.getType() == type)
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method loadModules.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int loadModules() {
|
||||
File dir = Settings.MODULE_FOLDER;
|
||||
int count = 0;
|
||||
if (!dir.isDirectory()) {
|
||||
dir.mkdirs();
|
||||
return count;
|
||||
}
|
||||
|
||||
File[] files = dir.listFiles();
|
||||
if (files == null) {
|
||||
return count;
|
||||
}
|
||||
for (File pathToJar : files) {
|
||||
JarFile jarFile = null;
|
||||
URLClassLoader cl = null;
|
||||
try {
|
||||
jarFile = new JarFile(pathToJar);
|
||||
URL[] urls = {new URL("jar:file:" + pathToJar.getAbsolutePath() + "!/")};
|
||||
cl = URLClassLoader.newInstance(urls);
|
||||
|
||||
Enumeration<?> e = jarFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
JarEntry je = (JarEntry) e.nextElement();
|
||||
if (je.isDirectory() || !je.getName().endsWith("Main.class")) {
|
||||
continue;
|
||||
}
|
||||
String className = je.getName().substring(0, je.getName().length() - 6);
|
||||
className = className.replace('/', '.');
|
||||
Class<?> c = cl.loadClass(className);
|
||||
if (!Module.class.isAssignableFrom(c)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Module mod = (Module) c.newInstance();
|
||||
mod.load();
|
||||
modules.add(mod);
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.logException("Cannot load " + pathToJar.getName() + " jar file!", ex);
|
||||
} finally {
|
||||
try {
|
||||
if (jarFile != null) {
|
||||
jarFile.close();
|
||||
}
|
||||
if (cl != null) {
|
||||
cl.close();
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public void reloadModules() {
|
||||
unloadModules();
|
||||
loadModules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method unloadModule.
|
||||
*
|
||||
* @param name String
|
||||
*/
|
||||
public void unloadModule(String name) {
|
||||
Iterator<Module> it = modules.iterator();
|
||||
while (it.hasNext()) {
|
||||
Module m = it.next();
|
||||
if (m.getName().equalsIgnoreCase(name)) {
|
||||
m.unload();
|
||||
it.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadModules() {
|
||||
Iterator<Module> it = modules.iterator();
|
||||
while (it.hasNext()) {
|
||||
it.next().unload();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -76,6 +76,9 @@ public class Messages {
|
||||
+ "Please verify your config file at '" + fileName + "'");
|
||||
return formatMessage(getDefault(code));
|
||||
}
|
||||
if(message.isEmpty()) {
|
||||
return new String[0];
|
||||
}
|
||||
return formatMessage(message);
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
package fr.xephi.authme.permission;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import de.bananaco.bpermissions.api.ApiLayer;
|
||||
import de.bananaco.bpermissions.api.CalculableType;
|
||||
import fr.xephi.authme.command.CommandDescription;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.anjocaido.groupmanager.GroupManager;
|
||||
import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -18,15 +17,15 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService;
|
||||
|
||||
import de.bananaco.bpermissions.api.ApiLayer;
|
||||
import de.bananaco.bpermissions.api.CalculableType;
|
||||
import fr.xephi.authme.command.CommandDescription;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import ru.tehkode.permissions.PermissionUser;
|
||||
import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* PermissionsManager.
|
||||
@ -49,18 +48,10 @@ public class PermissionsManager implements PermissionsService {
|
||||
* Server instance.
|
||||
*/
|
||||
private final Server server;
|
||||
/**
|
||||
* Plugin instance.
|
||||
*/
|
||||
private final Plugin plugin;
|
||||
/**
|
||||
* Logger instance.
|
||||
*/
|
||||
private Logger log;
|
||||
/**
|
||||
* The permissions manager Bukkit listener instance.
|
||||
*/
|
||||
private PermissionsManagerBukkitListener bukkitListener;
|
||||
/**
|
||||
* Type of permissions system that is currently used.
|
||||
* Null if no permissions system is hooked and/or used.
|
||||
@ -79,28 +70,11 @@ public class PermissionsManager implements PermissionsService {
|
||||
* Constructor.
|
||||
*
|
||||
* @param server Server instance
|
||||
* @param plugin Plugin instance
|
||||
* @param log Logger
|
||||
*/
|
||||
public PermissionsManager(Server server, Plugin plugin, Logger log) {
|
||||
public PermissionsManager(Server server, Logger log) {
|
||||
this.server = server;
|
||||
this.plugin = plugin;
|
||||
this.log = log;
|
||||
|
||||
// Create and register the Bukkit listener on the server if it's valid
|
||||
if(this.server != null) {
|
||||
// Create the Bukkit listener
|
||||
this.bukkitListener = new PermissionsManagerBukkitListener(this);
|
||||
|
||||
// Get the plugin manager instance
|
||||
PluginManager pluginManager = this.server.getPluginManager();
|
||||
|
||||
// Register the Bukkit listener
|
||||
pluginManager.registerEvents(this.bukkitListener, this.plugin);
|
||||
|
||||
// Show a status message.
|
||||
//this.log.info("Started permission plugins state listener!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,15 +256,6 @@ public class PermissionsManager implements PermissionsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions manager Bukkit listener instance.
|
||||
*
|
||||
* @return Listener instance.
|
||||
*/
|
||||
public PermissionsManagerBukkitListener getListener() {
|
||||
return this.bukkitListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the command sender has permission for the given permissions node. If no permissions system is used or
|
||||
* if the sender is not a player (e.g. console user), the player has to be OP in order to have the permission.
|
||||
|
||||
@ -1,85 +0,0 @@
|
||||
package fr.xephi.authme.permission;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
|
||||
public class PermissionsManagerBukkitListener implements Listener {
|
||||
|
||||
/**
|
||||
* The permissions manager instance.
|
||||
*/
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
/**
|
||||
* Whether the listener is enabled or not.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Constructor.\
|
||||
*
|
||||
* @param permissionsManager Permissions manager instance.
|
||||
*/
|
||||
public PermissionsManagerBukkitListener(PermissionsManager permissionsManager) {
|
||||
this.permissionsManager = permissionsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the listener is enabled.
|
||||
*
|
||||
* @return True if the listener is enabled.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the listener is enabled.
|
||||
* Disabling the listener will stop the event handling until it's enabled again.
|
||||
*
|
||||
* @param enabled True if enabled, false if disabled.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a plugin is enabled.
|
||||
*
|
||||
* @param event Event reference.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent event) {
|
||||
// Make sure the listener is enabled
|
||||
if(!isEnabled())
|
||||
return;
|
||||
|
||||
// Make sure the permissions manager is set
|
||||
if(this.permissionsManager == null)
|
||||
return;
|
||||
|
||||
// Call the onPluginEnable method in the permissions manager
|
||||
permissionsManager.onPluginEnable(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a plugin is disabled.
|
||||
*
|
||||
* @param event Event reference.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
// Make sure the listener is enabled
|
||||
if(!isEnabled())
|
||||
return;
|
||||
|
||||
// Make sure the permissions manager is set
|
||||
if(this.permissionsManager == null)
|
||||
return;
|
||||
|
||||
// Call the onPluginDisable method in the permissions manager
|
||||
permissionsManager.onPluginDisable(event);
|
||||
}
|
||||
}
|
||||
@ -41,7 +41,7 @@ public class Management {
|
||||
}
|
||||
|
||||
public void performRegister(final Player player, final String password, final String email) {
|
||||
runTask(new AsyncRegister(player, password, email, plugin, dataSource, processService));
|
||||
runTask(new AsyncRegister(player, password, email, plugin, dataSource, playerCache, processService));
|
||||
}
|
||||
|
||||
public void performUnregister(final Player player, final String password, final boolean force) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package fr.xephi.authme.process;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
@ -11,10 +10,15 @@ import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Service for asynchronous and synchronous processes.
|
||||
*/
|
||||
@ -24,22 +28,24 @@ public class ProcessService {
|
||||
private final Messages messages;
|
||||
private final AuthMe authMe;
|
||||
private final DataSource dataSource;
|
||||
private final IpAddressManager ipAddressManager;
|
||||
private final PasswordSecurity passwordSecurity;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
private final ValidationService validationService;
|
||||
private final BukkitService bukkitService;
|
||||
|
||||
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, DataSource dataSource,
|
||||
IpAddressManager ipAddressManager, PasswordSecurity passwordSecurity, PluginHooks pluginHooks,
|
||||
SpawnLoader spawnLoader) {
|
||||
PasswordSecurity passwordSecurity, PluginHooks pluginHooks, SpawnLoader spawnLoader,
|
||||
ValidationService validationService, BukkitService bukkitService) {
|
||||
this.settings = settings;
|
||||
this.messages = messages;
|
||||
this.authMe = authMe;
|
||||
this.dataSource = dataSource;
|
||||
this.ipAddressManager = ipAddressManager;
|
||||
this.passwordSecurity = passwordSecurity;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
this.validationService = validationService;
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,15 +158,6 @@ public class ProcessService {
|
||||
return authMe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IP address manager.
|
||||
*
|
||||
* @return the ip address manager
|
||||
*/
|
||||
public IpAddressManager getIpAddressManager() {
|
||||
return ipAddressManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the hash for the given password.
|
||||
*
|
||||
@ -199,4 +196,31 @@ public class ProcessService {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether a password is valid according to the plugin settings.
|
||||
*
|
||||
* @param password the password to verify
|
||||
* @param username the username the password is associated with
|
||||
* @return message key with the password error, or {@code null} if password is valid
|
||||
*/
|
||||
public MessageKey validatePassword(String password, String username) {
|
||||
return validationService.validatePassword(password, username);
|
||||
}
|
||||
|
||||
public boolean validateEmail(String email) {
|
||||
return validationService.validateEmail(email);
|
||||
}
|
||||
|
||||
public boolean isEmailFreeForRegistration(String email, CommandSender sender) {
|
||||
return validationService.isEmailFreeForRegistration(email, sender);
|
||||
}
|
||||
|
||||
public Collection<? extends Player> getOnlinePlayers() {
|
||||
return bukkitService.getOnlinePlayers();
|
||||
}
|
||||
|
||||
public BukkitService getBukkitService() {
|
||||
return bukkitService;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
@ -41,9 +40,9 @@ public class AsyncAddEmail implements Process {
|
||||
|
||||
if (currentEmail != null && !"your@email.com".equals(currentEmail)) {
|
||||
service.send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
} else if (!Utils.isEmailCorrect(email, service.getSettings())) {
|
||||
} else if (!service.validateEmail(email)) {
|
||||
service.send(player, MessageKey.INVALID_EMAIL);
|
||||
} else if (dataSource.isEmailStored(email)) {
|
||||
} else if (!service.isEmailFreeForRegistration(email, player)) {
|
||||
service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
} else {
|
||||
auth.setEmail(email);
|
||||
|
||||
@ -7,7 +7,6 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
@ -41,11 +40,11 @@ public class AsyncChangeEmail implements Process {
|
||||
|
||||
if (currentEmail == null) {
|
||||
service.send(player, MessageKey.USAGE_ADD_EMAIL);
|
||||
} else if (newEmail == null || !Utils.isEmailCorrect(newEmail, service.getSettings())) {
|
||||
} else if (newEmail == null || !service.validateEmail(newEmail)) {
|
||||
service.send(player, MessageKey.INVALID_NEW_EMAIL);
|
||||
} else if (!oldEmail.equals(currentEmail)) {
|
||||
service.send(player, MessageKey.INVALID_OLD_EMAIL);
|
||||
} else if (dataSource.isEmailStored(newEmail)) {
|
||||
} else if (!service.isEmailFreeForRegistration(newEmail, player)) {
|
||||
service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
} else {
|
||||
saveNewEmail(auth);
|
||||
@ -62,7 +61,6 @@ public class AsyncChangeEmail implements Process {
|
||||
service.send(player, MessageKey.EMAIL_CHANGED_SUCCESS);
|
||||
} else {
|
||||
service.send(player, MessageKey.ERROR);
|
||||
auth.setEmail(newEmail);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,23 +14,27 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.Utils.GroupType;
|
||||
import org.apache.commons.lang.reflect.MethodUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AsynchronousJoin implements Process {
|
||||
@ -42,6 +46,9 @@ public class AsynchronousJoin implements Process {
|
||||
private final ProcessService service;
|
||||
private final PlayerCache playerCache;
|
||||
|
||||
private final boolean disableCollisions = MethodUtils
|
||||
.getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null;
|
||||
|
||||
public AsynchronousJoin(Player player, AuthMe plugin, DataSource database, PlayerCache playerCache,
|
||||
ProcessService service) {
|
||||
this.player = player;
|
||||
@ -62,14 +69,14 @@ public class AsynchronousJoin implements Process {
|
||||
service.getPluginHooks().setEssentialsSocialSpyStatus(player, false);
|
||||
}
|
||||
|
||||
final String ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
if (isNameRestricted(name, ip, player.getAddress().getHostName(), service.getSettings())) {
|
||||
final String ip = Utils.getPlayerIp(player);
|
||||
if (isNameRestricted(name, ip, player.getAddress().getHostName())) {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
|
||||
player.kickPlayer(service.retrieveSingleMessage(MessageKey.NOT_OWNER_ERROR));
|
||||
if (Settings.banUnsafeIp) {
|
||||
if (service.getProperty(RestrictionSettings.BAN_UNKNOWN_IP)) {
|
||||
plugin.getServer().banIP(ip);
|
||||
}
|
||||
}
|
||||
@ -80,7 +87,7 @@ public class AsynchronousJoin implements Process {
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
&& !"127.0.0.1".equalsIgnoreCase(ip)
|
||||
&& !"localhost".equalsIgnoreCase(ip)
|
||||
&& hasJoinedIp(player.getName(), ip, service.getSettings())) {
|
||||
&& hasJoinedIp(player.getName(), ip)) {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -89,10 +96,14 @@ public class AsynchronousJoin implements Process {
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Prevent player collisions in 1.9
|
||||
if (disableCollisions) {
|
||||
((LivingEntity) player).setCollidable(false);
|
||||
}
|
||||
final Location spawnLoc = service.getSpawnLoader().getSpawnLocation(player);
|
||||
final boolean isAuthAvailable = database.isAuthAvailable(name);
|
||||
if (isAuthAvailable) {
|
||||
if (!Settings.noTeleport) {
|
||||
if (!service.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||
if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
@ -111,12 +122,12 @@ public class AsynchronousJoin implements Process {
|
||||
LimboCache.getInstance().updateLimboPlayer(player);
|
||||
|
||||
// protect inventory
|
||||
if (Settings.protectInventoryBeforeLogInEnabled && plugin.inventoryProtector != null) {
|
||||
if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN) && plugin.inventoryProtector != null) {
|
||||
ProtectInventoryEvent ev = new ProtectInventoryEvent(player);
|
||||
plugin.getServer().getPluginManager().callEvent(ev);
|
||||
if (ev.isCancelled()) {
|
||||
plugin.inventoryProtector.sendInventoryPacket(player);
|
||||
if (!Settings.noConsoleSpam) {
|
||||
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + "...");
|
||||
}
|
||||
}
|
||||
@ -134,7 +145,7 @@ public class AsynchronousJoin implements Process {
|
||||
service.send(player, MessageKey.SESSION_RECONNECTION);
|
||||
plugin.getManagement().performLogin(player, "dontneed", true);
|
||||
return;
|
||||
} else if (Settings.sessionExpireOnIpChange) {
|
||||
} else if (service.getProperty(PluginSettings.SESSIONS_EXPIRE_ON_IP_CHANGE)) {
|
||||
service.send(player, MessageKey.SESSION_EXPIRED);
|
||||
}
|
||||
}
|
||||
@ -142,7 +153,7 @@ public class AsynchronousJoin implements Process {
|
||||
if (!Settings.unRegisteredGroup.isEmpty()) {
|
||||
Utils.setGroup(player, Utils.GroupType.UNREGISTERED);
|
||||
}
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
if (!service.getProperty(RegistrationSettings.FORCE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -173,12 +184,13 @@ public class AsynchronousJoin implements Process {
|
||||
@Override
|
||||
public void run() {
|
||||
player.setOp(false);
|
||||
if (Settings.isRemoveSpeedEnabled) {
|
||||
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)
|
||||
&& service.getProperty(RestrictionSettings.REMOVE_SPEED)) {
|
||||
player.setFlySpeed(0.0f);
|
||||
player.setWalkSpeed(0.0f);
|
||||
}
|
||||
player.setNoDamageTicks(registrationTimeout);
|
||||
if (service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) {
|
||||
if (plugin.getPluginHooks().isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) {
|
||||
player.performCommand("motd");
|
||||
}
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
@ -200,12 +212,13 @@ public class AsynchronousJoin implements Process {
|
||||
if (isAuthAvailable) {
|
||||
msg = MessageKey.LOGIN_MESSAGE;
|
||||
} else {
|
||||
msg = Settings.emailRegistration
|
||||
msg = service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)
|
||||
? MessageKey.REGISTER_EMAIL_MESSAGE
|
||||
: MessageKey.REGISTER_MESSAGE;
|
||||
}
|
||||
if (msgInterval > 0 && LimboCache.getInstance().getLimboPlayer(name) != null) {
|
||||
BukkitTask msgTask = service.runTask(new MessageTask(plugin, name, msg, msgInterval));
|
||||
BukkitTask msgTask = service.runTask(new MessageTask(service.getBukkitService(), plugin.getMessages(),
|
||||
name, msg, msgInterval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTask(msgTask);
|
||||
}
|
||||
}
|
||||
@ -266,24 +279,22 @@ public class AsynchronousJoin implements Process {
|
||||
* @param name The name to check
|
||||
* @param ip The IP address of the player
|
||||
* @param domain The hostname of the IP address
|
||||
* @param settings The settings instance
|
||||
* @return True if the name is restricted (IP/domain is not allowed for the given name),
|
||||
* false if the restrictions are met or if the name has no restrictions to it
|
||||
*/
|
||||
private static boolean isNameRestricted(String name, String ip, String domain, NewSetting settings) {
|
||||
if (!settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)) {
|
||||
private boolean isNameRestricted(String name, String ip, String domain) {
|
||||
if (!service.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean nameFound = false;
|
||||
for (String entry : settings.getProperty(RestrictionSettings.ALLOWED_RESTRICTED_USERS)) {
|
||||
for (String entry : service.getProperty(RestrictionSettings.ALLOWED_RESTRICTED_USERS)) {
|
||||
String[] args = entry.split(";");
|
||||
String testName = args[0];
|
||||
String testIp = args[1];
|
||||
if (testName.equalsIgnoreCase(name)) {
|
||||
nameFound = true;
|
||||
if ((ip != null && testIp.equals(ip))
|
||||
|| (domain != null && testIp.equalsIgnoreCase(domain))) {
|
||||
if ((ip != null && testIp.equals(ip)) || (domain != null && testIp.equalsIgnoreCase(domain))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -291,14 +302,14 @@ public class AsynchronousJoin implements Process {
|
||||
return nameFound;
|
||||
}
|
||||
|
||||
private boolean hasJoinedIp(String name, String ip, NewSetting settings) {
|
||||
private boolean hasJoinedIp(String name, String ip) {
|
||||
int count = 0;
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(service.getIpAddressManager().getPlayerIp(player))
|
||||
for (Player player : service.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(Utils.getPlayerIp(player))
|
||||
&& !player.getName().equalsIgnoreCase(name)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count >= settings.getProperty(RestrictionSettings.MAX_JOIN_PER_IP);
|
||||
return count >= service.getProperty(RestrictionSettings.MAX_JOIN_PER_IP);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
@ -52,7 +53,7 @@ public class AsynchronousLogin implements Process {
|
||||
this.forceLogin = forceLogin;
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
this.ip = Utils.getPlayerIp(player);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@ -96,8 +97,8 @@ public class AsynchronousLogin implements Process {
|
||||
String[] msg = service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)
|
||||
? service.retrieveMessage(MessageKey.REGISTER_EMAIL_MESSAGE)
|
||||
: service.retrieveMessage(MessageKey.REGISTER_MESSAGE);
|
||||
BukkitTask messageTask = service.runTask(
|
||||
new MessageTask(plugin, name, msg, service.getProperty(RegistrationSettings.MESSAGE_INTERVAL)));
|
||||
BukkitTask messageTask = service.runTask(new MessageTask(service.getBukkitService(),
|
||||
name, msg, service.getProperty(RegistrationSettings.MESSAGE_INTERVAL)));
|
||||
limboPlayer.setMessageTask(messageTask);
|
||||
}
|
||||
return null;
|
||||
@ -166,11 +167,12 @@ public class AsynchronousLogin implements Process {
|
||||
|
||||
displayOtherAccounts(auth);
|
||||
|
||||
if (Settings.recallEmail && (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email))) {
|
||||
if (service.getProperty(EmailSettings.RECALL_PLAYERS)
|
||||
&& (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email))) {
|
||||
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info(realName + " logged in!");
|
||||
}
|
||||
|
||||
@ -182,8 +184,7 @@ public class AsynchronousLogin implements Process {
|
||||
// task, we schedule it in the end
|
||||
// so that we can be sure, and have not to care if it might be
|
||||
// processed in other order.
|
||||
ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(
|
||||
player, plugin, database, service.getSettings());
|
||||
ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(player, plugin, database, service);
|
||||
if (syncPlayerLogin.getLimbo() != null) {
|
||||
if (syncPlayerLogin.getLimbo().getTimeoutTask() != null) {
|
||||
syncPlayerLogin.getLimbo().getTimeoutTask().cancel();
|
||||
@ -213,7 +214,7 @@ public class AsynchronousLogin implements Process {
|
||||
}
|
||||
|
||||
private void displayOtherAccounts(PlayerAuth auth) {
|
||||
if (!Settings.displayOtherAccounts || auth == null) {
|
||||
if (!service.getProperty(RestrictionSettings.DISPLAY_OTHER_ACCOUNTS) || auth == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -222,7 +223,7 @@ public class AsynchronousLogin implements Process {
|
||||
return;
|
||||
}
|
||||
String message = "[AuthMe] " + StringUtils.join(", ", auths) + ".";
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
for (Player player : service.getOnlinePlayers()) {
|
||||
if (plugin.getPermissionsManager().hasPermission(player, AdminPermission.SEE_OTHER_ACCOUNTS)
|
||||
|| (player.getName().equals(this.player.getName())
|
||||
&& plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OWN_ACCOUNTS))) {
|
||||
|
||||
@ -1,18 +1,7 @@
|
||||
package fr.xephi.authme.process.login;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.backup.JsonCache;
|
||||
@ -24,14 +13,26 @@ import fr.xephi.authme.events.LoginEvent;
|
||||
import fr.xephi.authme.events.RestoreInventoryEvent;
|
||||
import fr.xephi.authme.events.SpawnTeleportEvent;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.Utils.GroupType;
|
||||
import org.apache.commons.lang.reflect.MethodUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.KEEP_COLLISIONS_DISABLED;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||
|
||||
|
||||
public class ProcessSyncPlayerLogin implements Runnable {
|
||||
public class ProcessSyncPlayerLogin implements Process {
|
||||
|
||||
private final LimboPlayer limbo;
|
||||
private final Player player;
|
||||
@ -40,7 +41,10 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
private final AuthMe plugin;
|
||||
private final PluginManager pm;
|
||||
private final JsonCache playerCache;
|
||||
private final NewSetting settings;
|
||||
private final ProcessService service;
|
||||
|
||||
private final boolean restoreCollisions = MethodUtils
|
||||
.getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null;
|
||||
|
||||
/**
|
||||
* Constructor for ProcessSyncPlayerLogin.
|
||||
@ -48,10 +52,9 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param database DataSource
|
||||
* @param settings The plugin settings
|
||||
* @param service The process service
|
||||
*/
|
||||
public ProcessSyncPlayerLogin(Player player, AuthMe plugin,
|
||||
DataSource database, NewSetting settings) {
|
||||
public ProcessSyncPlayerLogin(Player player, AuthMe plugin, DataSource database, ProcessService service) {
|
||||
this.plugin = plugin;
|
||||
this.pm = plugin.getServer().getPluginManager();
|
||||
this.player = player;
|
||||
@ -59,7 +62,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
this.limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
this.auth = database.getAuth(name);
|
||||
this.playerCache = new JsonCache();
|
||||
this.settings = settings;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public LimboPlayer getLimbo() {
|
||||
@ -92,7 +95,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
|
||||
private void restoreSpeedEffects() {
|
||||
if (settings.getProperty(RestrictionSettings.REMOVE_SPEED)) {
|
||||
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT) && service.getProperty(RestrictionSettings.REMOVE_SPEED)) {
|
||||
player.setWalkSpeed(0.2F);
|
||||
player.setFlySpeed(0.1F);
|
||||
}
|
||||
@ -107,10 +110,10 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
|
||||
private void forceCommands() {
|
||||
for (String command : Settings.forceCommands) {
|
||||
for (String command : service.getProperty(RegistrationSettings.FORCE_COMMANDS)) {
|
||||
player.performCommand(command.replace("%p", player.getName()));
|
||||
}
|
||||
for (String command : Settings.forceCommandsAsConsole) {
|
||||
for (String command : service.getProperty(RegistrationSettings.FORCE_COMMANDS_AS_CONSOLE)) {
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command.replace("%p", player.getName()));
|
||||
}
|
||||
}
|
||||
@ -148,10 +151,18 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||
if (restoreCollisions && !service.getProperty(KEEP_COLLISIONS_DISABLED)) {
|
||||
player.setCollidable(true);
|
||||
}
|
||||
|
||||
if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||
restoreInventory();
|
||||
}
|
||||
|
||||
if (service.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN) && plugin.tablistHider != null) {
|
||||
plugin.tablistHider.sendTablist(player);
|
||||
}
|
||||
|
||||
// Cleanup no longer used temporary data
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
if (playerCache.doesCacheExist(player)) {
|
||||
@ -163,7 +174,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
String jm = AuthMePlayerListener.joinMessage.get(name);
|
||||
if (jm != null) {
|
||||
if (!jm.isEmpty()) {
|
||||
for (Player p : Utils.getOnlinePlayers()) {
|
||||
for (Player p : service.getOnlinePlayers()) {
|
||||
if (p.isOnline()) {
|
||||
p.sendMessage(jm);
|
||||
}
|
||||
@ -173,24 +184,24 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
|
||||
restoreSpeedEffects();
|
||||
if (settings.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
player.removePotionEffect(PotionEffectType.BLINDNESS);
|
||||
}
|
||||
|
||||
// The Login event now fires (as intended) after everything is processed
|
||||
Bukkit.getServer().getPluginManager().callEvent(new LoginEvent(player));
|
||||
player.saveData();
|
||||
if (settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
if (service.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
sendBungeeMessage();
|
||||
}
|
||||
// Login is done, display welcome message
|
||||
if (settings.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
|
||||
if (settings.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
if (service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
|
||||
if (service.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) {
|
||||
for (String s : service.getSettings().getWelcomeMessage()) {
|
||||
Bukkit.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
} else {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
for (String s : service.getSettings().getWelcomeMessage()) {
|
||||
player.sendMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
}
|
||||
@ -198,15 +209,15 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
|
||||
// Login is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
|
||||
sendTo();
|
||||
}
|
||||
|
||||
private void sendTo() {
|
||||
if (!settings.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
|
||||
if (!service.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(settings.getProperty(HooksSettings.BUNGEECORD_SERVER));
|
||||
out.writeUTF(service.getProperty(HooksSettings.BUNGEECORD_SERVER));
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,8 @@ public class ProcessSynchronousPlayerLogout implements Process {
|
||||
BukkitTask id = service.runTaskLater(new TimeoutTask(plugin, name, player), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTask(id);
|
||||
}
|
||||
BukkitTask msgT = service.runTask(new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
BukkitTask msgT = service.runTask(new MessageTask(service.getBukkitService(), plugin.getMessages(),
|
||||
name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTask(msgT);
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null) {
|
||||
player.getVehicle().eject();
|
||||
|
||||
@ -43,7 +43,7 @@ public class AsynchronousQuit implements Process {
|
||||
return;
|
||||
}
|
||||
|
||||
String ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
String ip = Utils.getPlayerIp(player);
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||
@ -94,7 +94,6 @@ public class AsynchronousQuit implements Process {
|
||||
database.setUnlogged(name);
|
||||
}
|
||||
|
||||
service.getIpAddressManager().removeCache(player.getName());
|
||||
if (plugin.isEnabled()) {
|
||||
service.scheduleSyncDelayedTask(new ProcessSyncronousPlayerQuit(plugin, player, isOp, needToChange));
|
||||
}
|
||||
|
||||
@ -38,9 +38,6 @@ public class ProcessSyncronousPlayerQuit implements Runnable {
|
||||
if (needToChange) {
|
||||
player.setOp(isOp);
|
||||
}
|
||||
try {
|
||||
player.getVehicle().eject();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
player.leaveVehicle();
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,8 +12,13 @@ import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.TwoFactor;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -30,43 +35,36 @@ public class AsyncRegister implements Process {
|
||||
private final String email;
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private final PlayerCache playerCache;
|
||||
private final ProcessService service;
|
||||
|
||||
public AsyncRegister(Player player, String password, String email, AuthMe plugin, DataSource data,
|
||||
ProcessService service) {
|
||||
PlayerCache playerCache, ProcessService service) {
|
||||
this.player = player;
|
||||
this.password = password;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.email = email;
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
this.ip = Utils.getPlayerIp(player);
|
||||
this.playerCache = playerCache;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private boolean preRegisterCheck() {
|
||||
String passLow = password.toLowerCase();
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
if (playerCache.isAuthenticated(name)) {
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return false;
|
||||
} else if (!Settings.isRegistrationEnabled) {
|
||||
} else if (!service.getProperty(RegistrationSettings.IS_ENABLED)) {
|
||||
service.send(player, MessageKey.REGISTRATION_DISABLED);
|
||||
return false;
|
||||
}
|
||||
|
||||
//check the password safety only if it's not a automatically generated password
|
||||
if (service.getProperty(SecuritySettings.PASSWORD_HASH) != HashAlgorithm.TWO_FACTOR) {
|
||||
if (!passLow.matches(Settings.getPassRegex)) {
|
||||
service.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
return false;
|
||||
} else if (passLow.equalsIgnoreCase(player.getName())) {
|
||||
service.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
return false;
|
||||
} else if (password.length() < Settings.getPasswordMinLen || password.length() > Settings.passwordMaxLength) {
|
||||
service.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
return false;
|
||||
} else if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(password.toLowerCase())) {
|
||||
service.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
MessageKey passwordError = service.validatePassword(password, player.getName());
|
||||
if (passwordError != null) {
|
||||
service.send(player, passwordError);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -75,15 +73,17 @@ public class AsyncRegister implements Process {
|
||||
if (database.isAuthAvailable(name)) {
|
||||
service.send(player, MessageKey.NAME_ALREADY_REGISTERED);
|
||||
return false;
|
||||
} else if(Settings.getmaxRegPerIp > 0
|
||||
&& !ip.equalsIgnoreCase("127.0.0.1")
|
||||
&& !ip.equalsIgnoreCase("localhost")
|
||||
}
|
||||
|
||||
final int maxRegPerIp = service.getProperty(RestrictionSettings.MAX_REGISTRATION_PER_IP);
|
||||
if (maxRegPerIp > 0
|
||||
&& !"127.0.0.1".equalsIgnoreCase(ip)
|
||||
&& !"localhost".equalsIgnoreCase(ip)
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) {
|
||||
int maxReg = Settings.getmaxRegPerIp;
|
||||
List<String> otherAccounts = database.getAllAuthsByIp(ip);
|
||||
if (otherAccounts.size() >= maxReg) {
|
||||
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxReg),
|
||||
Integer.toString(otherAccounts.size()), StringUtils.join(", ", otherAccounts.toString()));
|
||||
if (otherAccounts.size() >= maxRegPerIp) {
|
||||
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxRegPerIp),
|
||||
Integer.toString(otherAccounts.size()), StringUtils.join(", ", otherAccounts));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -102,12 +102,12 @@ public class AsyncRegister implements Process {
|
||||
}
|
||||
|
||||
private void emailRegister() {
|
||||
if (Settings.getmaxRegPerEmail > 0
|
||||
final int maxRegPerEmail = service.getProperty(EmailSettings.MAX_REG_PER_EMAIL);
|
||||
if (maxRegPerEmail > 0
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) {
|
||||
int maxReg = Settings.getmaxRegPerEmail;
|
||||
int otherAccounts = database.countAuthsByEmail(email);
|
||||
if (otherAccounts >= maxReg) {
|
||||
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxReg),
|
||||
if (otherAccounts >= maxRegPerEmail) {
|
||||
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxRegPerEmail),
|
||||
Integer.toString(otherAccounts), "@");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -52,13 +52,13 @@ public class ProcessSyncEmailRegister implements Process {
|
||||
limbo.setTimeoutTask(id);
|
||||
}
|
||||
BukkitTask messageTask = service.runTask(new MessageTask(
|
||||
service.getAuthMe(), name, service.retrieveMessage(MessageKey.LOGIN_MESSAGE), msgInterval));
|
||||
service.getBukkitService(), name, service.retrieveMessage(MessageKey.LOGIN_MESSAGE), msgInterval));
|
||||
limbo.setMessageTask(messageTask);
|
||||
}
|
||||
|
||||
player.saveData();
|
||||
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info(player.getName() + " registered " + service.getIpAddressManager().getPlayerIp(player));
|
||||
ConsoleLogger.info(player.getName() + " registered " + Utils.getPlayerIp(player));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,9 +12,11 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
@ -23,12 +25,15 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN;
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ProcessSyncPasswordRegister implements Process {
|
||||
|
||||
protected final Player player;
|
||||
protected final String name;
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private final AuthMe plugin;
|
||||
private final ProcessService service;
|
||||
|
||||
@ -49,27 +54,33 @@ public class ProcessSyncPasswordRegister implements Process {
|
||||
}
|
||||
|
||||
private void forceCommands() {
|
||||
for (String command : Settings.forceRegisterCommands) {
|
||||
for (String command : service.getProperty(RegistrationSettings.FORCE_REGISTER_COMMANDS)) {
|
||||
player.performCommand(command.replace("%p", player.getName()));
|
||||
}
|
||||
for (String command : Settings.forceRegisterCommandsAsConsole) {
|
||||
for (String command : service.getProperty(RegistrationSettings.FORCE_REGISTER_COMMANDS_AS_CONSOLE)) {
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
command.replace("%p", player.getName()));
|
||||
command.replace("%p", player.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private void forceLogin(Player player) {
|
||||
/**
|
||||
* Request that the player log in.
|
||||
*
|
||||
* @param player the player
|
||||
*/
|
||||
private void requestLogin(Player player) {
|
||||
Utils.teleportToSpawn(player);
|
||||
LimboCache cache = LimboCache.getInstance();
|
||||
cache.updateLimboPlayer(player);
|
||||
int delay = service.getProperty(RestrictionSettings.TIMEOUT) * 20;
|
||||
int delay = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
BukkitTask task;
|
||||
if (delay != 0) {
|
||||
task = service.runTaskLater(new TimeoutTask(service.getAuthMe(), name, player), delay);
|
||||
cache.getLimboPlayer(name).setTimeoutTask(task);
|
||||
}
|
||||
task = service.runTask(new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
task = service.runTask(new MessageTask(service.getBukkitService(), plugin.getMessages(),
|
||||
name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
cache.getLimboPlayer(name).setMessageTask(task);
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null) {
|
||||
player.getVehicle().eject();
|
||||
@ -80,11 +91,15 @@ public class ProcessSyncPasswordRegister implements Process {
|
||||
public void run() {
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (limbo != null) {
|
||||
if (service.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN) && plugin.tablistHider != null) {
|
||||
plugin.tablistHider.sendTablist(player);
|
||||
}
|
||||
|
||||
Utils.teleportToSpawn(player);
|
||||
|
||||
if (Settings.protectInventoryBeforeLogInEnabled && plugin.inventoryProtector != null) {
|
||||
if (service.getProperty(HIDE_TABLIST_BEFORE_LOGIN) && plugin.inventoryProtector != null) {
|
||||
RestoreInventoryEvent event = new RestoreInventoryEvent(player);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
service.callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
plugin.inventoryProtector.sendInventoryPacket(player);
|
||||
}
|
||||
@ -99,7 +114,7 @@ public class ProcessSyncPasswordRegister implements Process {
|
||||
|
||||
service.send(player, MessageKey.REGISTER_SUCCESS);
|
||||
|
||||
if (!Settings.getmailAccount.isEmpty()) {
|
||||
if (!service.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
|
||||
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
|
||||
@ -111,42 +126,29 @@ public class ProcessSyncPasswordRegister implements Process {
|
||||
plugin.getServer().getPluginManager().callEvent(new LoginEvent(player));
|
||||
player.saveData();
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
ConsoleLogger.info(player.getName() + " registered " + service.getIpAddressManager().getPlayerIp(player));
|
||||
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info(player.getName() + " registered " + Utils.getPlayerIp(player));
|
||||
}
|
||||
|
||||
// Kick Player after Registration is enabled, kick the player
|
||||
if (Settings.forceRegKick) {
|
||||
if (service.getProperty(RegistrationSettings.FORCE_KICK_AFTER_REGISTER)) {
|
||||
player.kickPlayer(service.retrieveSingleMessage(MessageKey.REGISTER_SUCCESS));
|
||||
return;
|
||||
}
|
||||
|
||||
// Register is finish and player is logged, display welcome message
|
||||
if (service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
|
||||
if (service.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) {
|
||||
for (String s : service.getSettings().getWelcomeMessage()) {
|
||||
plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
} else {
|
||||
for (String s : service.getSettings().getWelcomeMessage()) {
|
||||
player.sendMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Register is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
// Request Login after Registration
|
||||
if (Settings.forceRegLogin) {
|
||||
forceLogin(player);
|
||||
// Request login after registration
|
||||
if (service.getProperty(RegistrationSettings.FORCE_LOGIN_AFTER_REGISTER)) {
|
||||
requestLogin(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.bungee) {
|
||||
if (service.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
sendBungeeMessage();
|
||||
}
|
||||
|
||||
// Register is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
sendTo();
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ import fr.xephi.authme.util.Utils.GroupType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class AsynchronousUnregister implements Process {
|
||||
@ -73,13 +72,12 @@ public class AsynchronousUnregister implements Process {
|
||||
LimboCache.getInstance().addLimboPlayer(player);
|
||||
LimboPlayer limboPlayer = LimboCache.getInstance().getLimboPlayer(name);
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
BukkitScheduler scheduler = plugin.getServer().getScheduler();
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
BukkitTask id = service.runTaskLater(new TimeoutTask(plugin, name, player), timeOut);
|
||||
limboPlayer.setTimeoutTask(id);
|
||||
}
|
||||
limboPlayer.setMessageTask(scheduler.runTask(plugin,
|
||||
new MessageTask(plugin, name, MessageKey.REGISTER_MESSAGE, interval)));
|
||||
limboPlayer.setMessageTask(service.runTask(new MessageTask(service.getBukkitService(),
|
||||
plugin.getMessages(), name, MessageKey.REGISTER_MESSAGE, interval)));
|
||||
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
return;
|
||||
@ -99,7 +97,6 @@ public class AsynchronousUnregister implements Process {
|
||||
}
|
||||
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
Utils.teleportToSpawn(player);
|
||||
} else {
|
||||
service.send(player, MessageKey.WRONG_PASSWORD);
|
||||
}
|
||||
|
||||
@ -8,46 +8,75 @@ import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Manager class for password-related operations.
|
||||
*/
|
||||
public class PasswordSecurity {
|
||||
|
||||
private final NewSetting settings;
|
||||
private HashAlgorithm algorithm;
|
||||
private boolean supportOldAlgorithm;
|
||||
private final DataSource dataSource;
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
public PasswordSecurity(DataSource dataSource, NewSetting settings, PluginManager pluginManager) {
|
||||
this.settings = settings;
|
||||
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||
this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH);
|
||||
this.dataSource = dataSource;
|
||||
this.pluginManager = pluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the hash of the configured algorithm for the given password and username.
|
||||
*
|
||||
* @param password The password to hash
|
||||
* @param playerName The player's name
|
||||
*
|
||||
* @return The password hash
|
||||
*/
|
||||
public HashedPassword computeHash(String password, String playerName) {
|
||||
return computeHash(algorithm, password, playerName);
|
||||
}
|
||||
|
||||
public HashedPassword computeHash(HashAlgorithm algorithm, String password, String playerName) {
|
||||
String playerLowerCase = playerName.toLowerCase();
|
||||
EncryptionMethod method = initializeEncryptionMethod(algorithm, playerLowerCase);
|
||||
EncryptionMethod method = initializeEncryptionMethodWithEvent(algorithm, playerLowerCase);
|
||||
return method.computeHash(password, playerLowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given password matches the player's stored password.
|
||||
*
|
||||
* @param password The password to check
|
||||
* @param playerName The player to check for
|
||||
*
|
||||
* @return True if the password is correct, false otherwise
|
||||
*/
|
||||
public boolean comparePassword(String password, String playerName) {
|
||||
HashedPassword auth = dataSource.getPassword(playerName);
|
||||
return auth != null && comparePassword(password, auth, playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given password matches the given hashed password.
|
||||
*
|
||||
* @param password The password to check
|
||||
* @param hashedPassword The hashed password to check against
|
||||
* @param playerName The player to check for
|
||||
*
|
||||
* @return True if the password matches, false otherwise
|
||||
*/
|
||||
public boolean comparePassword(String password, HashedPassword hashedPassword, String playerName) {
|
||||
EncryptionMethod method = initializeEncryptionMethod(algorithm, playerName);
|
||||
EncryptionMethod method = initializeEncryptionMethodWithEvent(algorithm, playerName);
|
||||
String playerLowerCase = playerName.toLowerCase();
|
||||
return methodMatches(method, password, hashedPassword, playerLowerCase)
|
||||
|| supportOldAlgorithm && compareWithAllEncryptionMethods(password, hashedPassword, playerLowerCase);
|
||||
}
|
||||
|
||||
public void reload(NewSetting settings) {
|
||||
/**
|
||||
* Reload the configuration.
|
||||
*/
|
||||
public void reload() {
|
||||
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||
this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH);
|
||||
}
|
||||
@ -63,11 +92,10 @@ public class PasswordSecurity {
|
||||
*
|
||||
* @return True if there was a password match with another encryption method, false otherwise
|
||||
*/
|
||||
private boolean compareWithAllEncryptionMethods(String password, HashedPassword hashedPassword,
|
||||
String playerName) {
|
||||
private boolean compareWithAllEncryptionMethods(String password, HashedPassword hashedPassword, String playerName) {
|
||||
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
||||
if (!HashAlgorithm.CUSTOM.equals(algorithm)) {
|
||||
EncryptionMethod method = initializeEncryptionMethodWithoutEvent(algorithm);
|
||||
EncryptionMethod method = initializeEncryptionMethod(algorithm, settings);
|
||||
if (methodMatches(method, password, hashedPassword, playerName)) {
|
||||
hashPasswordForNewAlgorithm(password, playerName);
|
||||
return true;
|
||||
@ -85,6 +113,7 @@ public class PasswordSecurity {
|
||||
* @param password The password to check
|
||||
* @param hashedPassword The hash to check against
|
||||
* @param playerName The name of the player
|
||||
*
|
||||
* @return True if the password matched, false otherwise
|
||||
*/
|
||||
private static boolean methodMatches(EncryptionMethod method, String password,
|
||||
@ -103,33 +132,45 @@ public class PasswordSecurity {
|
||||
*
|
||||
* @return The encryption method
|
||||
*/
|
||||
private EncryptionMethod initializeEncryptionMethod(HashAlgorithm algorithm, String playerName) {
|
||||
EncryptionMethod method = initializeEncryptionMethodWithoutEvent(algorithm);
|
||||
private EncryptionMethod initializeEncryptionMethodWithEvent(HashAlgorithm algorithm, String playerName) {
|
||||
EncryptionMethod method = initializeEncryptionMethod(algorithm, settings);
|
||||
PasswordEncryptionEvent event = new PasswordEncryptionEvent(method, playerName);
|
||||
pluginManager.callEvent(event);
|
||||
return event.getMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the encryption method corresponding to the given hash algorithm.
|
||||
* Initialize the encryption method associated with the given hash algorithm.
|
||||
*
|
||||
* @param algorithm The algorithm to retrieve the encryption method for
|
||||
* @param settings The settings instance to pass to the constructor if required
|
||||
*
|
||||
* @return The associated encryption method
|
||||
* @return The associated encryption method, or null if CUSTOM / deprecated
|
||||
*/
|
||||
private static EncryptionMethod initializeEncryptionMethodWithoutEvent(HashAlgorithm algorithm) {
|
||||
public static EncryptionMethod initializeEncryptionMethod(HashAlgorithm algorithm,
|
||||
NewSetting settings) {
|
||||
try {
|
||||
return HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)
|
||||
? null
|
||||
: algorithm.getClazz().newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
||||
return null;
|
||||
}
|
||||
Constructor<?> constructor = algorithm.getClazz().getConstructors()[0];
|
||||
Class<?>[] parameters = constructor.getParameterTypes();
|
||||
if (parameters.length == 0) {
|
||||
return (EncryptionMethod) constructor.newInstance();
|
||||
} else if (parameters.length == 1 && parameters[0] == NewSetting.class) {
|
||||
return (EncryptionMethod) constructor.newInstance(settings);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Did not find default constructor or constructor with settings "
|
||||
+ "parameter in class " + algorithm.getClazz().getSimpleName());
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new UnsupportedOperationException("Constructor for '" + algorithm.getClazz().getSimpleName()
|
||||
+ "' could not be invoked. (Is there no default constructor?)", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void hashPasswordForNewAlgorithm(String password, String playerName) {
|
||||
HashedPassword hashedPassword = initializeEncryptionMethod(algorithm, playerName)
|
||||
HashedPassword hashedPassword = initializeEncryptionMethodWithEvent(algorithm, playerName)
|
||||
.computeHash(password, playerName);
|
||||
dataSource.updatePassword(playerName, hashedPassword);
|
||||
}
|
||||
|
||||
@ -5,7 +5,8 @@ import fr.xephi.authme.security.crypts.description.HasSalt;
|
||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||
import fr.xephi.authme.security.crypts.description.SaltType;
|
||||
import fr.xephi.authme.security.crypts.description.Usage;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
|
||||
@ -13,6 +14,12 @@ import fr.xephi.authme.util.StringUtils;
|
||||
@HasSalt(value = SaltType.TEXT) // length depends on Settings.bCryptLog2Rounds
|
||||
public class BCRYPT implements EncryptionMethod {
|
||||
|
||||
private final int bCryptLog2Rounds;
|
||||
|
||||
public BCRYPT(NewSetting settings) {
|
||||
this.bCryptLog2Rounds = settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String computeHash(String password, String salt, String name) {
|
||||
return BCryptService.hashpw(password, salt);
|
||||
@ -36,7 +43,7 @@ public class BCRYPT implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String generateSalt() {
|
||||
return BCryptService.gensalt(Settings.bCryptLog2Rounds);
|
||||
return BCryptService.gensalt(bCryptLog2Rounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.security.crypts.description.AsciiRestricted;
|
||||
import fr.xephi.authme.security.pbkdf2.PBKDF2Engine;
|
||||
import fr.xephi.authme.security.pbkdf2.PBKDF2Parameters;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
@ -31,8 +32,8 @@ public class CryptPBKDF2Django extends HexSaltedMethod {
|
||||
try {
|
||||
iterations = Integer.parseInt(line[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
ConsoleLogger.logException("Could not read number of rounds in '" + hashedPassword.getHash()
|
||||
+ " for CryptPBKDF2Django", e);
|
||||
ConsoleLogger.showError("Could not read number of rounds for CryptPBKDF2Django:"
|
||||
+ StringUtils.formatException(e));
|
||||
return false;
|
||||
}
|
||||
String salt = line[2];
|
||||
|
||||
@ -2,6 +2,10 @@ package fr.xephi.authme.security.crypts;
|
||||
|
||||
/**
|
||||
* Public interface for custom password encryption methods.
|
||||
* <p>
|
||||
* Note that {@link fr.xephi.authme.security.PasswordSecurity} requires classes implementing this interface
|
||||
* to either have the default constructor or an accessible constructor with one parameter of type
|
||||
* {@link fr.xephi.authme.settings.NewSetting}.
|
||||
*/
|
||||
public interface EncryptionMethod {
|
||||
|
||||
@ -31,9 +35,9 @@ public interface EncryptionMethod {
|
||||
/**
|
||||
* Check whether the given hash matches the clear-text password.
|
||||
*
|
||||
* @param password The clear-text password to verify
|
||||
* @param password The clear-text password to verify
|
||||
* @param hashedPassword The hash to check the password against
|
||||
* @param name The player name to do the check for (sometimes required for generating the salt)
|
||||
* @param name The player name to do the check for (sometimes required for generating the salt)
|
||||
*
|
||||
* @return True if the password matches, false otherwise
|
||||
*/
|
||||
|
||||
@ -19,7 +19,7 @@ public class MYBB extends SeparateSaltMethod {
|
||||
|
||||
@Override
|
||||
public String generateSalt() {
|
||||
return RandomString.generateHex(8);
|
||||
return RandomString.generateLowerUpper(8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,8 @@ import fr.xephi.authme.security.crypts.description.HasSalt;
|
||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||
import fr.xephi.authme.security.crypts.description.SaltType;
|
||||
import fr.xephi.authme.security.crypts.description.Usage;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
|
||||
import static fr.xephi.authme.security.HashUtils.md5;
|
||||
|
||||
@ -13,6 +14,12 @@ import static fr.xephi.authme.security.HashUtils.md5;
|
||||
@HasSalt(value = SaltType.TEXT) // length defined by Settings.saltLength
|
||||
public class SALTED2MD5 extends SeparateSaltMethod {
|
||||
|
||||
private final int saltLength;
|
||||
|
||||
public SALTED2MD5(NewSetting settings) {
|
||||
saltLength = settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String computeHash(String password, String salt, String name) {
|
||||
return md5(md5(password) + salt);
|
||||
@ -20,7 +27,7 @@ public class SALTED2MD5 extends SeparateSaltMethod {
|
||||
|
||||
@Override
|
||||
public String generateSalt() {
|
||||
return RandomString.generateHex(Settings.saltLength);
|
||||
return RandomString.generateHex(saltLength);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,10 +8,8 @@ import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -22,55 +20,27 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public final class Settings {
|
||||
|
||||
public static final File PLUGIN_FOLDER = Wrapper.getInstance().getDataFolder();
|
||||
public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules");
|
||||
public static final File CACHE_FOLDER = new File(PLUGIN_FOLDER, "cache");
|
||||
// This is not an option!
|
||||
public static boolean antiBotInAction = false;
|
||||
public static List<String> allowCommands;
|
||||
public static List<String> getJoinPermissions;
|
||||
public static List<String> getUnrestrictedName;
|
||||
public static List<String> getRestrictedIp;
|
||||
public static List<String> getForcedWorlds;
|
||||
public static List<String> countries;
|
||||
public static List<String> countriesBlacklist;
|
||||
public static List<String> forceCommands;
|
||||
public static List<String> forceCommandsAsConsole;
|
||||
public static List<String> forceRegisterCommands;
|
||||
public static List<String> forceRegisterCommandsAsConsole;
|
||||
public static List<String> unsafePasswords;
|
||||
public static HashAlgorithm getPasswordHash;
|
||||
public static Pattern nickPattern;
|
||||
public static boolean useLogging = false;
|
||||
public static boolean isChatAllowed, isPermissionCheckEnabled, isRegistrationEnabled,
|
||||
public static boolean isPermissionCheckEnabled,
|
||||
isForcedRegistrationEnabled, isTeleportToSpawnEnabled,
|
||||
isSessionsEnabled, isAllowRestrictedIp,
|
||||
isMovementAllowed, isKickNonRegisteredEnabled,
|
||||
isForceSingleSessionEnabled, isForceSpawnLocOnJoinEnabled,
|
||||
isSaveQuitLocationEnabled, isForceSurvivalModeEnabled,
|
||||
isKickOnWrongPasswordEnabled, enablePasswordConfirmation,
|
||||
protectInventoryBeforeLogInEnabled, isStopEnabled, reloadSupport,
|
||||
rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts,
|
||||
emailRegistration, multiverse, bungee,
|
||||
banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange,
|
||||
disableSocialSpy, useEssentialsMotd,
|
||||
enableProtection, recallEmail, useWelcomeMessage,
|
||||
broadcastWelcomeMessage, forceRegKick, forceRegLogin,
|
||||
checkVeryGames, removeJoinMessage, removeLeaveMessage, delayJoinMessage,
|
||||
noTeleport, hideTablistBeforeLogin, denyTabcompleteBeforeLogin,
|
||||
kickPlayersBeforeStopping, allowAllCommandsIfRegIsOptional,
|
||||
customAttributes, isRemoveSpeedEnabled, preventOtherCase;
|
||||
isSaveQuitLocationEnabled, protectInventoryBeforeLogInEnabled,
|
||||
isStopEnabled, reloadSupport, rakamakUseIp,
|
||||
removePassword, multiverse, bungee,
|
||||
enableProtection, forceRegLogin, noTeleport,
|
||||
allowAllCommandsIfRegIsOptional, isRemoveSpeedEnabled;
|
||||
public static String getNickRegex, getUnloggedinGroup,
|
||||
unRegisteredGroup,
|
||||
backupWindowsPath, getRegisteredGroup,
|
||||
rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld,
|
||||
spawnPriority, crazyloginFileName, getPassRegex, sendPlayerTo;
|
||||
public static int getWarnMessageInterval, getSessionTimeout,
|
||||
getRegistrationTimeout, getMaxNickLength, getMinNickLength,
|
||||
getPasswordMinLen, getMovementRadius, getmaxRegPerIp,
|
||||
getNonActivatedGroup, passwordMaxLength, getRecoveryPassLength,
|
||||
getMailPort, maxLoginTry, captchaLength, saltLength,
|
||||
getmaxRegPerEmail, bCryptLog2Rounds, getMaxLoginPerIp, getMaxJoinPerIp;
|
||||
unRegisteredGroup, backupWindowsPath, getRegisteredGroup,
|
||||
rakamakUsers, rakamakUsersIp, defaultWorld, crazyloginFileName;
|
||||
public static int getSessionTimeout, getMaxNickLength, getMinNickLength,
|
||||
getNonActivatedGroup, maxLoginTry, captchaLength, getMaxLoginPerIp;
|
||||
protected static FileConfiguration configFile;
|
||||
|
||||
/**
|
||||
@ -85,32 +55,19 @@ public final class Settings {
|
||||
|
||||
private static void loadVariables() {
|
||||
isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK);
|
||||
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
|
||||
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
|
||||
isForcedRegistrationEnabled = load(RegistrationSettings.FORCE);
|
||||
isTeleportToSpawnEnabled = load(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN);
|
||||
getWarnMessageInterval = load(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
isSessionsEnabled = load(PluginSettings.SESSIONS_ENABLED);
|
||||
getSessionTimeout = configFile.getInt("settings.sessions.timeout", 10);
|
||||
getRegistrationTimeout = load(RestrictionSettings.TIMEOUT);
|
||||
isChatAllowed = load(RestrictionSettings.ALLOW_CHAT);
|
||||
getMaxNickLength = configFile.getInt("settings.restrictions.maxNicknameLength", 20);
|
||||
getMinNickLength = configFile.getInt("settings.restrictions.minNicknameLength", 3);
|
||||
getPasswordMinLen = configFile.getInt("settings.security.minPasswordLength", 4);
|
||||
getNickRegex = configFile.getString("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_?]*");
|
||||
nickPattern = Pattern.compile(getNickRegex);
|
||||
isAllowRestrictedIp = load(RestrictionSettings.ENABLE_RESTRICTED_USERS);
|
||||
getRestrictedIp = load(RestrictionSettings.ALLOWED_RESTRICTED_USERS);
|
||||
isMovementAllowed = configFile.getBoolean("settings.restrictions.allowMovement", false);
|
||||
isRemoveSpeedEnabled = configFile.getBoolean("settings.restrictions.removeSpeed", true);
|
||||
getMovementRadius = configFile.getInt("settings.restrictions.allowedMovementRadius", 100);
|
||||
getJoinPermissions = configFile.getStringList("GroupOptions.Permissions.PermissionsOnJoin");
|
||||
isKickOnWrongPasswordEnabled = configFile.getBoolean("settings.restrictions.kickOnWrongPassword", false);
|
||||
isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered", false);
|
||||
isForceSingleSessionEnabled = configFile.getBoolean("settings.restrictions.ForceSingleSession", true);
|
||||
isForceSpawnLocOnJoinEnabled = configFile.getBoolean("settings.restrictions.ForceSpawnLocOnJoinEnabled", false);
|
||||
isRemoveSpeedEnabled = load(RestrictionSettings.REMOVE_SPEED);
|
||||
isForceSingleSessionEnabled = load(RestrictionSettings.FORCE_SINGLE_SESSION);
|
||||
isForceSpawnLocOnJoinEnabled = load(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN);
|
||||
isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation", false);
|
||||
isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode", false);
|
||||
getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp", 1);
|
||||
getPasswordHash = load(SecuritySettings.PASSWORD_HASH);
|
||||
getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP);
|
||||
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
|
||||
@ -122,18 +79,12 @@ public final class Settings {
|
||||
}
|
||||
|
||||
getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", "");
|
||||
enablePasswordConfirmation = load(RestrictionSettings.ENABLE_PASSWORD_CONFIRMATION);
|
||||
|
||||
protectInventoryBeforeLogInEnabled = load(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
||||
denyTabcompleteBeforeLogin = load(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN);
|
||||
hideTablistBeforeLogin = load(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN);
|
||||
|
||||
passwordMaxLength = load(SecuritySettings.MAX_PASSWORD_LENGTH);
|
||||
backupWindowsPath = configFile.getString("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||
isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
|
||||
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
|
||||
allowAllCommandsIfRegIsOptional = configFile.getBoolean("settings.restrictions.allowAllCommandsIfRegistrationIsOptional", false);
|
||||
allowAllCommandsIfRegIsOptional = load(RestrictionSettings.ALLOW_ALL_COMMANDS_IF_REGISTRATION_IS_OPTIONAL);
|
||||
allowCommands = new ArrayList<>();
|
||||
allowCommands.addAll(Arrays.asList("/login", "/l", "/register", "/reg", "/email", "/captcha"));
|
||||
for (String cmd : configFile.getStringList("settings.restrictions.allowCommands")) {
|
||||
@ -146,71 +97,20 @@ public final class Settings {
|
||||
rakamakUsers = configFile.getString("Converter.Rakamak.fileName", "users.rak");
|
||||
rakamakUsersIp = configFile.getString("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
rakamakUseIp = configFile.getBoolean("Converter.Rakamak.useIp", false);
|
||||
noConsoleSpam = load(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE);
|
||||
removePassword = configFile.getBoolean("Security.console.removePassword", true);
|
||||
getmailAccount = configFile.getString("Email.mailAccount", "");
|
||||
getMailPort = configFile.getInt("Email.mailPort", 465);
|
||||
getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
|
||||
displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
|
||||
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
|
||||
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
|
||||
emailRegistration = load(RegistrationSettings.USE_EMAIL_REGISTRATION);
|
||||
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
|
||||
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
|
||||
multiverse = load(HooksSettings.MULTIVERSE);
|
||||
bungee = configFile.getBoolean("Hooks.bungeecord", false);
|
||||
bungee = load(HooksSettings.BUNGEECORD);
|
||||
getForcedWorlds = configFile.getStringList("settings.restrictions.ForceSpawnOnTheseWorlds");
|
||||
banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false);
|
||||
doubleEmailCheck = configFile.getBoolean("settings.registration.doubleEmailCheck", false);
|
||||
sessionExpireOnIpChange = configFile.getBoolean("settings.sessions.sessionExpireOnIpChange", true);
|
||||
useLogging = configFile.getBoolean("Security.console.logConsole", false);
|
||||
disableSocialSpy = configFile.getBoolean("Hooks.disableSocialSpy", true);
|
||||
bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10);
|
||||
useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false);
|
||||
defaultWorld = configFile.getString("Purge.defaultWorld", "world");
|
||||
enableProtection = configFile.getBoolean("Protection.enableProtection", false);
|
||||
countries = configFile.getStringList("Protection.countries");
|
||||
forceCommands = configFile.getStringList("settings.forceCommands");
|
||||
forceCommandsAsConsole = configFile.getStringList("settings.forceCommandsAsConsole");
|
||||
recallEmail = configFile.getBoolean("Email.recallPlayers", false);
|
||||
useWelcomeMessage = load(RegistrationSettings.USE_WELCOME_MESSAGE);
|
||||
unsafePasswords = configFile.getStringList("settings.security.unsafePasswords");
|
||||
countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist");
|
||||
broadcastWelcomeMessage = load(RegistrationSettings.BROADCAST_WELCOME_MESSAGE);
|
||||
forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false);
|
||||
forceRegLogin = load(RegistrationSettings.FORCE_LOGIN_AFTER_REGISTER);
|
||||
spawnPriority = load(RestrictionSettings.SPAWN_PRIORITY);
|
||||
getMaxLoginPerIp = load(RestrictionSettings.MAX_LOGIN_PER_IP);
|
||||
getMaxJoinPerIp = load(RestrictionSettings.MAX_JOIN_PER_IP);
|
||||
checkVeryGames = load(HooksSettings.ENABLE_VERYGAMES_IP_CHECK);
|
||||
removeJoinMessage = load(RegistrationSettings.REMOVE_JOIN_MESSAGE);
|
||||
removeLeaveMessage = load(RegistrationSettings.REMOVE_LEAVE_MESSAGE);
|
||||
delayJoinMessage = load(RegistrationSettings.DELAY_JOIN_MESSAGE);
|
||||
noTeleport = load(RestrictionSettings.NO_TELEPORT);
|
||||
crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
|
||||
forceRegisterCommands = configFile.getStringList("settings.forceRegisterCommands");
|
||||
forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole");
|
||||
customAttributes = configFile.getBoolean("Hooks.customAttributes");
|
||||
preventOtherCase = configFile.getBoolean("settings.preventOtherCase", false);
|
||||
kickPlayersBeforeStopping = configFile.getBoolean("Security.stop.kickPlayersBeforeStopping", true);
|
||||
sendPlayerTo = configFile.getString("Hooks.sendPlayerTo", "");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method switchAntiBotMod.
|
||||
*
|
||||
* @param mode boolean
|
||||
*/
|
||||
public static void switchAntiBotMod(boolean mode) {
|
||||
if (mode) {
|
||||
isKickNonRegisteredEnabled = true;
|
||||
antiBotInAction = true;
|
||||
} else {
|
||||
isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered", false);
|
||||
antiBotInAction = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -59,7 +59,7 @@ public class SettingsMigrationService {
|
||||
private static boolean hasDeprecatedProperties(FileConfiguration configuration) {
|
||||
String[] deprecatedProperties = {
|
||||
"Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications",
|
||||
"Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt"};
|
||||
"Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt", "VeryGames"};
|
||||
for (String deprecatedPath : deprecatedProperties) {
|
||||
if (configuration.contains(deprecatedPath)) {
|
||||
return true;
|
||||
|
||||
@ -35,10 +35,6 @@ public class HooksSettings implements SettingsClass {
|
||||
public static final Property<Boolean> CACHE_CUSTOM_ATTRIBUTES =
|
||||
newProperty("Hooks.customAttributes", false);
|
||||
|
||||
@Comment("These features are only available on VeryGames Server Provider")
|
||||
public static final Property<Boolean> ENABLE_VERYGAMES_IP_CHECK =
|
||||
newProperty("VeryGames.enableIpCheck", false);
|
||||
|
||||
@Comment({
|
||||
"-1 means disabled. If you want that only activated players",
|
||||
"can log into your server, you can set here the group number",
|
||||
|
||||
@ -53,6 +53,12 @@ public class PluginSettings implements SettingsClass {
|
||||
public static final Property<Boolean> ENABLE_PERMISSION_CHECK =
|
||||
newProperty("permission.EnablePermissionCheck", false);
|
||||
|
||||
@Comment({
|
||||
"Keeps collisions disabled for logged players",
|
||||
"Works only with MC 1.9"
|
||||
})
|
||||
public static final Property<Boolean> KEEP_COLLISIONS_DISABLED =
|
||||
newProperty("settings.restrictions.keepCollisionsDisabled", false);
|
||||
|
||||
private PluginSettings() {
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ public class RegistrationSettings implements SettingsClass {
|
||||
newListProperty("settings.forceRegisterCommandsAsConsole");
|
||||
|
||||
@Comment({
|
||||
"Enable to display the welcome message (welcome.txt) after a registration or a login",
|
||||
"Enable to display the welcome message (welcome.txt) after 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",
|
||||
|
||||
@ -12,15 +12,19 @@ import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
public class RestrictionSettings implements SettingsClass {
|
||||
|
||||
@Comment({
|
||||
"Can not authenticated players chat and see the chat log?",
|
||||
"Can not authenticated players chat?",
|
||||
"Keep in mind that this feature also blocks all commands not",
|
||||
"listed in the list below."})
|
||||
public static final Property<Boolean> ALLOW_CHAT =
|
||||
newProperty("settings.restrictions.allowChat", false);
|
||||
|
||||
@Comment("Hide the chat log from players who are not authenticated?")
|
||||
public static final Property<Boolean> HIDE_CHAT =
|
||||
newProperty("settings.restrictions.hideChat", false);
|
||||
|
||||
@Comment({
|
||||
"Allow unlogged users to use all the commands if registration is not forced!",
|
||||
"WARNING: use this only if you need it!)"})
|
||||
"WARNING: use this only if you need it!"})
|
||||
public static final Property<Boolean> ALLOW_ALL_COMMANDS_IF_REGISTRATION_IS_OPTIONAL =
|
||||
newProperty("settings.restrictions.allowAllCommandsIfRegistrationIsOptional", false);
|
||||
|
||||
@ -29,8 +33,9 @@ public class RestrictionSettings implements SettingsClass {
|
||||
newListProperty("settings.restrictions.allowCommands",
|
||||
"login", "register", "l", "reg", "email", "captcha");
|
||||
|
||||
@Comment("Max number of allowed registrations per IP")
|
||||
// TODO ljacqu 20160109: If 0 == unlimited, add this fact to the comment
|
||||
@Comment({
|
||||
"Max number of allowed registrations per IP",
|
||||
"The value 0 means an unlimited number of registrations!"})
|
||||
public static final Property<Integer> MAX_REGISTRATION_PER_IP =
|
||||
newProperty("settings.restrictions.maxRegPerIp", 1);
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ public final class SettingsFieldRetriever {
|
||||
for (Class<?> clazz : CONFIGURATION_CLASSES) {
|
||||
Field[] declaredFields = clazz.getDeclaredFields();
|
||||
for (Field field : declaredFields) {
|
||||
Property property = getPropertyField(field);
|
||||
Property<?> property = getPropertyField(field);
|
||||
if (property != null) {
|
||||
properties.put(property, getCommentsForField(field));
|
||||
}
|
||||
@ -64,7 +64,7 @@ public final class SettingsFieldRetriever {
|
||||
field.setAccessible(true);
|
||||
if (field.isAccessible() && Property.class.equals(field.getType()) && Modifier.isStatic(field.getModifiers())) {
|
||||
try {
|
||||
return (Property) field.get(null);
|
||||
return (Property<?>) field.get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Could not fetch field '" + field.getName() + "' from class '"
|
||||
+ field.getDeclaringClass().getSimpleName() + "': " + StringUtils.formatException(e));
|
||||
|
||||
@ -31,7 +31,7 @@ public class PropertyMap {
|
||||
* @param property The property to add
|
||||
* @param comments The comments associated to the property
|
||||
*/
|
||||
public void put(Property property, String[] comments) {
|
||||
public void put(Property<?> property, String[] comments) {
|
||||
comparator.add(property);
|
||||
map.put(property, comments);
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import java.util.Comparator;
|
||||
* property, then "DataSource" properties will come before the "security" ones.</li>
|
||||
* </ul>
|
||||
*/
|
||||
final class PropertyMapComparator implements Comparator<Property> {
|
||||
final class PropertyMapComparator implements Comparator<Property<?>> {
|
||||
|
||||
private Node parent = Node.createRoot();
|
||||
|
||||
@ -22,12 +22,12 @@ final class PropertyMapComparator implements Comparator<Property> {
|
||||
*
|
||||
* @param property The property that is being added
|
||||
*/
|
||||
public void add(Property property) {
|
||||
public void add(Property<?> property) {
|
||||
parent.addNode(property.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Property p1, Property p2) {
|
||||
public int compare(Property<?> p1, Property<?> p2) {
|
||||
return parent.compare(p1.getPath(), p2.getPath());
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package fr.xephi.authme.task;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
@ -12,28 +12,27 @@ import org.bukkit.scheduler.BukkitTask;
|
||||
*/
|
||||
public class MessageTask implements Runnable {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final BukkitService bukkitService;
|
||||
private final String name;
|
||||
private final String[] msg;
|
||||
private final int interval;
|
||||
|
||||
/**
|
||||
* Constructor for MessageTask.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
* @param name String
|
||||
* @param lines String[]
|
||||
* @param interval int
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public MessageTask(AuthMe plugin, String name, String[] lines, int interval) {
|
||||
this.plugin = plugin;
|
||||
public MessageTask(BukkitService bukkitService, String name, String[] lines, int interval) {
|
||||
this.bukkitService = bukkitService;
|
||||
this.name = name;
|
||||
this.msg = lines;
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public MessageTask(AuthMe plugin, String name, MessageKey messageKey, int interval) {
|
||||
this(plugin, name, plugin.getMessages().retrieve(messageKey), interval);
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public MessageTask(BukkitService bukkitService, Messages messages, String name, MessageKey messageKey,
|
||||
int interval) {
|
||||
this(bukkitService, name, messages.retrieve(messageKey), interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,12 +41,12 @@ public class MessageTask implements Runnable {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
for (Player player : bukkitService.getOnlinePlayers()) {
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
for (String ms : msg) {
|
||||
player.sendMessage(ms);
|
||||
}
|
||||
BukkitTask nextTask = plugin.getServer().getScheduler().runTaskLater(plugin, this, interval * 20);
|
||||
BukkitTask nextTask = bukkitService.runTaskLater(this, interval * 20);
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTask(nextTask);
|
||||
}
|
||||
|
||||
@ -1,7 +1,18 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Service for operations requiring server entities, such as for scheduling.
|
||||
@ -14,9 +25,12 @@ public class BukkitService {
|
||||
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
|
||||
|
||||
private final AuthMe authMe;
|
||||
private final boolean getOnlinePlayersIsCollection;
|
||||
private Method getOnlinePlayers;
|
||||
|
||||
public BukkitService(AuthMe authMe) {
|
||||
this.authMe = authMe;
|
||||
getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,6 +58,47 @@ public class BukkitService {
|
||||
return Bukkit.getScheduler().scheduleSyncDelayedTask(authMe, task, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a task that will run on the next server tick.
|
||||
*
|
||||
* @param task the task to be run
|
||||
* @return a BukkitTask that contains the id number
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalArgumentException if task is null
|
||||
*/
|
||||
public BukkitTask runTask(Runnable task) {
|
||||
return Bukkit.getScheduler().runTask(authMe, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a task that will run after the specified number of server
|
||||
* ticks.
|
||||
*
|
||||
* @param task the task to be run
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @return a BukkitTask that contains the id number
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalArgumentException if task is null
|
||||
*/
|
||||
public BukkitTask runTaskLater(Runnable task, long delay) {
|
||||
return Bukkit.getScheduler().runTaskLater(authMe, task, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Returns a task that will run asynchronously.
|
||||
*
|
||||
* @param task the task to be run
|
||||
* @return a BukkitTask that contains the id number
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalArgumentException if task is null
|
||||
*/
|
||||
public BukkitTask runTaskAsynchronously(Runnable task) {
|
||||
return Bukkit.getScheduler().runTaskAsynchronously(authMe, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players.
|
||||
*
|
||||
@ -54,4 +109,76 @@ public class BukkitService {
|
||||
return Bukkit.broadcastMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player with the exact given name, case insensitive.
|
||||
*
|
||||
* @param name Exact name of the player to retrieve
|
||||
* @return a player object if one was found, null otherwise
|
||||
*/
|
||||
public Player getPlayerExact(String name) {
|
||||
return authMe.getServer().getPlayerExact(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set containing all banned players.
|
||||
*
|
||||
* @return a set containing banned players
|
||||
*/
|
||||
public Set<OfflinePlayer> getBannedPlayers() {
|
||||
return Bukkit.getBannedPlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe way to retrieve the list of online players from the server. Depending on the
|
||||
* implementation of the server, either an array of {@link Player} instances is being returned,
|
||||
* or a Collection. Always use this wrapper to retrieve online players instead of {@link
|
||||
* Bukkit#getOnlinePlayers()} directly.
|
||||
*
|
||||
* @return collection of online players
|
||||
*
|
||||
* @see <a href="https://www.spigotmc.org/threads/solved-cant-use-new-getonlineplayers.33061/">SpigotMC
|
||||
* forum</a>
|
||||
* @see <a href="http://stackoverflow.com/questions/32130851/player-changed-from-array-to-collection">StackOverflow</a>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<? extends Player> getOnlinePlayers() {
|
||||
if (getOnlinePlayersIsCollection) {
|
||||
return Bukkit.getOnlinePlayers();
|
||||
}
|
||||
try {
|
||||
// The lookup of a method via Reflections is rather expensive, so we keep a reference to it
|
||||
if (getOnlinePlayers == null) {
|
||||
getOnlinePlayers = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
|
||||
}
|
||||
Object obj = getOnlinePlayers.invoke(null);
|
||||
if (obj instanceof Collection<?>) {
|
||||
return (Collection<? extends Player>) obj;
|
||||
} else if (obj instanceof Player[]) {
|
||||
return Arrays.asList((Player[]) obj);
|
||||
} else {
|
||||
String type = (obj != null) ? obj.getClass().getName() : "null";
|
||||
ConsoleLogger.showError("Unknown list of online players of type " + type);
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
ConsoleLogger.logException("Could not retrieve list of online players:", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run upon initialization to verify whether or not the Bukkit implementation
|
||||
* returns the online players as a Collection.
|
||||
*
|
||||
* @see #getOnlinePlayers()
|
||||
*/
|
||||
private static boolean initializeOnlinePlayersIsCollectionField() {
|
||||
try {
|
||||
Method method = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
|
||||
return method.getReturnType() == Collection.class;
|
||||
} catch (NoSuchMethodException e) {
|
||||
ConsoleLogger.showError("Error verifying if getOnlinePlayers is a collection! Method doesn't exist");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import com.maxmind.geoip.LookupService;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -37,7 +37,8 @@ public class GeoLiteAPI {
|
||||
if (lookupService != null) {
|
||||
return true;
|
||||
}
|
||||
final File data = new File(Settings.PLUGIN_FOLDER, "GeoIP.dat");
|
||||
final File pluginFolder = AuthMe.getInstance().getDataFolder();
|
||||
final File data = new File(pluginFolder, "GeoIP.dat");
|
||||
boolean dataIsOld = (System.currentTimeMillis() - data.lastModified()) > TimeUnit.DAYS.toMillis(30);
|
||||
if (dataIsOld && !data.delete()) {
|
||||
ConsoleLogger.showError("Failed to delete GeoLiteAPI database");
|
||||
|
||||
@ -37,12 +37,17 @@ public final class MigrationService {
|
||||
if (HashAlgorithm.PLAINTEXT == settings.getProperty(SecuritySettings.PASSWORD_HASH)) {
|
||||
ConsoleLogger.showError("Your HashAlgorithm has been detected as plaintext and is now deprecated;"
|
||||
+ " it will be changed and hashed now to the AuthMe default hashing method");
|
||||
ConsoleLogger.showError("Don't stop your server; wait for the conversion to have been completed!");
|
||||
List<PlayerAuth> allAuths = dataSource.getAllAuths();
|
||||
for (PlayerAuth auth : allAuths) {
|
||||
HashedPassword hashedPassword = authmeSha256.computeHash(
|
||||
auth.getPassword().getHash(), auth.getNickname());
|
||||
auth.setPassword(hashedPassword);
|
||||
dataSource.updatePassword(auth);
|
||||
String hash = auth.getPassword().getHash();
|
||||
if (hash.startsWith("$SHA$")) {
|
||||
ConsoleLogger.showError("Skipping conversion for " + auth.getNickname() + "; detected SHA hash");
|
||||
} else {
|
||||
HashedPassword hashedPassword = authmeSha256.computeHash(hash, auth.getNickname());
|
||||
auth.setPassword(hashedPassword);
|
||||
dataSource.updatePassword(auth);
|
||||
}
|
||||
}
|
||||
settings.setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
|
||||
settings.save();
|
||||
|
||||
@ -7,41 +7,23 @@ import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.events.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class for various operations used in the codebase.
|
||||
*/
|
||||
public final class Utils {
|
||||
|
||||
private static AuthMe plugin;
|
||||
private static Wrapper wrapper;
|
||||
|
||||
private static boolean getOnlinePlayersIsCollection = false;
|
||||
private static Method getOnlinePlayers;
|
||||
|
||||
static {
|
||||
wrapper = Wrapper.getInstance();
|
||||
plugin = wrapper.getAuthMe();
|
||||
initializeOnlinePlayersIsCollectionField();
|
||||
}
|
||||
private static AuthMe plugin = AuthMe.getInstance();
|
||||
|
||||
private Utils() {
|
||||
// Utility class
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,12 +152,12 @@ public final class Utils {
|
||||
final World world = theWorld;
|
||||
final Location loc = new Location(world, x, y, z);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(wrapper.getAuthMe(), new Runnable() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(pl, loc);
|
||||
wrapper.getServer().getPluginManager().callEvent(tpEvent);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
pl.teleport(tpEvent.getTo());
|
||||
}
|
||||
@ -183,62 +165,6 @@ public final class Utils {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe way to retrieve the list of online players from the server. Depending on the
|
||||
* implementation of the server, either an array of {@link Player} instances is being returned,
|
||||
* or a Collection. Always use this wrapper to retrieve online players instead of {@link
|
||||
* Bukkit#getOnlinePlayers()} directly.
|
||||
*
|
||||
* @return collection of online players
|
||||
*
|
||||
* @see <a href="https://www.spigotmc.org/threads/solved-cant-use-new-getonlineplayers.33061/">SpigotMC
|
||||
* forum</a>
|
||||
* @see <a href="http://stackoverflow.com/questions/32130851/player-changed-from-array-to-collection">StackOverflow</a>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Collection<? extends Player> getOnlinePlayers() {
|
||||
if (getOnlinePlayersIsCollection) {
|
||||
return Bukkit.getOnlinePlayers();
|
||||
}
|
||||
try {
|
||||
// The lookup of a method via Reflections is rather expensive, so we keep a reference to it
|
||||
if (getOnlinePlayers == null) {
|
||||
getOnlinePlayers = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
|
||||
}
|
||||
Object obj = getOnlinePlayers.invoke(null);
|
||||
if (obj instanceof Collection<?>) {
|
||||
return (Collection<? extends Player>) obj;
|
||||
} else if (obj instanceof Player[]) {
|
||||
return Arrays.asList((Player[]) obj);
|
||||
} else {
|
||||
String type = (obj != null) ? obj.getClass().getName() : "null";
|
||||
ConsoleLogger.showError("Unknown list of online players of type " + type);
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
ConsoleLogger.logException("Could not retrieve list of online players:", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run when the Utils class is loaded to verify whether or not the Bukkit implementation
|
||||
* returns the online players as a Collection.
|
||||
*
|
||||
* @see Utils#getOnlinePlayers()
|
||||
*/
|
||||
private static void initializeOnlinePlayersIsCollectionField() {
|
||||
try {
|
||||
Method method = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
|
||||
getOnlinePlayersIsCollection = method.getReturnType() == Collection.class;
|
||||
} catch (NoSuchMethodException e) {
|
||||
ConsoleLogger.showError("Error verifying if getOnlinePlayers is a collection! Method doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
public static Player getPlayer(String name) {
|
||||
return wrapper.getServer().getPlayerExact(name);
|
||||
}
|
||||
|
||||
public static boolean isNPC(Player player) {
|
||||
return player.hasMetadata("NPC") || plugin.getPluginHooks().isNpcInCombatTagPlus(player);
|
||||
}
|
||||
@ -247,45 +173,19 @@ public final class Utils {
|
||||
if (Settings.isTeleportToSpawnEnabled && !Settings.noTeleport) {
|
||||
Location spawn = plugin.getSpawnLocation(player);
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, spawn);
|
||||
wrapper.getServer().getPluginManager().callEvent(tpEvent);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEmailCorrect(String email, NewSetting settings) {
|
||||
if (!email.contains("@") || "your@email.com".equalsIgnoreCase(email)) {
|
||||
return false;
|
||||
}
|
||||
final String emailDomain = email.split("@")[1];
|
||||
|
||||
List<String> whitelist = settings.getProperty(EmailSettings.DOMAIN_WHITELIST);
|
||||
if (!CollectionUtils.isEmpty(whitelist)) {
|
||||
return containsIgnoreCase(whitelist, emailDomain);
|
||||
}
|
||||
|
||||
List<String> blacklist = settings.getProperty(EmailSettings.DOMAIN_BLACKLIST);
|
||||
return CollectionUtils.isEmpty(blacklist) || !containsIgnoreCase(blacklist, emailDomain);
|
||||
}
|
||||
|
||||
private static boolean containsIgnoreCase(Collection<String> coll, String needle) {
|
||||
for (String entry : coll) {
|
||||
if (entry.equalsIgnoreCase(needle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getUUIDorName(OfflinePlayer player) {
|
||||
String uuidOrName;
|
||||
try {
|
||||
uuidOrName = player.getUniqueId().toString();
|
||||
return player.getUniqueId().toString();
|
||||
} catch (Exception ignore) {
|
||||
uuidOrName = player.getName();
|
||||
return player.getName();
|
||||
}
|
||||
return uuidOrName;
|
||||
}
|
||||
|
||||
public enum GroupType {
|
||||
@ -294,4 +194,15 @@ public final class Utils {
|
||||
NOTLOGGEDIN,
|
||||
LOGGEDIN
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP of the given player.
|
||||
*
|
||||
* @param p The player to return the IP address for
|
||||
*
|
||||
* @return The player's IP address
|
||||
*/
|
||||
public static String getPlayerIp(Player p) {
|
||||
return p.getAddress().getAddress().getHostAddress();
|
||||
}
|
||||
}
|
||||
|
||||
133
src/main/java/fr/xephi/authme/util/ValidationService.java
Normal file
133
src/main/java/fr/xephi/authme/util/ValidationService.java
Normal file
@ -0,0 +1,133 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Validation service.
|
||||
*/
|
||||
public class ValidationService {
|
||||
|
||||
private final NewSetting settings;
|
||||
private final DataSource dataSource;
|
||||
private final PermissionsManager permissionsManager;
|
||||
|
||||
public ValidationService(NewSetting settings, DataSource dataSource, PermissionsManager permissionsManager) {
|
||||
this.settings = settings;
|
||||
this.dataSource = dataSource;
|
||||
this.permissionsManager = permissionsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether a password is valid according to the plugin settings.
|
||||
*
|
||||
* @param password the password to verify
|
||||
* @param username the username the password is associated with
|
||||
* @return message key with the password error, or {@code null} if password is valid
|
||||
*/
|
||||
public MessageKey validatePassword(String password, String username) {
|
||||
String passLow = password.toLowerCase();
|
||||
if (!passLow.matches(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX))) {
|
||||
return MessageKey.PASSWORD_MATCH_ERROR;
|
||||
} else if (passLow.equalsIgnoreCase(username)) {
|
||||
return MessageKey.PASSWORD_IS_USERNAME_ERROR;
|
||||
} else if (password.length() < settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|
||||
|| password.length() > settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
|
||||
return MessageKey.INVALID_PASSWORD_LENGTH;
|
||||
} else if (settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(passLow)) {
|
||||
// TODO #602 20160312: The UNSAFE_PASSWORDS should be all lowercase
|
||||
// -> introduce a lowercase String list property type
|
||||
return MessageKey.PASSWORD_UNSAFE_ERROR;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the email is valid and admitted for use according to the plugin settings.
|
||||
*
|
||||
* @param email the email to verify
|
||||
* @return true if the email is valid, false otherwise
|
||||
*/
|
||||
public boolean validateEmail(String email) {
|
||||
if (!email.contains("@") || "your@email.com".equalsIgnoreCase(email)) {
|
||||
return false;
|
||||
}
|
||||
final String emailDomain = email.split("@")[1];
|
||||
return validateWhitelistAndBlacklist(
|
||||
emailDomain, EmailSettings.DOMAIN_WHITELIST, EmailSettings.DOMAIN_BLACKLIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the database whether the email is still free for registration, i.e. whether the given
|
||||
* command sender may use the email to register a new account (as defined by settings and permissions).
|
||||
*
|
||||
* @param email the email to verify
|
||||
* @param sender the command sender
|
||||
* @return true if the email may be used, false otherwise (registration threshold has been exceeded)
|
||||
*/
|
||||
public boolean isEmailFreeForRegistration(String email, CommandSender sender) {
|
||||
return permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
|| dataSource.countAuthsByEmail(email) < settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the player's country is allowed to join the server, based on the given IP address
|
||||
* and the configured country whitelist or blacklist.
|
||||
*
|
||||
* @param hostAddress the IP address to verify
|
||||
* @return true if the IP address' country is allowed, false otherwise
|
||||
*/
|
||||
public boolean isCountryAdmitted(String hostAddress) {
|
||||
// Check if we have restrictions on country, if not return true and avoid the country lookup
|
||||
if (settings.getProperty(ProtectionSettings.COUNTRIES_WHITELIST).isEmpty()
|
||||
&& settings.getProperty(ProtectionSettings.COUNTRIES_BLACKLIST).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String countryCode = GeoLiteAPI.getCountryCode(hostAddress);
|
||||
return validateWhitelistAndBlacklist(countryCode,
|
||||
ProtectionSettings.COUNTRIES_WHITELIST,
|
||||
ProtectionSettings.COUNTRIES_BLACKLIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the given value is allowed according to the given whitelist and blacklist settings.
|
||||
* Whitelist has precedence over blacklist: if a whitelist is set, the value is rejected if not present
|
||||
* in the whitelist.
|
||||
*
|
||||
* @param value the value to verify
|
||||
* @param whitelist the whitelist property
|
||||
* @param blacklist the blacklist property
|
||||
* @return true if the value is admitted by the lists, false otherwise
|
||||
*/
|
||||
private boolean validateWhitelistAndBlacklist(String value, Property<List<String>> whitelist,
|
||||
Property<List<String>> blacklist) {
|
||||
List<String> whitelistValue = settings.getProperty(whitelist);
|
||||
if (!CollectionUtils.isEmpty(whitelistValue)) {
|
||||
return containsIgnoreCase(whitelistValue, value);
|
||||
}
|
||||
List<String> blacklistValue = settings.getProperty(blacklist);
|
||||
return CollectionUtils.isEmpty(blacklistValue) || !containsIgnoreCase(blacklistValue, value);
|
||||
}
|
||||
|
||||
private static boolean containsIgnoreCase(Collection<String> coll, String needle) {
|
||||
for (String entry : coll) {
|
||||
if (entry.equalsIgnoreCase(needle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Wrapper for the retrieval of common singletons used throughout the application.
|
||||
* This class simply delegates the calls.
|
||||
*/
|
||||
public class Wrapper {
|
||||
|
||||
private static Wrapper singleton;
|
||||
|
||||
/**
|
||||
* Package-private constructor for testing purposes to inject a mock instance.
|
||||
*/
|
||||
Wrapper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-private setter of the singleton field used for tests to inject a mock instance.
|
||||
*
|
||||
* @param wrapper The wrapper to use as singleton
|
||||
*/
|
||||
static void setSingleton(Wrapper wrapper) {
|
||||
Wrapper.singleton = wrapper;
|
||||
}
|
||||
|
||||
public static Wrapper getInstance() {
|
||||
if (singleton == null) {
|
||||
singleton = new Wrapper();
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public AuthMe getAuthMe() {
|
||||
return AuthMe.getInstance();
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return getAuthMe().getServer();
|
||||
}
|
||||
|
||||
public Messages getMessages() {
|
||||
return getAuthMe().getMessages();
|
||||
}
|
||||
|
||||
public PlayerCache getPlayerCache() {
|
||||
return PlayerCache.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the folder containing plugin data via the AuthMe instance.
|
||||
*
|
||||
* @return The plugin data folder
|
||||
* @see AuthMe#getDataFolder()
|
||||
*/
|
||||
public File getDataFolder() {
|
||||
return getAuthMe().getDataFolder();
|
||||
}
|
||||
|
||||
public BukkitScheduler getScheduler() {
|
||||
return Bukkit.getScheduler();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -67,6 +67,8 @@ settings:
|
||||
# Care that this feature blocks also all the commands not
|
||||
# listed in the list below.
|
||||
allowChat: false
|
||||
# Can not authenticated players see the chat log?
|
||||
hideChat: false
|
||||
# WARNING: use this only if you need it!
|
||||
# Allow unlogged users to use all the commands if registration is not forced!
|
||||
allowAllCommandsIfRegistrationIsOptional: false
|
||||
@ -159,6 +161,9 @@ settings:
|
||||
noTeleport: false
|
||||
# Regex syntax for allowed Chars in passwords.
|
||||
allowedPasswordCharacters: '[\x21-\x7E]*'
|
||||
# Keeps collisions disabled for logged players
|
||||
# Works only with MC 1.9
|
||||
keepCollisionsDisabled: false
|
||||
GameMode:
|
||||
# ForceSurvivalMode to player when join ?
|
||||
ForceSurvivalMode: false
|
||||
@ -248,11 +253,11 @@ settings:
|
||||
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
|
||||
# Do we need to display the welcome message (welcome.txt) after 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
|
||||
@ -418,6 +423,3 @@ Protection:
|
||||
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,30 +1,30 @@
|
||||
unknown_user: '&cBenutzer ist nicht in der Datenbank'
|
||||
unsafe_spawn: '&cDeine Logoutposition war unsicher, Du wurdest zum Spawn teleportiert'
|
||||
unsafe_spawn: '&cDeine Logoutposition war unsicher, du wurdest zum Spawn teleportiert'
|
||||
not_logged_in: '&cNicht eingeloggt!'
|
||||
reg_voluntarily: 'Du kannst dich mit folgendem Befehl registrieren "/register <passwort> <passwortBestätigen>"'
|
||||
reg_voluntarily: 'Du kannst dich mit folgendem Befehl registrieren: "/register <passwort> <passwortBestätigen>"'
|
||||
usage_log: '&cBenutze: /login <passwort>'
|
||||
wrong_pwd: '&cFalsches Passwort'
|
||||
unregistered: '&cBenutzerkonto erfolgreich gelöscht!'
|
||||
reg_disabled: '&cRegistrierungen sind deaktiviert'
|
||||
valid_session: '&2Erfolgreich eingeloggt!'
|
||||
login: '&2Erfolgreich eingeloggt!'
|
||||
vb_nonActiv: '&cDein Account wurde noch nicht aktiviert. Bitte prüfe Deine E-Mails!'
|
||||
vb_nonActiv: '&cDein Account wurde noch nicht aktiviert. Bitte prüfe deine E-Mails!'
|
||||
user_regged: '&cDieser Benutzername ist schon vergeben'
|
||||
usage_reg: '&cBenutze: /register <passwort> <passwortBestätigen>'
|
||||
max_reg: '&cDu hast die maximale Anzahl an Accounts erreicht.'
|
||||
max_reg: '&cDu hast die maximale Anzahl an Accounts erreicht (%max_acc/%reg_count).'
|
||||
no_perm: '&4Du hast keine Rechte, um diese Aktion auszuführen!'
|
||||
error: '&4Ein Fehler ist aufgetreten. Bitte kontaktiere einen Administrator.'
|
||||
login_msg: '&cBitte logge Dich ein mit "/login <passwort>"'
|
||||
reg_msg: '&3Bitte registriere Dich mit "/register <passwort> <passwortBestätigen>"'
|
||||
reg_email_msg: '&3Bitte registriere Dich mit "/register <email> <emailBestätigen>"'
|
||||
login_msg: '&cBitte logge dich ein mit "/login <passwort>"'
|
||||
reg_msg: '&3Bitte registriere dich mit "/register <passwort> <passwortBestätigen>"'
|
||||
reg_email_msg: '&3Bitte registriere dich mit "/register <email> <emailBestätigen>"'
|
||||
usage_unreg: '&cBenutze: /unregister <passwort>'
|
||||
pwd_changed: '&2Passwort geändert!'
|
||||
user_unknown: '&cBenutzername nicht registriert!'
|
||||
password_error: '&cPasswörter stimmen nicht überein!'
|
||||
password_error_nick: '&cDu kannst nicht Deinen Namen als Passwort nutzen!'
|
||||
password_error_unsafe: '&cDu kannst nicht unsichere Passwörter nutzen!'
|
||||
invalid_session: '&cUngültige Session. Bitte starte das Spiel neu oder warte, bis die Session abgelaufen ist'
|
||||
reg_only: '&4Nur für registrierte Spieler! Bitte besuche http://example.com zum Registrieren'
|
||||
password_error_nick: '&cDu kannst deinen Namen nicht als Passwort verwenden!'
|
||||
password_error_unsafe: '&cPasswort unsicher! Bitte wähle ein anderes.'
|
||||
invalid_session: '&cUngültige Session. Bitte starte das Spiel neu oder warte, bis die Session abgelaufen ist.'
|
||||
reg_only: '&4Nur für registrierte Spieler! Bitte besuche http://example.com um dich zu registrieren.'
|
||||
logged_in: '&cBereits eingeloggt!'
|
||||
logout: '&2Erfolgreich ausgeloggt'
|
||||
same_nick: '&4Jemand mit diesem Namen spielt bereits auf dem Server!'
|
||||
@ -34,8 +34,8 @@ reload: '&2Konfiguration und Datenbank wurden erfolgreich neu geladen.'
|
||||
timeout: '&4Zeitüberschreitung beim Login'
|
||||
usage_changepassword: '&cBenutze: /changepassword <altesPasswort> <neuesPasswort>'
|
||||
name_len: '&4Dein Nickname ist zu kurz oder zu lang.'
|
||||
regex: '&4Dein Nickname enthält nicht erlaubte Zeichen. Zulässige Zeichen: REG_EX'
|
||||
add_email: '&3Bitte hinterlege Deine E-Mail-Adresse: /email add <deineEmail> <emailBestätigen>'
|
||||
regex: '&4Dein Nickname enthält unerlaubte Zeichen. Zulässige Zeichen: REG_EX'
|
||||
add_email: '&3Bitte hinterlege deine E-Mail-Adresse: /email add <deineEmail> <emailBestätigen>'
|
||||
recovery_email: '&3Passwort vergessen? Nutze "/email recovery <deineEmail>" für ein neues Passwort'
|
||||
usage_captcha: '&3Um dich einzuloggen, tippe dieses Captcha so ein: /captcha <theCaptcha>'
|
||||
wrong_captcha: '&cFalsches Captcha, bitte nutze: /captcha THE_CAPTCHA'
|
||||
@ -49,14 +49,14 @@ new_email_invalid: '&cDie neue E-Mail ist ungültig!'
|
||||
old_email_invalid: '&cDie alte E-Mail ist ungültig!'
|
||||
email_invalid: '&cUngültige E-Mail!'
|
||||
email_added: '&2E-Mail hinzugefügt!'
|
||||
email_confirm: '&cBitte bestätige Deine E-Mail!'
|
||||
email_confirm: '&cBitte bestätige deine E-Mail!'
|
||||
email_changed: '&2E-Mail aktualisiert!'
|
||||
email_send: '&2Wiederherstellungs-E-Mail wurde gesendet!'
|
||||
email_exists: '&cEine Wiederherstellungs-E-Mail wurde bereits versandt! Nutze folgenden Befehl um eine neue E-Mail zu versenden:'
|
||||
country_banned: '&4Dein Land ist gesperrt!'
|
||||
antibot_auto_enabled: '&4[AntiBotService] AntiBotMod wurde aufgrund hoher Netzauslastung automatisch aktiviert!'
|
||||
antibot_auto_disabled: '&2[AntiBotService] AntiBotMod wurde nach %m Minuten deaktiviert, hoffentlich ist die Invasion vorbei.'
|
||||
kick_antibot: 'AntiBotMod ist aktiviert! Bitte warte einige Minuten, bevor Du Dich mit dem Server verbindest.'
|
||||
kick_antibot: 'AntiBotMod ist aktiviert! Bitte warte einige Minuten, bevor du dich mit dem Server verbindest.'
|
||||
two_factor_create: '&2Dein geheimer Code ist %code. Du kannst ihn hier abfragen: %url'
|
||||
email_already_used: '&4Diese E-Mail-Adresse wird bereits genutzt.'
|
||||
invalid_name_case: 'Dein registrierter Benutzername ist &2%valid&f - nicht &4%invalid&f.'
|
||||
|
||||
@ -1,50 +1,50 @@
|
||||
reg_only: Csak regisztrált játékosoknak! Jelentkezni a mail@email.com e-mail címen lehet
|
||||
usage_unreg: '&cHasználat: /unregister jelszó'
|
||||
registered: '&aSikeres regisztráció. Üdvözöllek!'
|
||||
user_regged: '&cJátékosnév már regisztrálva'
|
||||
login_msg: '&cKérlek jelentkezz be: "/login jelszó"'
|
||||
reg_only: '&4Csak regisztrált játékosok tudnak csatlakozni a szerverhez! Kérlek kattints a http://example.com weboldalra és regisztráld magad!'
|
||||
usage_unreg: '&cHasználat: "/unregister <jelszó>"'
|
||||
registered: '&aSikeres regisztráció.'
|
||||
user_regged: '&cEz a játékosnév már regisztrálva van!'
|
||||
login_msg: '&cKérlek jelentkezz be: "/login <jelszó>"'
|
||||
not_logged_in: '&cNem vagy bejelentkezve!'
|
||||
logout: '&cSikeresen kijelentkeztél!'
|
||||
usage_log: '&cBejelentkezés: /login <jelszó>'
|
||||
unknown_user: '&cA kért felhasználó nem telálható az adatbázisban!'
|
||||
reg_voluntarily: Regisztrálhatod magad a szerveren a következö parancsal "/register <jelszó> <jelszó újra>"
|
||||
usage_log: '&cBejelentkezés: "/login <jelszó>"'
|
||||
unknown_user: '&cA kért felhasználó nem található az adatbázisban!'
|
||||
reg_voluntarily: Regisztrálhatod magad a szerveren a következö parancsal "/register <jelszó> <jelszó ismét>"
|
||||
reg_disabled: '&cRegisztráció letiltva!'
|
||||
no_perm: '&cNincs jogod ehhez!'
|
||||
usage_reg: '&cHasználat: /register <jelszó> <jelszó újra>'
|
||||
usage_reg: '&cHasználat: "/register <jelszó> <jelszó ismét>"'
|
||||
password_error_nick: '&cNem használhatod a felhasználóneved jelszónak, kérlek válassz másikat...'
|
||||
password_error_unsafe: '&cA választott jelszó nem biztonságos, kérlek válassz másikat...'
|
||||
unregistered: '&cRegisztráció sikeresen törölve!'
|
||||
same_nick: 'Ezzel a játékosnévvel már játszanak a szerveren.'
|
||||
valid_session: '&2A hálózati kapcsolat újraépítése megtörtént.'
|
||||
valid_session: '&2A megadott időkereten belül csatlakoztál vissza így a rendszer automatikusan beléptetett.'
|
||||
pwd_changed: '&cJelszó cserélve!'
|
||||
reload: 'Beálítások és adatbázis újratöltve!'
|
||||
timeout: 'Bejelentkezési időtúllépés!'
|
||||
error: 'Hiba lépett fel; Lépj kapcsolatba a tulajjal'
|
||||
error: 'Hiba lépett fel! Lépj kapcsolatba a tulajjal!'
|
||||
logged_in: '&cMár be vagy jelentkezve!'
|
||||
login: '&aSikeresen beléptél!'
|
||||
wrong_pwd: '&4Hibás jelszó!'
|
||||
user_unknown: '&cEz a felhasználó nincs regisztrálva!'
|
||||
reg_msg: '&cKérlek Regisztrálj: "/register jelszó jelszóújra"'
|
||||
reg_msg: '&cKérlek Regisztrálj: "/register <jelszó> <jelszó ismét>"'
|
||||
reg_email_msg: '&cKérlek regisztrálj: "/register <Email> <Email újra>"'
|
||||
unsafe_spawn: 'A kilépési helyzeted nem biztonságos, teleportálás a Spawnra.'
|
||||
max_reg: 'Csak egy karakterrel registrálhatsz!'
|
||||
unsafe_spawn: 'A kilépési helyzeted nem biztonságos, teleportálás a kezdő pozícióra.'
|
||||
max_reg: '&cElérted a maximálisan beregisztrálható karakterek számát. (%reg_count/%max_acc %reg_names)!'
|
||||
password_error: 'A két jelszó nem egyezik!'
|
||||
invalid_session: '&cAz IP címed megváltozott és a hálózati kapcsolatod lejárt. Kapcsolódj újra.'
|
||||
invalid_session: '&cAz IP címed megváltozott, ezért a visszacsatlakozási időkereted lejárt.'
|
||||
pass_len: 'A jelszavad nem éri el a minimális hosszúságot!'
|
||||
vb_nonActiv: '&cA felhasználód aktiválása még nem történt meg, ellenőrizd a leveleid!'
|
||||
usage_changepassword: 'Használat: /changepassword <régi Jelszó> <új Jelszó>'
|
||||
vb_nonActiv: '&cA felhasználód aktiválása még nem történt meg, ellenőrizd a megadott emailed!'
|
||||
usage_changepassword: 'Használat: "/changepassword <régi Jelszó> <új Jelszó>"'
|
||||
name_len: '&4A felhasználó neved túl hosszú, vagy túl rövid! Válassz másikat!'
|
||||
regex: '&4A felhasználóneved nem használható karaktereket tartalmaz. Elfogadott karakterek: REG_EX'
|
||||
add_email: '&3Kérlek add hozzá a felhasználódhoz az email címedet "/email add <Email címed> <Email címed ismét>"'
|
||||
recovery_email: '&3Ha elfelejtetted a jelszavad, használd az: "/email recovery <regisztrált Email címed>"'
|
||||
usage_captcha: '&3A bejelentkezéshez CAPTCHA szükséges, kérem használd a következő parancsot "/captcha <theCaptcha>"'
|
||||
wrong_captcha: '&cHibás captcha, kérlek írd be a következő parancsot "/captcha THE_CAPTCHA" a chat-be!'
|
||||
valid_captcha: '&2Captcha sikeresen feloldva!'
|
||||
usage_captcha: '&3A bejelentkezéshez CAPTCHA szükséges, kérlek használd a következő parancsot "/captcha <theCaptcha>"'
|
||||
wrong_captcha: '&cHibás CAPTCHA, kérlek írd be a következő parancsot "/captcha THE_CAPTCHA"!'
|
||||
valid_captcha: '&2CAPTCHA sikeresen feloldva!'
|
||||
kick_forvip: '&3VIP játékos csatlakozott a szerverhez!'
|
||||
kick_fullserver: '&4A szerver megtelt, próbálj csatlakozni később!'
|
||||
usage_email_add: '&cHasználat: /email add <email> <Email újra>'
|
||||
usage_email_change: '&cHasználat: /email change <régi Email> <új Email>'
|
||||
usage_email_recovery: '&cHasználat: /email recovery <email>'
|
||||
usage_email_add: '&cHasználat: "/email add <email> <Email újra>"'
|
||||
usage_email_change: '&cHasználat: "/email change <régi Email> <új Email>"'
|
||||
usage_email_recovery: '&cHasználat: "/email recovery <email>"'
|
||||
new_email_invalid: '&cHibás az új email cím, próbáld újra!'
|
||||
old_email_invalid: '&cHibás a régi email cím, próbáld újra!'
|
||||
email_invalid: '&cHibás az email cím, próbáld újra!'
|
||||
@ -52,12 +52,12 @@ email_added: '&2Az email címed rögzítése sikeresen megtörtént!'
|
||||
email_confirm: '&cKérlek ellenőrízd az email címedet!'
|
||||
email_changed: '&2Az email cím cseréje sikeresen megtörtént!'
|
||||
email_send: '&2A jelszó visszaállításhoz szükséges emailt elküldtük! Ellenőrízd a leveleidet!'
|
||||
email_exists: '&cA visszaállító emailt elküldtük! Hiba esetén újkérheted az alábbi parancs segítségével:'
|
||||
email_exists: '&cA visszaállító emailt elküldtük! Hiba esetén újra kérheted az alábbi parancs segítségével:'
|
||||
email_already_used: '&4Ez az email cím már használatban van!'
|
||||
country_banned: '&4Az országod tiltólistán van ezen a szerveren!'
|
||||
antibot_auto_enabled: '&4[AntiBot] Az AntiBot védelem bekapcsolt a nagy számú hálózati kapcsolat miatt!'
|
||||
antibot_auto_disabled: '&2[AntiBot] Az AntiBot kikapcsol %m múlva!'
|
||||
kick_antibot: 'Az AntiBot védelem bekapcsolva! Kérünk várj pár másodpercet a csatlakozáshoz.'
|
||||
# TODO email_already_used: '&4The email address is already being used'
|
||||
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
|
||||
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
|
||||
antibot_auto_enabled: '&4[AntiBot] Az AntiBot védelem bekapcsolt, mert a megszabott időn belül több felhasználó csatlakozott!'
|
||||
antibot_auto_disabled: '&2[AntiBot] Az AntiBot kikapcsol %m perc múlva!'
|
||||
kick_antibot: 'Az AntiBot védelem bekapcsolva! Kérlek várj pár percet mielőtt csatlakozol.'
|
||||
not_owner_error: 'Ez nem a te felhasználód. Kérlek válassz másik nevet!'
|
||||
invalid_name_case: '%valid a felhasználó neved nem? Akkor ne %invalid névvel próbálj feljönni.'
|
||||
two_factor_create: '&2A te titkos kódod a következő: %code. Vagy skenneld be a következő oldalról: %url'
|
||||
|
||||
@ -1,64 +1,64 @@
|
||||
#Lingua Italiana creata da Maxetto e sgdc3.
|
||||
unknown_user: 'L''utente non è presente nel database.'
|
||||
unsafe_spawn: 'Il tuo punto di disconnessione risulta ostruito o insicuro, sei stato teletrasportato al punto di rigenerazione!'
|
||||
# Lingua Italiana creata da Maxetto e sgdc3.
|
||||
kick_antibot: 'Il servizio di AntiBot è attualmente attivo! Devi aspettare qualche minuto prima di poter entrare nel server.'
|
||||
unknown_user: '&cL''utente non è presente nel database.'
|
||||
unsafe_spawn: '&cIl tuo punto di disconnessione risulta ostruito o insicuro, sei stato teletrasportato al punto di rigenerazione!'
|
||||
not_logged_in: '&cNon hai ancora eseguito l''autenticazione!'
|
||||
reg_voluntarily: 'Puoi eseguire la registrazione al server con il comando: "/register <password> <confermaPassword>"'
|
||||
usage_log: '&cUtilizzo: /login <password>'
|
||||
wrong_pwd: '&cPassword non corretta!'
|
||||
unregistered: '&cSei stato rimosso dal database con successo!'
|
||||
unregistered: '&2Sei stato correttamente rimosso dal database!'
|
||||
reg_disabled: '&cLa registrazione tramite i comandi di gioco è disabilitata.'
|
||||
valid_session: '&cAutenticato automaticamente attraverso la precedente sessione!'
|
||||
login: '&cAutenticazone effettuata correttamente!'
|
||||
vb_nonActiv: 'Il tuo account non è stato ancora verificato, controlla fra le tue email per scoprire come attivarlo!'
|
||||
valid_session: '&2Autenticato automaticamente attraverso la precedente sessione!'
|
||||
login: '&2Autenticazone effettuata correttamente!'
|
||||
vb_nonActiv: '&cIl tuo account non è stato ancora verificato, controlla fra le tue email per scoprire come attivarlo!'
|
||||
user_regged: '&cHai già effettuato la registrazione, non puoi eseguirla nuovamente.'
|
||||
usage_reg: '&cUtilizzo: /register <password> <confermaPassword>'
|
||||
error: 'Qualcosa è andato storto, riporta questo errore ad un Admin!'
|
||||
max_reg: 'Hai raggiunto il numero massimo di registrazioni per questo indirizzo IP!'
|
||||
no_perm: '&cNon hai il permesso di eseguire questa operazione.'
|
||||
login_msg: '&cPerfavore, esegui l''autenticazione con il comando: "/login <password>"'
|
||||
reg_msg: '&cPerfavore, esegui la registrazione con il comando: "/register <password> <confermaPassword>"'
|
||||
reg_email_msg: '&cPerfavore, esegui la registrazione con il comando: "/register <email> <confermaEmail>"'
|
||||
max_reg: '&cHai raggiunto il numero massimo di registrazioni (%reg_count/%max_acc %reg_names) per questo indirizzo IP!'
|
||||
no_perm: '&4Non hai il permesso di eseguire questa operazione.'
|
||||
error: '&4Qualcosa è andato storto, riporta questo errore ad un Admin!'
|
||||
login_msg: '&cPer favore, esegui l''autenticazione con il comando: "/login <password>"'
|
||||
reg_msg: '&3Per favore, esegui la registrazione con il comando: "/register <password> <confermaPassword>"'
|
||||
reg_email_msg: '&3Per favore, esegui la registrazione con il comando: "/register <email> <confermaEmail>"'
|
||||
usage_unreg: '&cUtilizzo: /unregister <password>'
|
||||
pwd_changed: '&cPassword cambiata con successo!'
|
||||
pwd_changed: '&2Password cambiata correttamente!'
|
||||
user_unknown: '&cL''utente non ha ancora eseguito la registrazione.'
|
||||
password_error: 'Le Password non corrispondono!'
|
||||
password_error_nick: 'Non puoi usare il tuo nome utente come password, scegline un''altra!'
|
||||
password_error_unsafe: 'La password che hai inserito non è sicura, scegline un''altra!'
|
||||
invalid_session: 'I tuoi dati di connessione attuali non sono quelli utilizzati in precedenza. Attendi la fine della sessione attuale.'
|
||||
reg_only: 'Puoi giocare in questo server solo dopo aver effettuato la registrazione attraverso il sito web! Perfavore, vai su http://esempio.it per procedere!'
|
||||
logged_in: '&cHai già eseguito l''autenticazione, non devi eseguirla nuovamente!'
|
||||
logout: '&cDisconnessione avvenuta correttamente!'
|
||||
same_nick: 'Questo stesso nome utente è già online sul server!'
|
||||
registered: '&cRegistrato correttamente!'
|
||||
pass_len: 'La password che hai inserito è troppo corta o troppo lunga, scegline un''altra!'
|
||||
reload: 'La configurazione e il database sono stati ricaricati con successo!'
|
||||
timeout: 'Tempo scaduto per effettuare l''autenticazione'
|
||||
usage_changepassword: 'Utilizzo: /changepassword <vecchiaPassword> <nuovaPassword>'
|
||||
name_len: '&cIl tuo nome utente è troppo corto o troppo lungo!'
|
||||
regex: '&cIl tuo nome utente contiene caratteri non consentiti. I caratteri consentiti sono: REG_EX'
|
||||
add_email: '&cPer poter recuperare la password in futuro, aggiungi un indirizzo email al tuo account con il comando: "/email add <tuaEmail> <confermaEmail>"'
|
||||
recovery_email: '&cHai dimenticato la tua password? Puoi recuperarla eseguendo il comando: "/email recovery <tuaEmail>"'
|
||||
usage_captcha: '&cAbbiamo bisogno che tu inserisca un captcha, perfavore scrivi: "/captcha <theCaptcha>"'
|
||||
wrong_captcha: '&cCaptcha sbagliato, perfavore riprova con il comando: "/captcha THE_CAPTCHA"'
|
||||
valid_captcha: '&cIl captcha inserito è valido!'
|
||||
kick_forvip: '&cUn utente VIP è entrato mentre il server era pieno e ha preso il tuo posto!'
|
||||
kick_fullserver: '&cIl server è attualmente pieno, riprova più tardi!'
|
||||
usage_email_add: '&fUtilizzo: /email add <email> <confermaEmail>'
|
||||
usage_email_change: '&fUtilizzo: /email change <vecchiaEmail> <nuovaEmail>'
|
||||
usage_email_recovery: '&fUtilizzo: /email recovery <email>'
|
||||
new_email_invalid: 'Il nuovo indirizzo email inserito non è valido!'
|
||||
old_email_invalid: 'Il vecchio indirizzo email inserito non è valido!'
|
||||
email_invalid: 'L''indirizzo email inserito non è valido'
|
||||
email_added: 'Indirizzo email aggiunto correttamente!'
|
||||
email_confirm: 'Conferma il tuo indirizzo email!'
|
||||
email_changed: 'Indirizzo email cambiato correttamente!'
|
||||
email_send: 'Una email di recupero è stata appena inviata al tuo indirizzo email!'
|
||||
email_exists: 'Il tuo account ha già un''indirizzo email configurato. Se vuoi, puoi cambiarlo con il seguente comando:'
|
||||
country_banned: 'Il tuo paese è bandito da questo server!'
|
||||
antibot_auto_enabled: 'Il servizio di AntiBot è stato automaticamente abilitato a seguito delle numerose connessioni!'
|
||||
antibot_auto_disabled: "Il servizio di AntiBot è stato automaticamente disabilitato dopo %m Minuti, sperando che l'attacco sia finito!"
|
||||
kick_antibot: 'Il servizio di AntiBot è attualmente attivo! Devi aspettare qualche minuto prima di poter entrare nel server.'
|
||||
password_error: '&cLe password non corrispondono!'
|
||||
password_error_nick: '&cNon puoi usare il tuo nome utente come password, per favore scegline un''altra...'
|
||||
password_error_unsafe: '&cLa password che hai inserito non è sicura, per favore scegline un''altra...'
|
||||
invalid_session: '&cIl tuo indirizzo IP è cambiato e la tua sessione è stata terminata!'
|
||||
reg_only: '&4Puoi giocare in questo server solo dopo aver effettuato la registrazione attraverso il sito web! Per favore, vai su http://esempio.it per procedere!'
|
||||
logged_in: '&cHai già eseguito l''autenticazione, non è necessario eseguirla nuovamente!'
|
||||
logout: '&2Disconnessione avvenuta correttamente!'
|
||||
same_nick: '&4Questo stesso nome utente è già online sul server!'
|
||||
registered: '&2Registrato correttamente!'
|
||||
pass_len: '&cLa password che hai inserito è troppo corta o troppo lunga, per favore scegline un''altra...'
|
||||
reload: '&2La configurazione e il database sono stati ricaricati correttamente!'
|
||||
timeout: '&4Tempo scaduto per effettuare l''autenticazione, sei stato espulso dal server, per favore riprova!'
|
||||
usage_changepassword: '&cUtilizzo: /changepassword <vecchiaPassword> <nuovaPassword>'
|
||||
name_len: '&4Il tuo nome utente è troppo corto o troppo lungo!'
|
||||
regex: '&4Il tuo nome utente contiene caratteri non consentiti. I caratteri consentiti sono: REG_EX'
|
||||
add_email: '&3Per poter recuperare la password in futuro, aggiungi un indirizzo email al tuo account con il comando: "/email add <tuaEmail> <confermaEmail>"'
|
||||
recovery_email: '&3Hai dimenticato la tua password? Puoi recuperarla eseguendo il comando: "/email recovery <tuaEmail>"'
|
||||
usage_captcha: '&3Per poterti autenticare devi risolvere un captcha, per favore scrivi: "/captcha <theCaptcha>"'
|
||||
wrong_captcha: '&cCaptcha sbagliato, per favore riprova scrivendo: "/captcha THE_CAPTCHA" in chat!'
|
||||
valid_captcha: '&2Il captcha inserito è valido!'
|
||||
kick_forvip: '&3Un utente VIP è entrato mentre il server era pieno e ha preso il tuo posto!'
|
||||
kick_fullserver: '&4Il server è attualmente pieno, riprova più tardi!'
|
||||
usage_email_add: '&cUtilizzo: /email add <email> <confermaEmail>'
|
||||
usage_email_change: '&cUtilizzo: /email change <vecchiaEmail> <nuovaEmail>'
|
||||
usage_email_recovery: '&cUtilizzo: /email recovery <email>'
|
||||
new_email_invalid: '&cIl nuovo indirizzo email inserito non è valido, riprova!'
|
||||
old_email_invalid: '&cIl vecchio indirizzo email inserito non è valido, riprova!'
|
||||
email_invalid: '&cL''indirizzo email inserito non è valido, riprova!'
|
||||
email_added: '&2Indirizzo email aggiunto correttamente al tuo account!'
|
||||
email_confirm: '&cPer favore, conferma il tuo indirizzo email!'
|
||||
email_changed: '&2Indirizzo email cambiato correttamente!'
|
||||
email_send: '&2Una email di recupero è stata appena inviata al tuo indirizzo email!'
|
||||
email_exists: '&cUna email di recupero è già stata inviata! Se vuoi, puoi annullarla e mandarne un''altra con il seguente comando:'
|
||||
country_banned: '&4Il tuo paese è bandito da questo server!'
|
||||
antibot_auto_enabled: '&4Il servizio di AntiBot è stato automaticamente abilitato a seguito delle numerose connessioni!'
|
||||
antibot_auto_disabled: "&2Il servizio di AntiBot è stato automaticamente disabilitato dopo %m Minuti, sperando che l'attacco sia finito!"
|
||||
email_already_used: '&4L''indirizzo email inserito è già in uso'
|
||||
two_factor_create: '&2Il tuo codice segreto è: &f%code&n&2Puoi anche scannerizzare il codice QR da qui: &f%url'
|
||||
# TODO email_already_used: '&4The email address is already being used'
|
||||
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
|
||||
not_owner_error: 'Non sei il proprietario di questo account. Per favore scegli un altro nome!'
|
||||
invalid_name_case: 'Dovresti entrare con questo nome utente: "%valid", al posto di: "%invalid".'
|
||||
|
||||
@ -1,68 +1,66 @@
|
||||
# Translator: uSoc_lifehome (http://lifeho.me) #
|
||||
# Translator: WaterXCubic 水方塊 #
|
||||
# Translator: Unknown #
|
||||
# Last modif: 1459528742 UTC #
|
||||
# -------------------------------------------- #
|
||||
unknown_user: '&8[&6用戶系統&8] &f用戶資料並不存在於資料庫中。'
|
||||
unsafe_spawn: '&8[&6用戶系統&8] &f你的登出位置不安全,現在將傳送你到重生點。'
|
||||
not_logged_in: '&8[&6用戶系統&8] &c你還沒有登入 !'
|
||||
reg_voluntarily: '&8[&6用戶系統&8] &f你可以使用這個的指令來註冊: 《 /register <密碼> <重覆密碼> 》'
|
||||
usage_log: '&8[&6用戶系統&8] &c用法: 《 /login <密碼> 》'
|
||||
wrong_pwd: '&8[&6用戶系統&8] &c你輸入了錯誤的密碼。'
|
||||
unregistered: '&8[&6用戶系統&8] &c你已成功取消會員註冊記錄。'
|
||||
reg_disabled: '&8[&6用戶系統&8] &c本伺服器已停止新玩家註冊。'
|
||||
valid_session: '&8[&6用戶系統&8] &b嗨 ! 我記得你,歡迎回來~'
|
||||
login: '&8[&6用戶系統&8] &c你成功的登入了。'
|
||||
password_error_nick: '&f你不可以使用你的名字為密碼!'
|
||||
password_error_unsafe: '&f你不可以使用不安全的密碼'
|
||||
vb_nonActiv: '&8[&6用戶系統&8] &f你的帳戶還沒有經過電郵驗證 !'
|
||||
user_regged: '&8[&6用戶系統&8] &c此用戶名已經註冊過了。'
|
||||
usage_reg: '&8[&6用戶系統&8] &c用法: 《 /register <密碼> <重覆密碼> 》'
|
||||
max_reg: '&8[&6用戶系統&8] &f你的IP地址已達到註冊數上限。'
|
||||
no_perm: '&8[&6用戶系統&8] &b你可以到 CraftingHK 玩家百科中查看說明文件。'
|
||||
error: '&8[&6用戶系統&8] &f發生錯誤,請與管理員聯絡。'
|
||||
login_msg: '&8[&6用戶系統&8] &c請使用這個指令來登入: 《 /login <密碼> 》'
|
||||
reg_msg: '&8[&6用戶系統&8] &c請使用這個的指令來註冊: 《 /register <密碼> <重覆密碼> 》'
|
||||
reg_email_msg: '&8[&6用戶系統&8] &c請使用這個的指令來註冊: 《 /register <電郵> <重覆電郵> 》'
|
||||
usage_unreg: '&8[&6用戶系統&8] &c用法: 《 /unregister <密碼> 》'
|
||||
pwd_changed: '&8[&6用戶系統&8] &c你成功的更換了你的密碼 !'
|
||||
user_unknown: '&8[&6用戶系統&8] &c此用戶名沒有已登記資料。'
|
||||
password_error: '&8[&6用戶系統&8] &f密碼不符合。'
|
||||
invalid_session: '&8[&6用戶系統&8] &f登入階段資料已損壞,請等待登入階段結束。'
|
||||
reg_only: '&8[&6用戶系統&8] &f限已註冊會員,請先到 https://www.example.com/ 註冊。'
|
||||
logged_in: '&8[&6用戶系統&8] &c你已經登入過了。'
|
||||
logout: '&8[&6用戶系統&8] &b你成功的登出了。'
|
||||
same_nick: '&8[&6用戶系統&8] &f同名玩家已在遊玩。'
|
||||
registered: '&8[&6用戶系統&8] &b你成功的註冊了。'
|
||||
pass_len: '&8[&6用戶系統&8] &f你的密碼並不符合規定長度。'
|
||||
reload: '&8[&6用戶系統&8] &b登入系統設定及資料庫重新載入完畢。'
|
||||
timeout: '&8[&6用戶系統&8] &f登入逾時。'
|
||||
usage_changepassword: '&8[&6用戶系統&8] &f用法: 《 /changepassword <舊密碼> <新密碼> 》'
|
||||
name_len: '&8[&6用戶系統&8] &c你的用戶名不符合規定長度。'
|
||||
regex: '&8[&6用戶系統&8] &c你的用戶名含有不容許之字符。以下為准許之字母: REG_EX'
|
||||
add_email: '&8[&6用戶系統&8] &b請為你的帳戶立即添加電郵地址: 《 /email add <電郵地址> <重覆電郵地址> 》'
|
||||
bad_database_email: '&8[&6用戶系統&8] 此指令只適用於使用MySQL或SQLite之伺服器。'
|
||||
recovery_email: '&8[&6用戶系統&8] &c忘記密碼 ? 請使用這個的指令來更新密碼: 《 /email recovery <電郵地址> 》'
|
||||
usage_captcha: '&8[&6用戶系統&8] &c用法: 《 /captcha <theCaptcha> 》'
|
||||
# TODO wrong_captcha: Missing tag THE_CAPTCHA
|
||||
wrong_captcha: '&8[&6用戶系統&8] &c你輸入了錯誤的驗證碼,請使用 《 /captcha <驗證碼> 》 再次輸入。'
|
||||
valid_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼是無效的 !'
|
||||
kick_forvip: '&c因為有VIP玩家登入了伺服器。'
|
||||
kick_fullserver: '&c抱歉! 因為伺服器滿人了,所以你目前未能登入伺服器。'
|
||||
usage_email_add: '&8[&6用戶系統&8] &f用法: 《 /email add <電郵> <重覆電郵> 》'
|
||||
usage_email_change: '&8[&6用戶系統&8] &f用法: 《 /email change <舊電郵> <新電郵> 》'
|
||||
usage_email_recovery: '&8[&6用戶系統&8] &f用法: 《 /email recovery <電郵> 》'
|
||||
new_email_invalid: '&8[&6用戶系統&8] 你所填寫的新電郵地址並不正確。'
|
||||
old_email_invalid: '&8[&6用戶系統&8] 你所填寫的舊電郵地址並不正確。'
|
||||
email_invalid: '&8[&6用戶系統&8] 你所填寫的電郵地址並不正確。'
|
||||
email_added: '&8[&6用戶系統&8] 已加入你的電郵地址記錄。'
|
||||
email_confirm: '&8[&6用戶系統&8] 請重覆輸入你的電郵地址。'
|
||||
email_changed: '&8[&6用戶系統&8] 你的電郵地址記錄已更改。'
|
||||
email_send: '&8[&6用戶系統&8] 忘記密碼信件已寄出,請查收。'
|
||||
country_banned: '&8[&6用戶系統&8] 本伺服器已停止對你的國家提供遊戲服務。'
|
||||
antibot_auto_enabled: '&8[&6用戶系統&8] 防止機械人程序已因應現時大量不尋常的連線而啟用。'
|
||||
antibot_auto_disabled: '&8[&6用戶系統&8] 防止機械人程序檢查到不正常連接數已減少,並於 %m 分鐘後停止運作。'
|
||||
# TODO email_already_used: '&4The email address is already being used'
|
||||
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
|
||||
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
|
||||
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
|
||||
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
|
||||
kick_antibot: '&8[&6玩家系统&8] &f防机器人程序已启用 !请稍等几分钟後才再次进入服务器'
|
||||
unknown_user: '&8[&6玩家系统&8] &f&f数据库里找不到此用户'
|
||||
unsafe_spawn: '&8[&6玩家系统&8] &f你退出服务器时的位置不安全,正在传送你到此世界的出生点'
|
||||
not_logged_in: '&8[&6玩家系统&8] &c你还未登录!'
|
||||
reg_voluntarily: '&8[&6玩家系统&8] &f你可以在服务器里使用这个指令以注册:“/register <密码> <再输入一次以确定密码>”'
|
||||
usage_log: '&8[&6玩家系统&8] &c正确用法:“/login <密码>”'
|
||||
wrong_pwd: '&8[&6玩家系统&8] &c错误的密码'
|
||||
unregistered: '&8[&6玩家系统&8] &c成功删除此用户!'
|
||||
reg_disabled: '&8[&6玩家系统&8] &c目前服务器暂时禁止注册,请到服务器论坛以得到更多资讯'
|
||||
valid_session: '&8[&6玩家系统&8] &c欢迎回来,已帮你自动登录到此服务器'
|
||||
login: '&8[&6玩家系统&8] &c已成功登录!'
|
||||
vb_nonActiv: '&8[&6玩家系统&8] &f你的帐号还未激活,请查看你的邮箱!'
|
||||
user_regged: '&8[&6玩家系统&8] &c此用户已经在此服务器注册过'
|
||||
usage_reg: '&8[&6玩家系统&8] &c正确用法:“/register <密码> <再输入一次以确定密码>”'
|
||||
max_reg: '&8[&6玩家系统&8] &f你不允许再为你的IP在服务器注册更多用户了!'
|
||||
no_perm: '&8[&6玩家系统&8] &c没有权限'
|
||||
error: '&8[&6玩家系统&8] &f发现错误,请联系管理员'
|
||||
login_msg: '&8[&6玩家系统&8] &c请输入“/login <密码>”以登录'
|
||||
reg_msg: '&8[&6玩家系统&8] &c请输入“/register <密码> <再输入一次以确定密码>”以注册'
|
||||
reg_email_msg: '&8[&6玩家系统&8] &c请输入 "/register <邮箱> <确认电子邮件>"'
|
||||
usage_unreg: '&8[&6玩家系统&8] &c正确用法:“/unregister <密码>”'
|
||||
pwd_changed: '&8[&6玩家系统&8] &c密码已成功修改!'
|
||||
user_unknown: '&8[&6玩家系统&8] &c此用户名还未注册过'
|
||||
password_error: '&8[&6玩家系统&8] &f密码不相同'
|
||||
password_error_nick: '&8[&6玩家系统&8] &f你不能使用你的名字作为密码。 '
|
||||
password_error_unsafe: '&8[&6玩家系统&8] &f你不能使用安全性过低的码。 '
|
||||
invalid_session: '&8[&6玩家系统&8] &f登陆数据异常,请等待登陆结束'
|
||||
reg_only: '&8[&6玩家系统&8] &f只允许注册过的玩家进服!请到 https://example.cn 注册'
|
||||
logged_in: '&8[&6玩家系统&8] &c你已经登陆过了!'
|
||||
logout: '&8[&6玩家系统&8] &c已成功登出!'
|
||||
same_nick: '&8[&6玩家系统&8] &f同样的用户名现在在线且已经登录了!'
|
||||
registered: '&8[&6玩家系统&8] &c已成功注册!'
|
||||
pass_len: '&8[&6玩家系统&8] &你的密码没有达到要求!'
|
||||
reload: '&8[&6玩家系统&8] &f配置以及数据已经重新加载完毕'
|
||||
timeout: '&8[&6玩家系统&8] &f给你登录的时间已经过了'
|
||||
usage_changepassword: '&8[&6玩家系统&8] &f正确用法:“/changepassword 旧密码 新密码”'
|
||||
name_len: '&8[&6玩家系统&8] &c你的用户名太短或者太长了'
|
||||
regex: '&8[&6玩家系统&8] &c你的用户名包含非法字母,用户名里允许的字母: REG_EX'
|
||||
add_email: '&8[&6玩家系统&8] &c请输入“/email add <你的邮箱> <再输入一次以确认>”以把你的邮箱添加到此帐号'
|
||||
recovery_email: '&8[&6玩家系统&8] &c忘了你的密码?请输入:“/email recovery <你的邮箱>”'
|
||||
usage_captcha: '&8[&6玩家系统&8] &c正确用法:/captcha <theCaptcha>'
|
||||
wrong_captcha: '&8[&6玩家系统&8] &c错误的验证码,请输入:“/captcha THE_CAPTCHA”'
|
||||
valid_captcha: '&8[&6玩家系统&8] &c你的验证码是有效的!'
|
||||
kick_forvip: '&8[&6玩家系统&8] &cA VIP玩家加入了已满的服务器!'
|
||||
kick_fullserver: '&8[&6玩家系统&8] &c抱歉,服务器已满!'
|
||||
usage_email_add: '&8[&6玩家系统&8] &f用法: /email add <邮箱> <确认电子邮件> '
|
||||
usage_email_change: '&8[&6玩家系统&8] &f用法: /email change <旧邮箱> <新邮箱> '
|
||||
usage_email_recovery: '&8[&6玩家系统&8] &f用法: /email recovery <邮箱>'
|
||||
new_email_invalid: '&8[&6玩家系统&8] &f新邮箱无效!'
|
||||
old_email_invalid: '&8[&6玩家系统&8] &f旧邮箱无效!'
|
||||
email_invalid: '&8[&6玩家系统&8] &f无效的邮箱'
|
||||
email_added: '&8[&6玩家系统&8] &f邮箱已添加 !'
|
||||
email_confirm: '&8[&6玩家系统&8] &f确认你的邮箱 !'
|
||||
email_changed: '&8[&6玩家系统&8] &f邮箱已改变 !'
|
||||
email_send: '&8[&6玩家系统&8] &f恢复邮件已发送 !'
|
||||
country_banned: '这个服务器禁止该国家登陆'
|
||||
antibot_auto_enabled: '&8[&6玩家系统&8] &f防机器人程序由于大量异常连接而启用'
|
||||
antibot_auto_disabled: '&8[&6玩家系统&8] &f防机器人程序由于异常连接减少而在 %m 分钟后停止'
|
||||
email_already_used: '&8[&6玩家系统&8] &4邮箱已被使用'
|
||||
email_exists: '&8[&6玩家系统&8] &c恢复邮件已发送 ! 你可以丢弃它然後使用以下的指令来发送新的邮件:'
|
||||
two_factor_create: '&8[&6玩家系统&8] &2你的代码是 %code,你可以使用 %url 来扫描'
|
||||
not_owner_error: '&8[&6玩家系统&8] &4警告! &c你并不是此帐户持有人,请立即登出。 '
|
||||
invalid_name_case: '&8[&6玩家系统&8] &c你应该使用「%valid」而并非「%invalid」登入游戏。 '
|
||||
@ -1,67 +1,66 @@
|
||||
#----------------------------------------#
|
||||
#translated by i998979
|
||||
#----------------------------------------#
|
||||
unknown_user: '&f用戶資料並不存在於資料庫中。'
|
||||
unsafe_spawn: '&f你的登出的位置不安全,將傳送你至重生點。'
|
||||
not_logged_in: '&c你並未登入!'
|
||||
reg_voluntarily: '&f請使用: /register <密碼> <重覆密碼> 來註冊。'
|
||||
usage_log: '&c用法: /login <密碼>'
|
||||
wrong_pwd: '&c密碼錯誤。'
|
||||
unregistered: '&c成功取消該名用戶的註冊記錄。'
|
||||
reg_disabled: '&c新玩家註冊已停用。'
|
||||
valid_session: '&cIP記憶,自動登入。'
|
||||
login: '&c登入成功。'
|
||||
vb_nonActiv: '&f你的帳戶並未啟用,請檢查你的電郵!'
|
||||
user_regged: '&c此用戶名已有註冊記錄。'
|
||||
usage_reg: '&c用法: /register <密碼> <重覆密碼>'
|
||||
max_reg: '&f你的IP地址已達到註冊帳號上限。'
|
||||
no_perm: '&c你沒有足夠的權限。'
|
||||
error: '&f發生錯誤,請與管理員聯絡。'
|
||||
login_msg: '&c請使用 /login <密碼> 來登入。'
|
||||
reg_msg: '&c請使用 /register <密碼> <重覆密碼> 來註冊。'
|
||||
reg_email_msg: '&c請使用 /register <電郵> <重覆電郵> 來註冊。'
|
||||
usage_unreg: '&c用法: /unregister <密碼>'
|
||||
pwd_changed: '&c密碼更改成功!'
|
||||
user_unknown: '&c該用戶並未註冊。'
|
||||
password_error: '&f密碼不符合。'
|
||||
password_error_nick: '&f你不能使用你的名字作為密碼。'
|
||||
password_error_unsafe: '&f你不能使用安全性過低的碼。'
|
||||
invalid_session: '&f登入階段資料不相同,請等待登入階段結束。'
|
||||
reg_only: '&f只限已註冊用戶,請先到 https://www.example.com 註冊。'
|
||||
logged_in: '&c你已經登入過了。'
|
||||
logout: '&b登出成功。'
|
||||
same_nick: '&f同名玩家已在遊玩。'
|
||||
registered: '&b註冊成功。'
|
||||
pass_len: '&f你的密碼太短或太長。'
|
||||
reload: '&b系統設定及資料庫已重新載入。'
|
||||
timeout: '&f登入逾時,請重新登入。'
|
||||
usage_changepassword: '&f用法: /changepassword <舊密碼> <新密碼>'
|
||||
name_len: '&c你的用戶名太短或太長。'
|
||||
regex: '&c你的用戶名含有不容許的字符。以下為准許之字母: REG_EX。'
|
||||
add_email: '&b請為你的帳戶添加電郵地址: /email add <電郵地址> <重覆電郵地址>。'
|
||||
bad_database_email: '/email 只適用於使用MySQL或SQLite之伺服器,請聯絡管理員。'
|
||||
recovery_email: '&c忘記密碼?請使用 /email recovery <電郵地址> 來更新密碼。'
|
||||
usage_captcha: '&c用法: /captcha <theCaptcha>'
|
||||
wrong_captcha: '&c驗證碼錯誤,請再次輸入 /captcha THE_CAPTCHA。'
|
||||
valid_captcha: '&c驗證碼無效!'
|
||||
kick_forvip: '&cVIP玩家登入了滿人的伺服器。'
|
||||
kick_fullserver: '&c因為伺服器滿人,請稍候再試。'
|
||||
usage_email_add: '&f用法: /email add <電郵> <重覆電郵>'
|
||||
usage_email_change: '&f用法: /email change <舊電郵> <新電郵>'
|
||||
usage_email_recovery: '&f用法: /email recovery <電郵>'
|
||||
new_email_invalid: '新電郵地址不正確。'
|
||||
old_email_invalid: '舊電郵地址不正確。'
|
||||
email_invalid: '電郵地址不正確。'
|
||||
email_added: '電郵地址已加入。'
|
||||
email_confirm: '請確認電郵地址。'
|
||||
email_changed: '電郵地址已更改。'
|
||||
email_send: '已寄出忘記密碼信件。'
|
||||
country_banned: '你的國家已被本伺服器封禁。'
|
||||
antibot_auto_enabled: '防止機械人程序因大量不尋常連線而啟用。'
|
||||
antibot_auto_disabled: '防止機械人程序將於 %m 分鐘後停止運作。'
|
||||
email_already_used: '&4邮箱已被使用'
|
||||
kick_antibot: '[AuthMe] 防机器人程序已启用 !请稍等几分钟後才再次进入服务器'
|
||||
email_exists: '&c恢复邮件已发送 ! 你可以丢弃它然後使用以下的指令来发送新的邮件:'
|
||||
two_factor_create: '&2你的代码是 %code,你可以使用 %url 来扫描'
|
||||
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
|
||||
# Translator: lifehome<m@lifeho.me> #
|
||||
# Last modif: 1459528742 UTC #
|
||||
# -------------------------------------------- #
|
||||
kick_antibot: '&8[&6用戶系統&8] &c伺服器錯誤!請稍候再嘗試登入吧。 &7(err: kick_due2_bot)'
|
||||
unknown_user: '&8[&6用戶系統&8] &f用戶資料並不存在。'
|
||||
unsafe_spawn: '&8[&6用戶系統&8] &f你的登出位置不安全,現在將傳送你到重生點。'
|
||||
not_logged_in: '&8[&6用戶系統&8] &c你還沒有登入 !'
|
||||
reg_voluntarily: '&8[&6用戶系統&8] &f你可以使用這個指令來註冊: 《 /register <密碼> <重覆密碼> 》'
|
||||
usage_log: '&8[&6用戶系統&8] &f用法: 《 /login <密碼> 》'
|
||||
wrong_pwd: '&8[&6用戶系統&8] &c你輸入了錯誤的密碼。'
|
||||
unregistered: '&8[&6用戶系統&8] &c你已成功刪除會員註冊記錄。'
|
||||
reg_disabled: '&8[&6用戶系統&8] &c本伺服器已停止新玩家註冊。'
|
||||
valid_session: '&8[&6用戶系統&8] &b嗨 ! 歡迎回來喔~'
|
||||
login: '&8[&6用戶系統&8] &c你成功登入了。'
|
||||
vb_nonActiv: '&8[&6用戶系統&8] &f你的帳戶還沒有經過電郵驗證 !'
|
||||
user_regged: '&8[&6用戶系統&8] &c此用戶名已經註冊過了。'
|
||||
usage_reg: '&8[&6用戶系統&8] &f用法: 《 /register <密碼> <重覆密碼> 》'
|
||||
max_reg: '&8[&6用戶系統&8] &f你的IP地址已達到註冊數上限。'
|
||||
no_perm: '&8[&6用戶系統&8] &b嗯~你想幹甚麼?'
|
||||
error: '&8[&6用戶系統&8] &f發生錯誤,請與管理員聯絡。'
|
||||
login_msg: '&8[&6用戶系統&8] &c請使用這個指令來登入: 《 /login <密碼> 》'
|
||||
reg_msg: '&8[&6用戶系統&8] &c請使用這個指令來註冊: 《 /register <密碼> <重覆密碼> 》'
|
||||
reg_email_msg: '&8[&6用戶系統&8] &c請使用這個指令來註冊: 《 /register <電郵> <重覆電郵> 》'
|
||||
usage_unreg: '&8[&6用戶系統&8] &f用法: 《 /unregister <密碼> 》'
|
||||
pwd_changed: '&8[&6用戶系統&8] &c你成功更換了你的密碼 !'
|
||||
user_unknown: '&8[&6用戶系統&8] &c此用戶名沒有已登記資料。'
|
||||
password_error: '&8[&6用戶系統&8] &f密碼不符合。'
|
||||
password_error_nick: '&8[&6用戶系統&8] &c這個密碼太不安全了!'
|
||||
password_error_unsafe: '&8[&6用戶系統&8] &c這個密碼太不安全了!'
|
||||
invalid_session: '&8[&6用戶系統&8] &f登入階段資料已損壞,請等待登入階段結束。'
|
||||
reg_only: '&8[&6用戶系統&8] &f限已註冊會員,請先到本服網站進行註冊。'
|
||||
logged_in: '&8[&6用戶系統&8] &c你已經登入過了。'
|
||||
logout: '&8[&6用戶系統&8] &b你成功登出了。'
|
||||
same_nick: '&8[&6用戶系統&8] &f同名玩家已在遊玩。'
|
||||
registered: '&8[&6用戶系統&8] &b你成功註冊了。'
|
||||
pass_len: '&8[&6用戶系統&8] &f你的密碼並不符合規定長度。'
|
||||
reload: '&8[&6用戶系統&8] &b登入系統設定及資料庫重新載入完畢。'
|
||||
timeout: '&8[&6用戶系統&8] &f登入逾時。'
|
||||
usage_changepassword: '&8[&6用戶系統&8] &f用法: 《 /changepassword <舊密碼> <新密碼> 》'
|
||||
name_len: '&8[&6用戶系統&8] &c你的用戶名不符合規定長度。'
|
||||
regex: '&8[&6用戶系統&8] &c用戶名稱錯誤! 登入系統只接受以下字符: REG_EX'
|
||||
add_email: '&8[&6用戶系統&8] &b請為你的帳戶立即添加電郵地址: 《 /email add <電郵地址> <重覆電郵地址> 》'
|
||||
recovery_email: '&8[&6用戶系統&8] &b忘記密碼?請使用 /email recovery <電郵地址> 來更新密碼。'
|
||||
usage_captcha: '&8[&6用戶系統&8] &f用法: 《 /captcha <theCaptcha> 》'
|
||||
wrong_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼無效,請使用 《 /captcha THE_CAPTCHA 》 再次輸入。'
|
||||
valid_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼無效 !'
|
||||
kick_forvip: '&c喔!因為有VIP玩家登入了伺服器。'
|
||||
kick_fullserver: '&c抱歉! 因為伺服器滿人了,所以你目前未能登入伺服器。'
|
||||
usage_email_add: '&8[&6用戶系統&8] &f用法: 《 /email add <電郵> <重覆電郵> 》'
|
||||
usage_email_change: '&8[&6用戶系統&8] &f用法: 《 /email change <舊電郵> <新電郵> 》'
|
||||
usage_email_recovery: '&8[&6用戶系統&8] &f用法: 《 /email recovery <電郵> 》'
|
||||
new_email_invalid: '&8[&6用戶系統&8] &c你所填寫的新電郵地址並不正確。'
|
||||
old_email_invalid: '&8[&6用戶系統&8] &c你所填寫的舊電郵地址並不正確。'
|
||||
email_invalid: '&8[&6用戶系統&8] &c你所填寫的電郵地址並不正確。'
|
||||
email_added: '&8[&6用戶系統&8] &a已新增你的電郵地址。'
|
||||
email_confirm: '&8[&6用戶系統&8] &5請重覆輸入你的電郵地址。'
|
||||
email_changed: '&8[&6用戶系統&8] &a你的電郵地址已更改。'
|
||||
email_send: '&8[&6用戶系統&8] &a忘記密碼信件已寄出,請查收。'
|
||||
country_banned: '&8[&6用戶系統&8] &4本伺服器已停止對你的國家提供遊戲服務。'
|
||||
antibot_auto_enabled: '&8[&6用戶系統&8] &3防止機械人程序已因應現時大量不尋常連線而啟用。'
|
||||
antibot_auto_disabled: '&8[&6用戶系統&8] &3不正常連接數已減少,防止機械人程序將於 %m 分鐘後停止。'
|
||||
email_already_used: '&8[&6用戶系統&8] &4這個電郵地址已被使用。'
|
||||
email_exists: '&8[&6用戶系統&8] &c訊息已發送!如果你收不到該封電郵,可以使用以下指令進行重寄:'
|
||||
two_factor_create: '&8[&6用戶系統 - 兩步驗證碼&8] &b你的登入金鑰為&9「%c%code&9」&b,掃描連結為:&c %url'
|
||||
not_owner_error: '&8[&6用戶系統&8] &4警告!&c你並不是此帳戶持有人,請立即登出。'
|
||||
invalid_name_case: '&8[&6用戶系統&8] &4警告!&c你應該使用「%valid」而並非「%invalid」登入遊戲。'
|
||||
@ -1,6 +1,7 @@
|
||||
# Translator: MineWolf50
|
||||
# Last Time Edit : 2015 / 7 / 14 , A.M.10:14
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = #
|
||||
# Translator: MineWolf50, lifehome #
|
||||
# Last modif: 1459528742 UTC #
|
||||
# -------------------------------------------- #
|
||||
kick_antibot: '&b【AuthMe】&cAntiBotMod 正在啟用中,請稍後再嘗試登入吧!'
|
||||
unknown_user: "&b【AuthMe】&6沒有在資料庫內找到該玩家。"
|
||||
unsafe_spawn: '&b【AuthMe】&6你登出的地點不安全,已傳送你到安全的地點。'
|
||||
not_logged_in: '&b【AuthMe】&6你還沒有登入!'
|
||||
@ -9,8 +10,6 @@ usage_log: '&b【AuthMe】&6用法: &c"/login <密碼>"'
|
||||
wrong_pwd: '&b【AuthMe】&6密碼錯誤!'
|
||||
unregistered: '&b【AuthMe】&6你已經成功取消註冊。'
|
||||
reg_disabled: '&b【AuthMe】&6已關閉註冊功能'
|
||||
password_error_nick: '&b【AuthMe】&6你不可以用你的 ID ( 名稱 ) 來當作密碼 !'
|
||||
password_error_unsafe: '&b【AuthMe】&6你不可以使用這個不安全的密碼'
|
||||
valid_session: '&b【AuthMe】&6你已經成功登入!'
|
||||
login: '&b【AuthMe】&6密碼正確,你已成功登入!'
|
||||
vb_nonActiv: '&b【AuthMe】&6你的帳號還沒有經過驗證! 檢查看看你的電子信箱 (Email) 吧!'
|
||||
@ -26,8 +25,10 @@ usage_unreg: '&b【AuthMe】&6用法: &c"/unregister <密碼>"'
|
||||
pwd_changed: '&b【AuthMe】&6密碼變更成功!'
|
||||
user_unknown: '&b【AuthMe】&6這個帳號還沒有註冊過'
|
||||
password_error: '&b【AuthMe】&6兩次輸入的密碼不一致!'
|
||||
password_error_nick: '&b【AuthMe】&6你不可以用你的 ID ( 名稱 ) 來當作密碼 !'
|
||||
password_error_unsafe: '&b【AuthMe】&6你不可以使用這個不安全的密碼'
|
||||
invalid_session: '&b【AuthMe】&6憑證日期不相符!'
|
||||
reg_only: '&b【AuthMe】&6請到下列網站 :「 http://example.com 」 進行註冊'
|
||||
reg_only: '&b【AuthMe】&6請到下列網站 :「 https://example.tw 」 進行註冊'
|
||||
logged_in: '&b【AuthMe】&6你已經登入了!'
|
||||
logout: '&b【AuthMe】&6你已成功登出'
|
||||
same_nick: '&b【AuthMe】&6有同樣帳號的玩家在線上!'
|
||||
@ -37,13 +38,11 @@ reload: '&b【AuthMe】&6已重新讀取設定檔及資料庫'
|
||||
timeout: '&b【AuthMe】&6超過登入時間,請稍後再試一次'
|
||||
usage_changepassword: '&b【AuthMe】&6用法: &c"/changepassword <舊密碼> <新密碼>"'
|
||||
name_len: '&b【AuthMe】&6你的暱稱 太長 / 太短 了!'
|
||||
# TODO regex: Missing tag REG_EX
|
||||
regex: '&b【AuthMe】&6暱稱裡包含不能使用的字符'
|
||||
regex: '&b【AuthMe】&6暱稱裡能使用的字符為: REG_EX'
|
||||
add_email: '&b【AuthMe】&6請使用 &c"/email add <你的Email> <再次輸入你的Email>" &6來添加 Email'
|
||||
recovery_email: '&b【AuthMe】&6忘記密碼了嗎? 使用 &c"/email recovery <你的Email>"'
|
||||
usage_captcha: '&b【AuthMe】&6請用 &c"/captcha <theCaptcha>" &6來輸入你的驗證碼'
|
||||
# TODO wrong_captcha: Missing tag THE_CAPTCHA
|
||||
wrong_captcha: '&b【AuthMe】&6錯誤的驗證碼'
|
||||
wrong_captcha: '&b【AuthMe】&6錯誤的驗證碼,請使用 《 /captcha THE_CAPTCHA 》 再試一次吧。'
|
||||
valid_captcha: '&b【AuthMe】&6驗證碼無效!'
|
||||
kick_forvip: '&b【AuthMe】&6你已經被請出。&c原因 : 有 VIP 玩家登入伺服器'
|
||||
kick_fullserver: '&b【AuthMe】&6伺服器已經滿了,請等等再試一次'
|
||||
@ -57,12 +56,11 @@ email_added: '&b【AuthMe】&6已添加Email!'
|
||||
email_confirm: '&b【AuthMe】&6請驗證你的Email!'
|
||||
email_changed: '&b【AuthMe】&6Email已變更!'
|
||||
email_send: '&b【AuthMe】&6已經送出重設密碼要求至你的Email , 請查收。'
|
||||
email_exists: '&b【AuthMe】&6這個帳戶已經有設定電子郵件了'
|
||||
country_banned: '&b【AuthMe】&6你所在的地區無法進入此伺服器'
|
||||
antibot_auto_enabled: '&b【AuthMe】&6AntiBotMod已自動啟用!'
|
||||
antibot_auto_disabled: '&b【AuthMe】&6AntiBotMod將會於 &c%m &6分鐘後自動關閉'
|
||||
# TODO email_already_used: '&4The email address is already being used'
|
||||
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
|
||||
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
|
||||
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
|
||||
email_already_used: '&b【AuthMe】&4這個電郵地址已被使用。'
|
||||
email_exists: '&b【AuthMe】&6這個帳戶已經有設定電子郵件了'
|
||||
two_factor_create: '&b【AuthMe - 兩步驗證碼】&b你的登入金鑰為&9「%c%code&9」&b,掃描連結為:&c %url'
|
||||
not_owner_error: '&b【AuthMe】&4警告!&c你並不是此帳戶持有人,請立即登出。'
|
||||
invalid_name_case: '&b【AuthMe】&4警告!&c你應該使用「%valid」而並非「%invalid」登入遊戲。'
|
||||
@ -167,6 +167,7 @@ public class AntiBotTest {
|
||||
antiBot.checkAntiBot(player);
|
||||
|
||||
// then
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> playerList = (List<String>) ReflectionTestUtils
|
||||
.getFieldValue(AntiBot.class, antiBot, "antibotPlayers");
|
||||
assertThat(playerList, hasSize(1));
|
||||
@ -196,6 +197,7 @@ public class AntiBotTest {
|
||||
antiBot.checkAntiBot(player);
|
||||
|
||||
// then
|
||||
@SuppressWarnings("rawtypes")
|
||||
List<?> playerList = (List) ReflectionTestUtils.getFieldValue(AntiBot.class, antiBot, "antibotPlayers");
|
||||
assertThat(playerList, empty());
|
||||
verify(bukkitService, never()).scheduleSyncDelayedTask(any(Runnable.class), anyLong());
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Test initializer for {@link ConsoleLogger}.
|
||||
*/
|
||||
public class ConsoleLoggerTestInitializer {
|
||||
|
||||
private ConsoleLoggerTestInitializer() {
|
||||
}
|
||||
|
||||
public static Logger setupLogger() {
|
||||
Logger logger = Mockito.mock(Logger.class);
|
||||
ConsoleLogger.setLogger(logger);
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
@ -3,11 +3,16 @@ package fr.xephi.authme;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@ -68,20 +73,6 @@ public final class TestHelper {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a {@link Runnable} passed to a mock's {@link BukkitService#scheduleSyncDelayedTask(Runnable)} method.
|
||||
* Note that calling this method expects that there be a runnable sent to the method and will fail
|
||||
* otherwise.
|
||||
*
|
||||
* @param service The mock service
|
||||
*/
|
||||
public static void runSyncDelayedTask(BukkitService service) {
|
||||
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
|
||||
verify(service).scheduleSyncDelayedTask(captor.capture());
|
||||
Runnable runnable = captor.getValue();
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a {@link Runnable} passed to a mock's {@link BukkitService#scheduleSyncDelayedTask(Runnable, long)}
|
||||
* method. Note that calling this method expects that there be a runnable sent to the method and will fail
|
||||
@ -96,4 +87,42 @@ public final class TestHelper {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the necessary fields on ConsoleLogger with mocks.
|
||||
*
|
||||
* @return The logger mock used
|
||||
*/
|
||||
public static Logger setupLogger() {
|
||||
Logger logger = Mockito.mock(Logger.class);
|
||||
ConsoleLogger.setLogger(logger);
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a class only has a hidden, zero-argument constructor, preventing the
|
||||
* instantiation of such classes (utility classes). Invokes the hidden constructor
|
||||
* as to register the code coverage.
|
||||
*
|
||||
* @param clazz The class to validate
|
||||
*/
|
||||
public static void validateHasOnlyPrivateEmptyConstructor(Class<?> clazz) {
|
||||
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||
if (constructors.length > 1) {
|
||||
throw new IllegalStateException("Class " + clazz.getSimpleName() + " has more than one constructor");
|
||||
} else if (constructors[0].getParameterTypes().length != 0) {
|
||||
throw new IllegalStateException("Constructor of " + clazz + " does not have empty parameter list");
|
||||
} else if (!Modifier.isPrivate(constructors[0].getModifiers())) {
|
||||
throw new IllegalStateException("Constructor of " + clazz + " is not private");
|
||||
}
|
||||
|
||||
// Ugly hack to get coverage on the private constructors
|
||||
// http://stackoverflow.com/questions/14077842/how-to-test-a-private-constructor-in-java-application
|
||||
try {
|
||||
constructors[0].setAccessible(true);
|
||||
constructors[0].newInstance();
|
||||
} catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
package fr.xephi.authme.cache;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link IpAddressManager}.
|
||||
*/
|
||||
public class IpAddressManagerTest {
|
||||
|
||||
@Test
|
||||
public void shouldRetrieveFromCache() {
|
||||
// given
|
||||
IpAddressManager ipAddressManager = new IpAddressManager(mockSettings(true));
|
||||
ipAddressManager.addCache("Test", "my test IP");
|
||||
|
||||
// when
|
||||
String result = ipAddressManager.getPlayerIp(mockPlayer("test", "123.123.123.123"));
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo("my test IP"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnPlainIp() {
|
||||
// given
|
||||
IpAddressManager ipAddressManager = new IpAddressManager(mockSettings(false));
|
||||
|
||||
// when
|
||||
String result = ipAddressManager.getPlayerIp(mockPlayer("bobby", "8.8.8.8"));
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo("8.8.8.8"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static NewSetting mockSettings(boolean useVeryGames) {
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK)).willReturn(useVeryGames);
|
||||
return settings;
|
||||
}
|
||||
|
||||
private static Player mockPlayer(String name, String ip) {
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
InetAddress inetAddress = mock(InetAddress.class);
|
||||
given(inetAddress.getHostAddress()).willReturn(ip);
|
||||
InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 8093);
|
||||
given(player.getAddress()).willReturn(inetSocketAddress);
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
||||
@ -17,13 +17,14 @@ import static fr.xephi.authme.command.FoundResultStatus.NO_PERMISSION;
|
||||
import static fr.xephi.authme.command.FoundResultStatus.SUCCESS;
|
||||
import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyListOf;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@ -95,11 +96,8 @@ public class CommandHandlerTest {
|
||||
// then
|
||||
verify(serviceMock).mapPartsToCommand(eq(sender), captor.capture());
|
||||
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
|
||||
|
||||
verify(command, never()).getExecutableCommand();
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(sender).sendMessage(captor.capture());
|
||||
assertThat(captor.getValue(), containsString("don't have permission"));
|
||||
verify(sender).sendMessage(argThat(containsString("don't have permission")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -170,11 +168,8 @@ public class CommandHandlerTest {
|
||||
// then
|
||||
verify(serviceMock).mapPartsToCommand(eq(sender), captor.capture());
|
||||
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
|
||||
|
||||
verify(command, never()).getExecutableCommand();
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(sender).sendMessage(captor.capture());
|
||||
assertThat(captor.getValue(), containsString("Failed to parse"));
|
||||
verify(sender).sendMessage(argThat(containsString("Failed to parse")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -3,7 +3,6 @@ package fr.xephi.authme.command;
|
||||
import fr.xephi.authme.permission.AdminPermission;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -38,7 +37,6 @@ public class CommandInitializerTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeCommandManager() {
|
||||
WrapperMock.createInstance();
|
||||
commands = CommandInitializer.buildCommands();
|
||||
}
|
||||
|
||||
|
||||
@ -13,12 +13,12 @@ import java.util.Set;
|
||||
import static fr.xephi.authme.command.TestCommandsUtil.getCommandWithLabel;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
@ -31,7 +31,7 @@ public class CommandMapperTest {
|
||||
|
||||
private static Set<CommandDescription> commands;
|
||||
private static CommandMapper mapper;
|
||||
private static PermissionsManager permissionsManagerMock;
|
||||
private static PermissionsManager permissionsManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpCommandHandler() {
|
||||
@ -40,8 +40,8 @@ public class CommandMapperTest {
|
||||
|
||||
@Before
|
||||
public void setUpMocks() {
|
||||
permissionsManagerMock = mock(PermissionsManager.class);
|
||||
mapper = new CommandMapper(commands, permissionsManagerMock);
|
||||
permissionsManager = mock(PermissionsManager.class);
|
||||
mapper = new CommandMapper(commands, permissionsManager);
|
||||
}
|
||||
|
||||
// -----------
|
||||
@ -52,7 +52,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("authme", "login", "test1");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -71,7 +71,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("Authme", "REG", "arg1", "arg2");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -89,7 +89,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("authme", "register", "pass123", "pass123", "pass123");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -107,7 +107,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("authme", "Reg");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -125,7 +125,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("authme", "reh", "pass123", "pass123");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -144,7 +144,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("authme", "asdfawetawty4asdca");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -162,7 +162,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = singletonList("unregister");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -180,7 +180,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = asList("bogus", "label1", "arg1");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -205,7 +205,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = asList("Unreg", "player1");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -223,7 +223,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = asList("unregistER", "player1", "wrongArg");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -241,7 +241,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = asList("email", "helptest", "arg1");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
@ -259,7 +259,7 @@ public class CommandMapperTest {
|
||||
// given
|
||||
List<String> parts = Arrays.asList("authme", "login", "test1");
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(permissionsManagerMock.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(false);
|
||||
given(permissionsManager.hasPermission(eq(sender), any(CommandDescription.class))).willReturn(false);
|
||||
|
||||
// when
|
||||
FoundCommandResult result = mapper.mapPartsToCommand(sender, parts);
|
||||
|
||||
@ -2,7 +2,6 @@ package fr.xephi.authme.command;
|
||||
|
||||
import fr.xephi.authme.AntiBot;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
@ -15,6 +14,8 @@ import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Before;
|
||||
@ -27,8 +28,8 @@ import org.mockito.runners.MockitoJUnitRunner;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
@ -56,18 +57,20 @@ public class CommandServiceTest {
|
||||
@Mock
|
||||
private NewSetting settings;
|
||||
@Mock
|
||||
private IpAddressManager ipAddressManager;
|
||||
@Mock
|
||||
private PluginHooks pluginHooks;
|
||||
@Mock
|
||||
private SpawnLoader spawnLoader;
|
||||
@Mock
|
||||
private AntiBot antiBot;
|
||||
@Mock
|
||||
private ValidationService validationService;
|
||||
@Mock
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Before
|
||||
public void setUpService() {
|
||||
commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity,
|
||||
permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot);
|
||||
permissionsManager, settings, pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -221,11 +224,63 @@ public class CommandServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnIpAddressManager() {
|
||||
// given/when
|
||||
IpAddressManager ipManager = commandService.getIpAddressManager();
|
||||
public void shouldValidatePassword() {
|
||||
// given
|
||||
String user = "asdf";
|
||||
String password = "mySecret55";
|
||||
given(validationService.validatePassword(password, user)).willReturn(MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
|
||||
// when
|
||||
MessageKey result = commandService.validatePassword(password, user);
|
||||
|
||||
// then
|
||||
assertThat(ipManager, equalTo(ipAddressManager));
|
||||
assertThat(result, equalTo(MessageKey.INVALID_PASSWORD_LENGTH));
|
||||
verify(validationService).validatePassword(password, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldValidateEmail() {
|
||||
// given
|
||||
String email = "test@example.tld";
|
||||
given(validationService.validateEmail(email)).willReturn(true);
|
||||
|
||||
// when
|
||||
boolean result = commandService.validateEmail(email);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
verify(validationService).validateEmail(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckIfEmailCanBeUsed() {
|
||||
// given
|
||||
String email = "mail@example.com";
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(validationService.isEmailFreeForRegistration(email, sender))
|
||||
.willReturn(true);
|
||||
|
||||
// when
|
||||
boolean result = commandService.isEmailFreeForRegistration(email, sender);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
verify(validationService).isEmailFreeForRegistration(email, sender);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPlayer() {
|
||||
// given
|
||||
String playerName = "_tester";
|
||||
Player player = mock(Player.class);
|
||||
given(bukkitService.getPlayerExact(playerName)).willReturn(player);
|
||||
|
||||
// when
|
||||
Player result = commandService.getPlayer(playerName);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(player));
|
||||
verify(bukkitService).getPlayerExact(playerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,14 +4,13 @@ import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@ -28,12 +27,10 @@ public class PlayerCommandTest {
|
||||
PlayerCommandImpl command = new PlayerCommandImpl();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.<String> emptyList(), mock(CommandService.class));
|
||||
command.executeCommand(sender, Collections.<String>emptyList(), mock(CommandService.class));
|
||||
|
||||
// then
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(sender, times(1)).sendMessage(captor.capture());
|
||||
assertThat(captor.getValue(), containsString("only for players"));
|
||||
verify(sender).sendMessage(argThat(containsString("only for players")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -58,12 +55,10 @@ public class PlayerCommandTest {
|
||||
PlayerCommandWithAlt command = new PlayerCommandWithAlt();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.<String> emptyList(), mock(CommandService.class));
|
||||
command.executeCommand(sender, Collections.<String>emptyList(), mock(CommandService.class));
|
||||
|
||||
// then
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(sender, times(1)).sendMessage(captor.capture());
|
||||
assertThat(captor.getValue(), containsString("use /authme test <command> instead"));
|
||||
verify(sender, times(1)).sendMessage(argThat(containsString("use /authme test <command> instead")));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -14,8 +14,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.TestHelper.runInnerRunnable;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@ -81,7 +81,7 @@ public class AccountsCommandTest {
|
||||
// given
|
||||
List<String> arguments = Collections.singletonList("SomeUser");
|
||||
given(dataSource.getAuth("someuser")).willReturn(mock(PlayerAuth.class));
|
||||
given(dataSource.getAllAuthsByIp(anyString())).willReturn(Collections.<String> emptyList());
|
||||
given(dataSource.getAllAuthsByIp(anyString())).willReturn(Collections.<String>emptyList());
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, arguments, service);
|
||||
@ -115,7 +115,7 @@ public class AccountsCommandTest {
|
||||
public void shouldReturnIpUnknown() {
|
||||
// given
|
||||
List<String> arguments = Collections.singletonList("123.45.67.89");
|
||||
given(dataSource.getAllAuthsByIp("123.45.67.89")).willReturn(Collections.<String> emptyList());
|
||||
given(dataSource.getAllAuthsByIp("123.45.67.89")).willReturn(Collections.<String>emptyList());
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, arguments, service);
|
||||
|
||||
@ -8,7 +8,7 @@ import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
@ -10,12 +9,12 @@ import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -29,97 +28,33 @@ import static org.mockito.Mockito.verify;
|
||||
/**
|
||||
* Test for {@link ChangePasswordAdminCommand}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ChangePasswordAdminCommandTest {
|
||||
|
||||
@Mock
|
||||
private CommandService service;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpLogger() {
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpServiceMock() {
|
||||
service = mock(CommandService.class);
|
||||
given(service.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
|
||||
given(service.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
|
||||
given(service.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20);
|
||||
given(service.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
|
||||
.willReturn(Arrays.asList("unsafe", "otherUnsafe"));
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectPasswordSameAsUsername() {
|
||||
public void shouldRejectInvalidPassword() {
|
||||
// given
|
||||
ExecutableCommand command = new ChangePasswordAdminCommand();
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(service.validatePassword("Bobby", "bobby")).willReturn(MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Arrays.asList("bobby", "Bobby"), service);
|
||||
|
||||
// then
|
||||
verify(service).validatePassword("Bobby", "bobby");
|
||||
verify(service).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
verify(service, never()).getDataSource();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectPasswordNotMatchingPattern() {
|
||||
// given
|
||||
ExecutableCommand command = new ChangePasswordAdminCommand();
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
// service mock returns pattern a-zA-Z -> numbers should not be accepted
|
||||
String invalidPassword = "invalid1234";
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Arrays.asList("myPlayer123", invalidPassword), service);
|
||||
|
||||
// then
|
||||
verify(service).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
verify(service, never()).getDataSource();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectTooShortPassword() {
|
||||
// given
|
||||
ExecutableCommand command = new ChangePasswordAdminCommand();
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Arrays.asList("player", "ab"), service);
|
||||
|
||||
// then
|
||||
verify(service).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
verify(service, never()).getDataSource();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectTooLongPassword() {
|
||||
// given
|
||||
ExecutableCommand command = new ChangePasswordAdminCommand();
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Arrays.asList("player", Strings.repeat("a", 30)), service);
|
||||
|
||||
// then
|
||||
verify(service).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
verify(service, never()).getDataSource();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectUnsafePassword() {
|
||||
// given
|
||||
ExecutableCommand command = new ChangePasswordAdminCommand();
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Arrays.asList("player", "unsafe"), service);
|
||||
|
||||
// then
|
||||
verify(service).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
verify(service, never()).getDataSource();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectCommandForUnknownUser() {
|
||||
// given
|
||||
@ -173,6 +108,7 @@ public class ChangePasswordAdminCommandTest {
|
||||
runInnerRunnable(service);
|
||||
|
||||
// then
|
||||
verify(service).validatePassword(password, player);
|
||||
verify(service).send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
|
||||
verify(passwordSecurity).computeHash(password, player);
|
||||
verify(auth).setPassword(hashedPassword);
|
||||
@ -209,6 +145,7 @@ public class ChangePasswordAdminCommandTest {
|
||||
runInnerRunnable(service);
|
||||
|
||||
// then
|
||||
verify(service).validatePassword(password, player);
|
||||
verify(service).send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
|
||||
verify(passwordSecurity).computeHash(password, player);
|
||||
verify(auth).setPassword(hashedPassword);
|
||||
@ -244,6 +181,7 @@ public class ChangePasswordAdminCommandTest {
|
||||
runInnerRunnable(service);
|
||||
|
||||
// then
|
||||
verify(service).validatePassword(password, player);
|
||||
verify(service).send(sender, MessageKey.ERROR);
|
||||
verify(passwordSecurity).computeHash(password, player);
|
||||
verify(auth).setPassword(hashedPassword);
|
||||
|
||||
@ -6,14 +6,13 @@ import fr.xephi.authme.settings.SpawnLoader;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@ -36,7 +35,7 @@ public class FirstSpawnCommandTest {
|
||||
ExecutableCommand command = new FirstSpawnCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.<String> emptyList(), service);
|
||||
command.executeCommand(player, Collections.<String>emptyList(), service);
|
||||
|
||||
// then
|
||||
verify(player).teleport(firstSpawn);
|
||||
@ -54,12 +53,10 @@ public class FirstSpawnCommandTest {
|
||||
ExecutableCommand command = new FirstSpawnCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.<String> emptyList(), service);
|
||||
command.executeCommand(player, Collections.<String>emptyList(), service);
|
||||
|
||||
// then
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(player).sendMessage(captor.capture());
|
||||
assertThat(captor.getValue(), containsString("spawn has failed"));
|
||||
verify(player).sendMessage(argThat(containsString("spawn has failed")));
|
||||
verify(player, never()).teleport(any(Location.class));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,146 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Test for {@link ForceLoginCommand}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ForceLoginCommandTest {
|
||||
|
||||
@Mock
|
||||
private CommandService commandService;
|
||||
|
||||
@Test
|
||||
public void shouldRejectOfflinePlayer() {
|
||||
// given
|
||||
String playerName = "Bobby";
|
||||
Player player = mockPlayer(false, playerName);
|
||||
given(commandService.getPlayer(playerName)).willReturn(player);
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
ExecutableCommand command = new ForceLoginCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(playerName), commandService);
|
||||
|
||||
// then
|
||||
verify(commandService).getPlayer(playerName);
|
||||
verify(sender).sendMessage(argThat(equalTo("Player needs to be online!")));
|
||||
verify(commandService, never()).getManagement();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectInexistentPlayer() {
|
||||
// given
|
||||
String playerName = "us3rname01";
|
||||
given(commandService.getPlayer(playerName)).willReturn(null);
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
ExecutableCommand command = new ForceLoginCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(playerName), commandService);
|
||||
|
||||
// then
|
||||
verify(commandService).getPlayer(playerName);
|
||||
verify(sender).sendMessage(argThat(equalTo("Player needs to be online!")));
|
||||
verify(commandService, never()).getManagement();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectPlayerWithMissingPermission() {
|
||||
// given
|
||||
String playerName = "testTest";
|
||||
Player player = mockPlayer(true, playerName);
|
||||
given(commandService.getPlayer(playerName)).willReturn(player);
|
||||
PermissionsManager permissionsManager = mock(PermissionsManager.class);
|
||||
given(permissionsManager.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)).willReturn(false);
|
||||
given(commandService.getPermissionsManager()).willReturn(permissionsManager);
|
||||
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
ExecutableCommand command = new ForceLoginCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(playerName), commandService);
|
||||
|
||||
// then
|
||||
verify(commandService).getPlayer(playerName);
|
||||
verify(sender).sendMessage(argThat(containsString("You cannot force login the player")));
|
||||
verify(commandService, never()).getManagement();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldForceLoginPlayer() {
|
||||
// given
|
||||
String playerName = "tester23";
|
||||
Player player = mockPlayer(true, playerName);
|
||||
given(commandService.getPlayer(playerName)).willReturn(player);
|
||||
PermissionsManager permissionsManager = mock(PermissionsManager.class);
|
||||
given(permissionsManager.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)).willReturn(true);
|
||||
given(commandService.getPermissionsManager()).willReturn(permissionsManager);
|
||||
Management management = mock(Management.class);
|
||||
given(commandService.getManagement()).willReturn(management);
|
||||
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
ExecutableCommand command = new ForceLoginCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(playerName), commandService);
|
||||
|
||||
// then
|
||||
verify(commandService).getPlayer(playerName);
|
||||
verify(management).performLogin(eq(player), anyString(), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldForceLoginSenderSelf() {
|
||||
// given
|
||||
String senderName = "tester23";
|
||||
Player player = mockPlayer(true, senderName);
|
||||
given(commandService.getPlayer(senderName)).willReturn(player);
|
||||
PermissionsManager permissionsManager = mock(PermissionsManager.class);
|
||||
given(permissionsManager.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)).willReturn(true);
|
||||
given(commandService.getPermissionsManager()).willReturn(permissionsManager);
|
||||
Management management = mock(Management.class);
|
||||
given(commandService.getManagement()).willReturn(management);
|
||||
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
given(sender.getName()).willReturn(senderName);
|
||||
ExecutableCommand command = new ForceLoginCommand();
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.<String>emptyList(), commandService);
|
||||
|
||||
// then
|
||||
verify(commandService).getPlayer(senderName);
|
||||
verify(management).performLogin(eq(player), anyString(), eq(true));
|
||||
}
|
||||
|
||||
private static Player mockPlayer(boolean isOnline, String name) {
|
||||
Player player = mock(Player.class);
|
||||
given(player.isOnline()).willReturn(isOnline);
|
||||
given(player.getName()).willReturn(name);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@ -7,13 +7,12 @@ import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@ -61,8 +60,6 @@ public class GetEmailCommandTest {
|
||||
command.executeCommand(sender, Collections.singletonList(user), service);
|
||||
|
||||
// then
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(sender).sendMessage(captor.capture());
|
||||
assertThat(captor.getValue(), containsString(email));
|
||||
verify(sender).sendMessage(argThat(containsString(email)));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user