mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-09-06 20:28:06 +02:00
commit
b9b5cba94e
@ -58,7 +58,7 @@ McStats: http://mcstats.org/plugin/AuthMe
|
||||
|
||||
#####"The best authentication plugin for the Bukkit/Spigot API!"
|
||||
|
||||
<p>Prevent username stealing on your server! Fully compatible with UUIDs and Craftbukkit/Spigot 1.8.X!<br>
|
||||
<p>Prevent username stealing on your server!<br>
|
||||
Use it to secure your Offline mode server or to increase your Online mode server's protection!</p>
|
||||
|
||||
<p>AuthMeReloaded disallows players who aren't authenticated to do actions like placing blocks, moving,<br>
|
||||
|
157
pom.xml
157
pom.xml
@ -48,22 +48,25 @@
|
||||
</prerequisites>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<!-- Project Properties -->
|
||||
<projectEncoding>UTF-8</projectEncoding>
|
||||
<project.build.sourceEncoding>${projectEncoding}</project.build.sourceEncoding>
|
||||
<project.build.outputEncoding>${projectEncoding}</project.build.outputEncoding>
|
||||
<jdkVersion>1.7</jdkVersion>
|
||||
<testJreVersion>1.7</testJreVersion>
|
||||
|
||||
<!-- Output properties -->
|
||||
<pluginName>AuthMe</pluginName>
|
||||
<jarName>${pluginName}-${project.version}</jarName>
|
||||
<mainClass>fr.xephi.authme.AuthMe</mainClass>
|
||||
<mainClass>${project.groupId}.${project.artifactId}.${pluginName}</mainClass>
|
||||
<pluginAuthors>Xephi, sgdc3, DNx5, timvisee, games647, ljacqu</pluginAuthors>
|
||||
<buildNumber>Unknown</buildNumber>
|
||||
|
||||
<!-- Change Compiler Version (JDK) HERE! -->
|
||||
<javaVersion>1.7</javaVersion>
|
||||
|
||||
<!-- Change Bukkit Version HERE! -->
|
||||
<bukkitVersion>1.9-pre1-SNAPSHOT</bukkitVersion>
|
||||
<bukkitVersion>1.9-SNAPSHOT</bukkitVersion>
|
||||
</properties>
|
||||
|
||||
<!-- Jenkins profile (add the real buildNumber to the version string) -->
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jenkins</id>
|
||||
@ -84,33 +87,21 @@
|
||||
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>email.html</include>
|
||||
<include>welcome.txt</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>false</filtering>
|
||||
<directory>.</directory>
|
||||
<includes>
|
||||
<include>LICENSE</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>*.yml</include>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>plugin.yml</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>./messages/</targetPath>
|
||||
@ -128,15 +119,28 @@
|
||||
</testResources>
|
||||
|
||||
<plugins>
|
||||
<!-- Maven Java Compiler -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>${javaVersion}</target>
|
||||
<source>${jdkVersion}</source>
|
||||
<target>${jdkVersion}</target>
|
||||
<testSource>${testJreVersion}</testSource>
|
||||
<testTarget>${testJreVersion}</testTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Test Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.19.1</version>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=${projectEncoding} ${argLine}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Libs Shading and Relocation -->
|
||||
<plugin>
|
||||
<!--Relocate all lib we use in order to fix class loading errors if we use different versions
|
||||
than already loaded libs (i.e. by Mojang -> gson)-->
|
||||
@ -161,33 +165,11 @@
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<!--We use a newer version of gson so include it to the jar and reference to the new version-->
|
||||
<!-- We use a newer version of gson so we need to include it! -->
|
||||
<relocation>
|
||||
<pattern>com.google.gson</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.google</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>fr.xephi.authme</shadedPattern>
|
||||
</relocation>
|
||||
<!--
|
||||
<relocation>
|
||||
<pattern>org.apache</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.apache</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>javax.mail</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.javax.mail</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>javax.activation</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.javax.activation</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.sun</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.sun</shadedPattern>
|
||||
</relocation>
|
||||
-->
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.hikari</shadedPattern>
|
||||
@ -204,6 +186,11 @@
|
||||
<pattern>net.ricecode.similarity</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.similarity</shadedPattern>
|
||||
</relocation>
|
||||
<!-- MCStats.org metrics -->
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>fr.xephi.authme</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<outputFile>target/${jarName}-spigot.jar</outputFile>
|
||||
</configuration>
|
||||
@ -215,34 +202,12 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!--Include all google libraries, because they are not avaialbe before 1.8-->
|
||||
<!-- Include all google libraries, because they are not available before 1.8 -->
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>com.google</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.google</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>fr.xephi.authme</shadedPattern>
|
||||
</relocation>
|
||||
<!--
|
||||
<relocation>
|
||||
<pattern>org.apache</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.apache</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>javax.mail</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.javax.mail</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>javax.activation</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.javax.activation</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.sun</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.sun</shadedPattern>
|
||||
</relocation>
|
||||
-->
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.hikari</shadedPattern>
|
||||
@ -259,16 +224,22 @@
|
||||
<pattern>net.ricecode.similarity</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.similarity</shadedPattern>
|
||||
</relocation>
|
||||
<!-- MCStats.org metrics -->
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>fr.xephi.authme</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<outputFile>target/${jarName}-legacy.jar</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Test coverage -->
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.7.5.201505241946</version>
|
||||
<version>0.7.6.201602180812</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-agent</id>
|
||||
@ -278,11 +249,12 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Coveralls data -->
|
||||
<plugin>
|
||||
<groupId>org.eluder.coveralls</groupId>
|
||||
<artifactId>coveralls-maven-plugin</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<!-- Token is provided by mvn command -->
|
||||
<!-- The secret token is provided by console! -->
|
||||
</plugin>
|
||||
<!-- Javadocs settings -->
|
||||
<plugin>
|
||||
@ -292,7 +264,10 @@
|
||||
<configuration>
|
||||
<charset>UTF-8</charset>
|
||||
<docencoding>UTF-8</docencoding>
|
||||
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
|
||||
<docfilessubdirs>true</docfilessubdirs>
|
||||
<show>public</show>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
@ -305,10 +280,10 @@
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
|
||||
</repository>
|
||||
|
||||
<!-- EssentialsX Repo -->
|
||||
<!-- Essentials Repo -->
|
||||
<repository>
|
||||
<id>ess-repo</id>
|
||||
<url>http://ci.drtshock.net/plugin/repository/everything</url>
|
||||
<url>http://repo.ess3.net/content/groups/essentials</url>
|
||||
</repository>
|
||||
|
||||
<!-- CombatTagPlus Repo -->
|
||||
@ -359,7 +334,7 @@
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<version>2.4.5-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -372,7 +347,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.7.16</version>
|
||||
<version>1.7.18</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@ -413,7 +388,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<version>2.6.2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@ -664,16 +639,20 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- EssentialsX plugin, http://www.spigotmc.org/resources/essentialsx.9089/ -->
|
||||
<!-- Essentials plugin -->
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>EssentialsX</artifactId>
|
||||
<version>2.0.1-SNAPSHOT</version>
|
||||
<artifactId>Essentials</artifactId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
@ -683,7 +662,7 @@
|
||||
<dependency>
|
||||
<groupId>net.minelink</groupId>
|
||||
<artifactId>CombatTagPlus</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
@ -42,14 +42,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.process.ProcessService;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.SHA256;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.OtherAccounts;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SettingsMigrationService;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
@ -64,7 +65,6 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -76,6 +76,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
@ -104,15 +105,14 @@ public class AuthMe extends JavaPlugin {
|
||||
// Private Instances
|
||||
private static AuthMe plugin;
|
||||
private static Server server;
|
||||
private Management management;
|
||||
private CommandHandler commandHandler = null;
|
||||
private PermissionsManager permsMan = null;
|
||||
private NewSetting newSettings;
|
||||
private Messages messages;
|
||||
private JsonCache playerBackup;
|
||||
private PasswordSecurity passwordSecurity;
|
||||
private DataSource database;
|
||||
|
||||
/*
|
||||
* Maps and stuff
|
||||
* TODO: Clean up and Move into a manager
|
||||
*/
|
||||
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 final ConcurrentHashMap<String, String> realIp = new ConcurrentHashMap<>();
|
||||
/*
|
||||
* Public Instances
|
||||
* TODO #432: Encapsulation
|
||||
@ -120,9 +120,7 @@ public class AuthMe extends JavaPlugin {
|
||||
public NewAPI api;
|
||||
public SendMailSSL mail;
|
||||
public DataManager dataManager;
|
||||
public OtherAccounts otherAccounts;
|
||||
public Location essentialsSpawn;
|
||||
|
||||
/*
|
||||
* Plugin Hooks
|
||||
* TODO: Move into modules
|
||||
@ -133,15 +131,14 @@ public class AuthMe extends JavaPlugin {
|
||||
public AuthMeInventoryPacketAdapter inventoryProtector;
|
||||
public AuthMeTabCompletePacketAdapter tabComplete;
|
||||
public AuthMeTablistPacketAdapter tablistHider;
|
||||
|
||||
/*
|
||||
* Maps and stuff
|
||||
* TODO: Clean up and Move into a manager
|
||||
*/
|
||||
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 final ConcurrentHashMap<String, String> realIp = new ConcurrentHashMap<>();
|
||||
private Management management;
|
||||
private CommandHandler commandHandler = null;
|
||||
private PermissionsManager permsMan = null;
|
||||
private NewSetting newSettings;
|
||||
private Messages messages;
|
||||
private JsonCache playerBackup;
|
||||
private PasswordSecurity passwordSecurity;
|
||||
private DataSource database;
|
||||
|
||||
/**
|
||||
* Get the plugin's instance.
|
||||
@ -259,9 +256,6 @@ public class AuthMe extends JavaPlugin {
|
||||
permsMan = initializePermissionsManager();
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings);
|
||||
|
||||
// Setup otherAccounts file
|
||||
this.otherAccounts = OtherAccounts.getInstance();
|
||||
|
||||
// Set up Metrics
|
||||
MetricsStarter.setupMetrics(plugin, newSettings);
|
||||
|
||||
@ -306,7 +300,8 @@ public class AuthMe extends JavaPlugin {
|
||||
setupApi();
|
||||
|
||||
// Set up the management
|
||||
management = new Management(this, newSettings);
|
||||
ProcessService processService = new ProcessService(newSettings, messages, this);
|
||||
management = new Management(this, processService, database, PlayerCache.getInstance());
|
||||
|
||||
// Set up the BungeeCord hook
|
||||
setupBungeeCordHook();
|
||||
@ -494,11 +489,41 @@ public class AuthMe extends JavaPlugin {
|
||||
if (newSettings != null) {
|
||||
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.STOP);
|
||||
}
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Integer> pendingTasks = new ArrayList<>();
|
||||
for (BukkitTask pendingTask : getServer().getScheduler().getPendingTasks()) {
|
||||
if (pendingTask.getOwner().equals(plugin) && !pendingTask.isSync()) {
|
||||
pendingTasks.add(pendingTask.getTaskId());
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("Waiting for " + pendingTasks.size() + " tasks to finish");
|
||||
int progress = 0;
|
||||
for (int taskId : pendingTasks) {
|
||||
int maxTries = 5;
|
||||
while (getServer().getScheduler().isCurrentlyRunning(taskId)) {
|
||||
if (maxTries <= 0) {
|
||||
ConsoleLogger.info("Async task " + taskId + " times out after to many tries");
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
maxTries--;
|
||||
}
|
||||
|
||||
progress++;
|
||||
ConsoleLogger.info("Progress: " + progress + " / " + pendingTasks.size());
|
||||
}
|
||||
if (database != null) {
|
||||
database.close();
|
||||
}
|
||||
}
|
||||
}, "AuthMe-DataSource#close").start();
|
||||
|
||||
// Close the database
|
||||
if (database != null) {
|
||||
database.close();
|
||||
}
|
||||
|
||||
// Disabled correctly
|
||||
ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!");
|
||||
@ -518,7 +543,10 @@ public class AuthMe extends JavaPlugin {
|
||||
* Sets up the data source.
|
||||
*
|
||||
* @param settings The settings instance
|
||||
*
|
||||
* @see AuthMe#database
|
||||
* @throws ClassNotFoundException if no driver could be found for the datasource
|
||||
* @throws SQLException when initialization of a SQL datasource failed
|
||||
*/
|
||||
public void setupDatabase(NewSetting settings) throws ClassNotFoundException, SQLException {
|
||||
if (this.database != null) {
|
||||
@ -653,6 +681,7 @@ public class AuthMe extends JavaPlugin {
|
||||
ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
|
||||
Settings.protectInventoryBeforeLogInEnabled = false;
|
||||
newSettings.setProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN, false);
|
||||
newSettings.save();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -667,14 +696,14 @@ public class AuthMe extends JavaPlugin {
|
||||
if (newSettings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN) && tabComplete == null) {
|
||||
tabComplete = new AuthMeTabCompletePacketAdapter(this);
|
||||
tabComplete.register();
|
||||
} else if (inventoryProtector != null) {
|
||||
} else if (tabComplete != null) {
|
||||
tabComplete.unregister();
|
||||
tabComplete = null;
|
||||
}
|
||||
if (newSettings.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN) && tablistHider == null) {
|
||||
tablistHider = new AuthMeTablistPacketAdapter(this);
|
||||
tablistHider.register();
|
||||
} else if (inventoryProtector != null) {
|
||||
} else if (tablistHider != null) {
|
||||
tablistHider.unregister();
|
||||
tablistHider = null;
|
||||
}
|
||||
@ -748,42 +777,6 @@ public class AuthMe extends JavaPlugin {
|
||||
return Spawn.getInstance().getSpawnLocation(player);
|
||||
}
|
||||
|
||||
// Return the default spawn point of a world
|
||||
private Location getDefaultSpawn(World world) {
|
||||
return world.getSpawnLocation();
|
||||
}
|
||||
|
||||
// Return the multiverse spawn point of a world
|
||||
private Location getMultiverseSpawn(World world) {
|
||||
if (multiverse != null && Settings.multiverse) {
|
||||
try {
|
||||
return multiverse.getMVWorldManager().getMVWorld(world).getSpawnLocation();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return the essentials spawn point
|
||||
private Location getEssentialsSpawn() {
|
||||
if (essentialsSpawn != null) {
|
||||
return essentialsSpawn;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return the AuthMe spawn point
|
||||
private Location getAuthMeSpawn(Player player) {
|
||||
if ((!database.isAuthAvailable(player.getName().toLowerCase()) || !player.hasPlayedBefore())
|
||||
&& (Spawn.getInstance().getFirstSpawn() != null)) {
|
||||
return Spawn.getInstance().getFirstSpawn();
|
||||
} else if (Spawn.getInstance().getSpawn() != null) {
|
||||
return Spawn.getInstance().getSpawn();
|
||||
}
|
||||
return player.getWorld().getSpawnLocation();
|
||||
}
|
||||
|
||||
private void scheduleRecallEmailTask() {
|
||||
if (!newSettings.getProperty(RECALL_PLAYERS)) {
|
||||
return;
|
||||
@ -793,7 +786,7 @@ public class AuthMe extends JavaPlugin {
|
||||
public void run() {
|
||||
for (PlayerAuth auth : database.getLoggedPlayers()) {
|
||||
String email = auth.getEmail();
|
||||
if (email == null || email.isEmpty() || email.equalsIgnoreCase("your@email.com")) {
|
||||
if (StringUtils.isEmpty(email) || email.equalsIgnoreCase("your@email.com")) {
|
||||
Player player = Utils.getPlayer(auth.getRealName());
|
||||
if (player != null) {
|
||||
messages.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
@ -801,7 +794,7 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1, 1200 * Settings.delayRecall);
|
||||
}, 1, 1200 * newSettings.getProperty(EmailSettings.DELAY_RECALL));
|
||||
}
|
||||
|
||||
public String replaceAllInfo(String message, Player player) {
|
||||
@ -863,15 +856,6 @@ public class AuthMe extends JavaPlugin {
|
||||
return count >= Settings.getMaxLoginPerIp;
|
||||
}
|
||||
|
||||
public boolean hasJoinedIp(String name, String ip) {
|
||||
int count = 0;
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(getIP(player)) && !player.getName().equalsIgnoreCase(name))
|
||||
count++;
|
||||
}
|
||||
return count >= Settings.getMaxJoinPerIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Bukkit commands.
|
||||
*
|
||||
|
@ -13,7 +13,10 @@ import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
|
||||
/**
|
||||
* The current API of AuthMe.
|
||||
* The current API of AuthMe. Recommended method of retrieving the API object:
|
||||
* <code>
|
||||
* NewAPI authmeApi = NewAPI.getInstance();
|
||||
* </code>
|
||||
*/
|
||||
public class NewAPI {
|
||||
|
||||
@ -23,7 +26,7 @@ public class NewAPI {
|
||||
/**
|
||||
* Constructor for NewAPI.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
* @param plugin The AuthMe plugin instance
|
||||
*/
|
||||
public NewAPI(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
@ -32,16 +35,17 @@ public class NewAPI {
|
||||
/**
|
||||
* Constructor for NewAPI.
|
||||
*
|
||||
* @param server Server
|
||||
* @param server The server instance
|
||||
*/
|
||||
public NewAPI(Server server) {
|
||||
this.plugin = (AuthMe) server.getPluginManager().getPlugin("AuthMe");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into AuthMe
|
||||
* Get the API object for AuthMe.
|
||||
*
|
||||
* @return The API object
|
||||
* @return The API object, or null if the AuthMe plugin instance could not be retrieved
|
||||
* from the server environment
|
||||
*/
|
||||
public static NewAPI getInstance() {
|
||||
if (singleton != null) {
|
||||
@ -69,7 +73,6 @@ public class NewAPI {
|
||||
* Return whether the given player is authenticated.
|
||||
*
|
||||
* @param player The player to verify
|
||||
*
|
||||
* @return true if the player is authenticated
|
||||
*/
|
||||
public boolean isAuthenticated(Player player) {
|
||||
@ -77,18 +80,22 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player a Player
|
||||
* Check whether the given player is an NPC.
|
||||
*
|
||||
* @return true if player is a npc
|
||||
* @param player The player to verify
|
||||
* @return true if the player is an npc
|
||||
*/
|
||||
public boolean isNPC(Player player) {
|
||||
return Utils.isNPC(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player a Player
|
||||
* Check whether the given player is unrestricted. For such players, AuthMe will not require
|
||||
* them to authenticate.
|
||||
*
|
||||
* @param player The player to verify
|
||||
* @return true if the player is unrestricted
|
||||
* @see fr.xephi.authme.settings.properties.RestrictionSettings#UNRESTRICTED_NAMES
|
||||
*/
|
||||
public boolean isUnrestricted(Player player) {
|
||||
return Utils.isUnrestricted(player);
|
||||
@ -97,30 +104,21 @@ public class NewAPI {
|
||||
/**
|
||||
* Get the last location of a player.
|
||||
*
|
||||
* @param player Player The player to process
|
||||
*
|
||||
* @param player The player to process
|
||||
* @return Location The location of the player
|
||||
*/
|
||||
public Location getLastLocation(Player player) {
|
||||
try {
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName());
|
||||
|
||||
if (auth != null) {
|
||||
return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (NullPointerException ex) {
|
||||
return null;
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName());
|
||||
if (auth != null) {
|
||||
return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the player is registered.
|
||||
*
|
||||
* @param playerName The player name to check
|
||||
*
|
||||
* @return true if player is registered, false otherwise
|
||||
*/
|
||||
public boolean isRegistered(String playerName) {
|
||||
@ -133,7 +131,6 @@ public class NewAPI {
|
||||
*
|
||||
* @param playerName The player to check the password for
|
||||
* @param passwordToCheck The password to check
|
||||
*
|
||||
* @return true if the password is correct, false otherwise
|
||||
*/
|
||||
public boolean checkPassword(String playerName, String passwordToCheck) {
|
||||
@ -141,11 +138,10 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a player.
|
||||
* Register a player with the given password.
|
||||
*
|
||||
* @param playerName The player to register
|
||||
* @param password The password to register the player with
|
||||
*
|
||||
* @return true if the player was registered successfully
|
||||
*/
|
||||
public boolean registerPlayer(String playerName, String password) {
|
||||
@ -163,7 +159,7 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a player to login.
|
||||
* Force a player to login, i.e. the player is logged in without needing his password.
|
||||
*
|
||||
* @param player The player to log in
|
||||
*/
|
||||
@ -181,7 +177,7 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a player to register.
|
||||
* Register a player with the given password.
|
||||
*
|
||||
* @param player The player to register
|
||||
* @param password The password to use
|
||||
@ -191,7 +187,7 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a player to unregister.
|
||||
* Unregister a player from AuthMe.
|
||||
*
|
||||
* @param player The player to unregister
|
||||
*/
|
||||
|
@ -8,7 +8,6 @@ import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
@ -41,14 +40,8 @@ public class JsonCache {
|
||||
return;
|
||||
}
|
||||
|
||||
String path;
|
||||
try {
|
||||
path = player.getUniqueId().toString();
|
||||
} catch (Exception | Error e) {
|
||||
path = player.getName().toLowerCase();
|
||||
}
|
||||
|
||||
File file = new File(cacheDir, path + File.separator + "cache.json");
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(cacheDir, name + File.separator + "cache.json");
|
||||
if (file.exists()) {
|
||||
return;
|
||||
}
|
||||
@ -61,19 +54,13 @@ public class JsonCache {
|
||||
Files.touch(file);
|
||||
Files.write(data, file, Charsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerData readCache(Player player) {
|
||||
String path;
|
||||
try {
|
||||
path = player.getUniqueId().toString();
|
||||
} catch (Exception | Error e) {
|
||||
path = player.getName().toLowerCase();
|
||||
}
|
||||
|
||||
File file = new File(cacheDir, path + File.separator + "cache.json");
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(cacheDir, name + File.separator + "cache.json");
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
@ -81,20 +68,15 @@ public class JsonCache {
|
||||
try {
|
||||
String str = Files.toString(file, Charsets.UTF_8);
|
||||
return gson.fromJson(str, PlayerData.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCache(Player player) {
|
||||
String path;
|
||||
try {
|
||||
path = player.getUniqueId().toString();
|
||||
} catch (Exception | Error e) {
|
||||
path = player.getName().toLowerCase();
|
||||
}
|
||||
File file = new File(cacheDir, path);
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(cacheDir, name);
|
||||
if (file.exists()) {
|
||||
purgeDirectory(file);
|
||||
if (!file.delete()) {
|
||||
@ -104,19 +86,15 @@ public class JsonCache {
|
||||
}
|
||||
|
||||
public boolean doesCacheExist(Player player) {
|
||||
String path;
|
||||
try {
|
||||
path = player.getUniqueId().toString();
|
||||
} catch (Exception | Error e) {
|
||||
path = player.getName().toLowerCase();
|
||||
}
|
||||
File file = new File(cacheDir, path + File.separator + "cache.json");
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(cacheDir, name + File.separator + "cache.json");
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
private class PlayerDataDeserializer implements JsonDeserializer<PlayerData> {
|
||||
@Override
|
||||
public PlayerData deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
public PlayerData deserialize(JsonElement jsonElement, Type type,
|
||||
JsonDeserializationContext context) {
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject == null) {
|
||||
return null;
|
||||
@ -143,7 +121,7 @@ public class JsonCache {
|
||||
private class PlayerDataSerializer implements JsonSerializer<PlayerData> {
|
||||
@Override
|
||||
public JsonElement serialize(PlayerData playerData, Type type,
|
||||
JsonSerializationContext jsonSerializationContext) {
|
||||
JsonSerializationContext context) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("group", playerData.getGroup());
|
||||
jsonObject.addProperty("operator", playerData.getOperator());
|
||||
|
@ -92,7 +92,7 @@ public final class CommandInitializer {
|
||||
.description("Enforce login player")
|
||||
.detailedDescription("Enforce the specified player to login.")
|
||||
.withArgument("player", "Online player name", true)
|
||||
.permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED)
|
||||
.permissions(OP_ONLY, AdminPermission.FORCE_LOGIN)
|
||||
.executableCommand(new ForceLoginCommand())
|
||||
.build();
|
||||
|
||||
|
@ -22,8 +22,8 @@ public class RegisterAdminCommand implements ExecutableCommand {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments,
|
||||
final CommandService commandService) {
|
||||
// Get the player name and password
|
||||
final String playerName = arguments.get(0).toLowerCase();
|
||||
final String playerPass = arguments.get(1).toLowerCase();
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerPass = arguments.get(1);
|
||||
final String playerNameLowerCase = playerName.toLowerCase();
|
||||
final String playerPassLowerCase = playerPass.toLowerCase();
|
||||
|
||||
|
@ -1,14 +1,5 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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 fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
@ -20,6 +11,14 @@ import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Admin command to unregister a player.
|
||||
@ -55,19 +54,20 @@ public class UnregisterAdminCommand implements ExecutableCommand {
|
||||
if (target != null && target.isOnline()) {
|
||||
Utils.teleportToSpawn(target);
|
||||
LimboCache.getInstance().addLimboPlayer(target);
|
||||
int delay = Settings.getRegistrationTimeout * 20;
|
||||
int timeOut = Settings.getRegistrationTimeout * 20;
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler scheduler = sender.getServer().getScheduler();
|
||||
if (delay != 0) {
|
||||
BukkitTask id = scheduler.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, playerNameLowerCase, target), delay);
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, playerNameLowerCase, target), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTaskId(id);
|
||||
}
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTaskId(
|
||||
scheduler.runTaskAsynchronously(plugin,
|
||||
new MessageTask(plugin, playerNameLowerCase, commandService.retrieveMessage(MessageKey.REGISTER_MESSAGE), interval)));
|
||||
scheduler.runTask(
|
||||
plugin, new MessageTask(plugin, playerNameLowerCase, MessageKey.REGISTER_MESSAGE, interval)
|
||||
)
|
||||
);
|
||||
if (Settings.applyBlindEffect) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,
|
||||
Settings.getRegistrationTimeout * 20, 2));
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
}
|
||||
commandService.send(target, MessageKey.UNREGISTERED_SUCCESS);
|
||||
}
|
||||
|
@ -3,14 +3,14 @@ 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 org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class VersionCommand implements ExecutableCommand {
|
||||
|
||||
@ -73,7 +73,7 @@ public class VersionCommand implements ExecutableCommand {
|
||||
private static boolean isPlayerOnline(String minecraftName) {
|
||||
// Note ljacqu 20151121: Generally you should use Utils#getOnlinePlayers to retrieve the list of online players.
|
||||
// If it's only used in a for-each loop such as here, it's fine. For other purposes, go through the Utils class.
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (player.getName().equalsIgnoreCase(minecraftName)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -3,39 +3,51 @@ package fr.xephi.authme.converter;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import java.sql.SQLException;
|
||||
import fr.xephi.authme.datasource.FlatFile;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mandatory migration from the deprecated flat file datasource to SQLite.
|
||||
*/
|
||||
public class ForceFlatToSqlite {
|
||||
public class ForceFlatToSqlite implements Converter {
|
||||
|
||||
private final DataSource database;
|
||||
private final NewSetting settings;
|
||||
private final DataSource source;
|
||||
private final DataSource destination;
|
||||
|
||||
public ForceFlatToSqlite(DataSource database, NewSetting settings) {
|
||||
this.database = database;
|
||||
this.settings = settings;
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param source The datasource to convert (flatfile)
|
||||
* @param destination The datasource to copy the data to (sqlite)
|
||||
*/
|
||||
public ForceFlatToSqlite(FlatFile source, DataSource destination) {
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public DataSource run() {
|
||||
try {
|
||||
DataSource sqlite = new SQLite(settings);
|
||||
for (PlayerAuth auth : database.getAllAuths()) {
|
||||
auth.setRealName("Player");
|
||||
sqlite.saveAuth(auth);
|
||||
/**
|
||||
* Perform the conversion.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
List<String> skippedPlayers = new ArrayList<>();
|
||||
for (PlayerAuth auth : source.getAllAuths()) {
|
||||
if (destination.isAuthAvailable(auth.getNickname())) {
|
||||
skippedPlayers.add(auth.getNickname());
|
||||
} else {
|
||||
destination.saveAuth(auth);
|
||||
destination.updateQuitLoc(auth);
|
||||
}
|
||||
settings.setProperty(DatabaseSettings.BACKEND, DataSourceType.SQLITE);
|
||||
settings.save();
|
||||
ConsoleLogger.info("Database successfully converted to sqlite!");
|
||||
return sqlite;
|
||||
} catch (SQLException | ClassNotFoundException e) {
|
||||
ConsoleLogger.logException("Could not convert from Flatfile to SQLite:", e);
|
||||
}
|
||||
return null;
|
||||
|
||||
if (!skippedPlayers.isEmpty()) {
|
||||
ConsoleLogger.showError("Warning: skipped conversion for players which were already in SQLite: "
|
||||
+ StringUtils.join(", ", skippedPlayers));
|
||||
}
|
||||
ConsoleLogger.info("Database successfully converted from " + source.getClass().getSimpleName()
|
||||
+ " to " + destination.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,19 @@ import com.google.common.base.Optional;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.cache.RemovalListener;
|
||||
import com.google.common.cache.RemovalNotification;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -20,6 +25,7 @@ public class CacheDataSource implements DataSource {
|
||||
|
||||
private final DataSource source;
|
||||
private final LoadingCache<String, Optional<PlayerAuth>> cachedAuths;
|
||||
private final ListeningExecutorService executorService;
|
||||
|
||||
/**
|
||||
* Constructor for CacheDataSource.
|
||||
@ -27,25 +33,35 @@ public class CacheDataSource implements DataSource {
|
||||
* @param src DataSource
|
||||
*/
|
||||
public CacheDataSource(DataSource src) {
|
||||
this.source = src;
|
||||
this.cachedAuths = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(8, TimeUnit.MINUTES)
|
||||
.removalListener(new RemovalListener<String, Optional<PlayerAuth>>() {
|
||||
source = src;
|
||||
executorService = MoreExecutors.listeningDecorator(
|
||||
Executors.newCachedThreadPool(new ThreadFactoryBuilder()
|
||||
.setDaemon(true)
|
||||
.setNameFormat("AuthMe-CacheLoader")
|
||||
.build())
|
||||
);
|
||||
cachedAuths = CacheBuilder.newBuilder()
|
||||
.refreshAfterWrite(8, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<String, Optional<PlayerAuth>>() {
|
||||
@Override
|
||||
public void onRemoval(RemovalNotification<String, Optional<PlayerAuth>> removalNotification) {
|
||||
String name = removalNotification.getKey();
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
cachedAuths.getUnchecked(name);
|
||||
}
|
||||
public Optional<PlayerAuth> load(String key) {
|
||||
return Optional.fromNullable(source.getAuth(key));
|
||||
}
|
||||
})
|
||||
.build(
|
||||
new CacheLoader<String, Optional<PlayerAuth>>() {
|
||||
@Override
|
||||
public Optional<PlayerAuth> load(String key) {
|
||||
return Optional.fromNullable(source.getAuth(key));
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public ListenableFuture<Optional<PlayerAuth>> reload(final String key, Optional<PlayerAuth> oldValue) {
|
||||
return executorService.submit(new Callable<Optional<PlayerAuth>>() {
|
||||
@Override
|
||||
public Optional<PlayerAuth> call() {
|
||||
return load(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public LoadingCache<String, Optional<PlayerAuth>> getCachedAuths() {
|
||||
return cachedAuths;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -137,6 +153,13 @@ public class CacheDataSource implements DataSource {
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
source.close();
|
||||
cachedAuths.invalidateAll();
|
||||
executorService.shutdown();
|
||||
try {
|
||||
executorService.awaitTermination(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -201,12 +224,6 @@ public class CacheDataSource implements DataSource {
|
||||
return source.getAccountsRegistered();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateName(final String oldOne, final String newOne) { // unused method
|
||||
source.updateName(oldOne, newOne);
|
||||
cachedAuths.invalidate(oldOne);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateRealName(String user, String realName) {
|
||||
boolean result = source.updateRealName(user, realName);
|
||||
|
@ -169,14 +169,6 @@ public interface DataSource {
|
||||
*/
|
||||
int getAccountsRegistered();
|
||||
|
||||
/**
|
||||
* Method updateName.
|
||||
*
|
||||
* @param oldOne String
|
||||
* @param newOne String
|
||||
*/
|
||||
void updateName(String oldOne, String newOne);
|
||||
|
||||
boolean updateRealName(String user, String realName);
|
||||
|
||||
boolean updateIp(String user, String ip);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
@ -42,7 +43,7 @@ public class FlatFile implements DataSource {
|
||||
try {
|
||||
source.createNewFile();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
ConsoleLogger.logException("Cannot open flatfile", e);
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use FLAT FILE... SHUTDOWN...");
|
||||
instance.getServer().shutdown();
|
||||
@ -50,10 +51,14 @@ public class FlatFile implements DataSource {
|
||||
if (!Settings.isStopEnabled) {
|
||||
instance.getServer().getPluginManager().disablePlugin(instance);
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public FlatFile(File source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
BufferedReader br = null;
|
||||
@ -599,17 +604,9 @@ public class FlatFile implements DataSource {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateName(String oldOne, String newOne) {
|
||||
PlayerAuth auth = this.getAuth(oldOne);
|
||||
auth.setNickname(newOne);
|
||||
this.saveAuth(auth);
|
||||
this.removeAuth(oldOne);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateRealName(String user, String realName) {
|
||||
return false;
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -626,33 +623,25 @@ public class FlatFile implements DataSource {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
auths.add(new PlayerAuth(args[0], args[1], "192.168.0.1", 0, "your@email.com", args[0]));
|
||||
break;
|
||||
case 3:
|
||||
auths.add(new PlayerAuth(args[0], args[1], args[2], 0, "your@email.com", args[0]));
|
||||
break;
|
||||
case 4:
|
||||
auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), "your@email.com", args[0]));
|
||||
break;
|
||||
case 7:
|
||||
auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), "unavailableworld", "your@email.com", args[0]));
|
||||
break;
|
||||
case 8:
|
||||
auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), args[7], "your@email.com", args[0]));
|
||||
break;
|
||||
case 9:
|
||||
auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), args[7], args[8], args[0]));
|
||||
break;
|
||||
// We expect to encounter 2, 3, 4, 7, 8 or 9 fields. Ignore the line otherwise
|
||||
if (args.length >= 2 && args.length != 5 && args.length != 6 && args.length <= 9) {
|
||||
PlayerAuth.Builder builder = PlayerAuth.builder()
|
||||
.name(args[0]).realName(args[0])
|
||||
.password(args[1], null);
|
||||
if (args.length >= 3) builder.ip(args[2]);
|
||||
if (args.length >= 4) builder.lastLogin(Long.parseLong(args[3]));
|
||||
if (args.length >= 7) {
|
||||
builder.locX(Double.parseDouble(args[4]))
|
||||
.locY(Double.parseDouble(args[5]))
|
||||
.locZ(Double.parseDouble(args[6]));
|
||||
}
|
||||
if (args.length >= 8) builder.locWorld(args[7]);
|
||||
if (args.length >= 9) builder.email(args[8]);
|
||||
auths.add(builder.build());
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return auths;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return auths;
|
||||
ConsoleLogger.logException("Error while getting auths from flatfile:", ex);
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
@ -666,7 +655,7 @@ public class FlatFile implements DataSource {
|
||||
|
||||
@Override
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
return new ArrayList<>();
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
@ -41,6 +42,10 @@ public class MySQL implements DataSource {
|
||||
private final HashAlgorithm hashAlgorithm;
|
||||
private HikariDataSource ds;
|
||||
|
||||
private final String phpBbPrefix;
|
||||
private final int phpBbGroup;
|
||||
private final String wordpressPrefix;
|
||||
|
||||
public MySQL(NewSetting settings) throws ClassNotFoundException, SQLException, PoolInitializationException {
|
||||
this.host = settings.getProperty(DatabaseSettings.MYSQL_HOST);
|
||||
this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT);
|
||||
@ -51,6 +56,9 @@ public class MySQL implements DataSource {
|
||||
this.columnOthers = settings.getProperty(HooksSettings.MYSQL_OTHER_USERNAME_COLS);
|
||||
this.col = new Columns(settings);
|
||||
this.hashAlgorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||
this.phpBbPrefix = settings.getProperty(HooksSettings.PHPBB_TABLE_PREFIX);
|
||||
this.phpBbGroup = settings.getProperty(HooksSettings.PHPBB_ACTIVATED_GROUP_ID);
|
||||
this.wordpressPrefix = settings.getProperty(HooksSettings.WORDPRESS_TABLE_PREFIX);
|
||||
|
||||
// Set the connection arguments (and check if connection is ok)
|
||||
try {
|
||||
@ -81,6 +89,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MySQL(NewSetting settings, HikariDataSource hikariDataSource) {
|
||||
this.host = settings.getProperty(DatabaseSettings.MYSQL_HOST);
|
||||
this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT);
|
||||
@ -91,6 +100,9 @@ public class MySQL implements DataSource {
|
||||
this.columnOthers = settings.getProperty(HooksSettings.MYSQL_OTHER_USERNAME_COLS);
|
||||
this.col = new Columns(settings);
|
||||
this.hashAlgorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||
this.phpBbPrefix = settings.getProperty(HooksSettings.PHPBB_TABLE_PREFIX);
|
||||
this.phpBbGroup = settings.getProperty(HooksSettings.PHPBB_ACTIVATED_GROUP_ID);
|
||||
this.wordpressPrefix = settings.getProperty(HooksSettings.WORDPRESS_TABLE_PREFIX);
|
||||
ds = hikariDataSource;
|
||||
}
|
||||
|
||||
@ -359,10 +371,10 @@ public class MySQL implements DataSource {
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
// Insert player in phpbb_user_group
|
||||
sql = "INSERT INTO " + Settings.getPhpbbPrefix
|
||||
sql = "INSERT INTO " + phpBbPrefix
|
||||
+ "user_group (group_id, user_id, group_leader, user_pending) VALUES (?,?,?,?);";
|
||||
pst2 = con.prepareStatement(sql);
|
||||
pst2.setInt(1, Settings.getPhpbbGroup);
|
||||
pst2.setInt(1, phpBbGroup);
|
||||
pst2.setInt(2, id);
|
||||
pst2.setInt(3, 0);
|
||||
pst2.setInt(4, 0);
|
||||
@ -380,7 +392,7 @@ public class MySQL implements DataSource {
|
||||
sql = "UPDATE " + tableName + " SET " + tableName
|
||||
+ ".group_id=? WHERE " + col.NAME + "=?;";
|
||||
pst2 = con.prepareStatement(sql);
|
||||
pst2.setInt(1, Settings.getPhpbbGroup);
|
||||
pst2.setInt(1, phpBbGroup);
|
||||
pst2.setString(2, auth.getNickname());
|
||||
pst2.executeUpdate();
|
||||
pst2.close();
|
||||
@ -403,7 +415,7 @@ public class MySQL implements DataSource {
|
||||
pst2.executeUpdate();
|
||||
pst2.close();
|
||||
// Increment num_users
|
||||
sql = "UPDATE " + Settings.getPhpbbPrefix
|
||||
sql = "UPDATE " + phpBbPrefix
|
||||
+ "config SET config_value = config_value + 1 WHERE config_name = 'num_users';";
|
||||
pst2 = con.prepareStatement(sql);
|
||||
pst2.executeUpdate();
|
||||
@ -417,7 +429,7 @@ public class MySQL implements DataSource {
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
sql = "INSERT INTO " + Settings.getWordPressPrefix + "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);
|
||||
@ -620,31 +632,32 @@ public class MySQL implements DataSource {
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
user = user.toLowerCase();
|
||||
try (Connection con = getConnection()) {
|
||||
String sql;
|
||||
PreparedStatement pst;
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
PreparedStatement xfSelect = null;
|
||||
PreparedStatement xfDelete = null;
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
if (hashAlgorithm == HashAlgorithm.XFBCRYPT) {
|
||||
sql = "SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
pst = con.prepareStatement(sql);
|
||||
pst.setString(1, user);
|
||||
ResultSet rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
sql = "DELETE FROM xf_user_authenticate WHERE " + col.ID + "=?;";
|
||||
PreparedStatement st = con.prepareStatement(sql);
|
||||
st.setInt(1, id);
|
||||
st.executeUpdate();
|
||||
st.close();
|
||||
xfSelect = con.prepareStatement(sql);
|
||||
xfSelect.setString(1, user);
|
||||
try (ResultSet rs = xfSelect.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
sql = "DELETE FROM xf_user_authenticate WHERE " + col.ID + "=?;";
|
||||
xfDelete = con.prepareStatement(sql);
|
||||
xfDelete.setInt(1, id);
|
||||
xfDelete.executeUpdate();
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
pst.close();
|
||||
}
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;");
|
||||
pst.setString(1, user);
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(xfSelect);
|
||||
close(xfDelete);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -817,18 +830,6 @@ public class MySQL implements DataSource {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateName(String oldOne, String newOne) {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.NAME + "=? WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, newOne);
|
||||
pst.setString(2, oldOne);
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateRealName(String user, String realName) {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
|
||||
@ -891,22 +892,24 @@ public class MySQL implements DataSource {
|
||||
@Override
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
List<PlayerAuth> auths = new ArrayList<>();
|
||||
try (Connection con = getConnection()) {
|
||||
Statement st = con.createStatement();
|
||||
ResultSet rs = st.executeQuery("SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;");
|
||||
PreparedStatement pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + col.ID + "=?;");
|
||||
String sql = "SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;";
|
||||
try (Connection con = getConnection();
|
||||
Statement st = con.createStatement();
|
||||
ResultSet rs = st.executeQuery(sql)) {
|
||||
while (rs.next()) {
|
||||
PlayerAuth pAuth = buildAuthFromResultSet(rs);
|
||||
if (hashAlgorithm == HashAlgorithm.XFBCRYPT) {
|
||||
int id = rs.getInt(col.ID);
|
||||
pst.setInt(1, id);
|
||||
ResultSet rs2 = pst.executeQuery();
|
||||
if (rs2.next()) {
|
||||
Blob blob = rs2.getBlob("data");
|
||||
byte[] bytes = blob.getBytes(1, (int) blob.length());
|
||||
pAuth.setPassword(new HashedPassword(XFBCRYPT.getHashFromBlob(bytes)));
|
||||
try (PreparedStatement pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + col.ID + "=?;")) {
|
||||
int id = rs.getInt(col.ID);
|
||||
pst.setInt(1, id);
|
||||
ResultSet rs2 = pst.executeQuery();
|
||||
if (rs2.next()) {
|
||||
Blob blob = rs2.getBlob("data");
|
||||
byte[] bytes = blob.getBytes(1, (int) blob.length());
|
||||
pAuth.setPassword(new HashedPassword(XFBCRYPT.getHashFromBlob(bytes)));
|
||||
}
|
||||
rs2.close();
|
||||
}
|
||||
rs2.close();
|
||||
}
|
||||
auths.add(pAuth);
|
||||
}
|
||||
@ -990,12 +993,22 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
private static void close(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
try {
|
||||
if (rs != null && !rs.isClosed()) {
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
ConsoleLogger.logException("Could not close ResultSet", e);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
ConsoleLogger.logException("Could not close ResultSet", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void close(PreparedStatement pst) {
|
||||
try {
|
||||
if (pst != null && !pst.isClosed()) {
|
||||
pst.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
ConsoleLogger.logException("Could not close PreparedStatement", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,9 @@ public class SQLite implements DataSource {
|
||||
/**
|
||||
* Constructor for SQLite.
|
||||
*
|
||||
* @throws ClassNotFoundException Exception
|
||||
* @throws SQLException Exception
|
||||
* @param settings The settings instance
|
||||
* @throws ClassNotFoundException if no driver could be found for the datasource
|
||||
* @throws SQLException when initialization of a SQL datasource failed
|
||||
*/
|
||||
public SQLite(NewSetting settings) throws ClassNotFoundException, SQLException {
|
||||
this.database = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
|
||||
@ -350,8 +351,9 @@ public class SQLite implements DataSource {
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
try {
|
||||
if (con != null && !con.isClosed())
|
||||
con.close();
|
||||
if (con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
@ -421,17 +423,14 @@ public class SQLite implements DataSource {
|
||||
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
for (String name : banned) {
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;");
|
||||
pst.setString(1, name);
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,37 +506,17 @@ public class SQLite implements DataSource {
|
||||
|
||||
@Override
|
||||
public int getAccountsRegistered() {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT COUNT(*) FROM " + tableName + ";");
|
||||
rs = pst.executeQuery();
|
||||
if (rs != null && rs.next()) {
|
||||
String sql = "SELECT COUNT(*) FROM " + tableName + ";";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateName(String oldOne, String newOne) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + col.NAME + "=? WHERE " + col.NAME + "=?;");
|
||||
pst.setString(1, newOne);
|
||||
pst.setString(2, oldOne);
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateRealName(String user, String realName) {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
|
||||
@ -569,19 +548,14 @@ public class SQLite implements DataSource {
|
||||
@Override
|
||||
public List<PlayerAuth> getAllAuths() {
|
||||
List<PlayerAuth> auths = new ArrayList<>();
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + ";");
|
||||
rs = pst.executeQuery();
|
||||
String sql = "SELECT * FROM " + tableName + ";";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
PlayerAuth auth = buildAuthFromResultSet(rs);
|
||||
auths.add(auth);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
@ -589,19 +563,14 @@ public class SQLite implements DataSource {
|
||||
@Override
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
List<PlayerAuth> auths = new ArrayList<>();
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;");
|
||||
rs = pst.executeQuery();
|
||||
String sql = "SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
PlayerAuth auth = buildAuthFromResultSet(rs);
|
||||
auths.add(auth);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is called when a player uses the /login command with correct credentials.
|
||||
* {@link #setCanLogin(boolean) {@code event.setCanLogin(false)}} prevents the player from logging in.
|
||||
* {@link #setCanLogin(boolean) event.setCanLogin(false)} prevents the player from logging in.
|
||||
*/
|
||||
public class AuthMeAsyncPreLoginEvent extends CustomEvent {
|
||||
|
||||
|
@ -41,7 +41,7 @@ public enum MessageKey {
|
||||
|
||||
REGISTER_EMAIL_MESSAGE("reg_email_msg"),
|
||||
|
||||
MAX_REGISTER_EXCEEDED("max_reg"),
|
||||
MAX_REGISTER_EXCEEDED("max_reg", "%max_acc", "%reg_count", "%reg_names"),
|
||||
|
||||
USAGE_REGISTER("usage_reg"),
|
||||
|
||||
|
@ -96,6 +96,7 @@ public class Messages {
|
||||
*
|
||||
* @param key The key of the message to send
|
||||
* @param replacements The replacements to apply for the tags
|
||||
* @return The message from the file with replacements
|
||||
*/
|
||||
public String retrieveSingle(MessageKey key, String... replacements) {
|
||||
String message = retrieveSingle(key);
|
||||
@ -111,7 +112,7 @@ public class Messages {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the messages manager.
|
||||
* Reset the messages manager to retrieve messages from the given file instead of the current one.
|
||||
*
|
||||
* @param messagesFile The new file to load messages from
|
||||
*/
|
||||
|
@ -2,6 +2,7 @@ package fr.xephi.authme.process;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.process.email.AsyncAddEmail;
|
||||
import fr.xephi.authme.process.email.AsyncChangeEmail;
|
||||
import fr.xephi.authme.process.join.AsynchronousJoin;
|
||||
@ -20,18 +21,25 @@ public class Management {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final BukkitScheduler sched;
|
||||
private final ProcessService processService;
|
||||
private final DataSource dataSource;
|
||||
private final PlayerCache playerCache;
|
||||
private final NewSetting settings;
|
||||
|
||||
/**
|
||||
* Constructor for Management.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public Management(AuthMe plugin, NewSetting settings) {
|
||||
public Management(AuthMe plugin, ProcessService processService, DataSource dataSource, PlayerCache playerCache) {
|
||||
this.plugin = plugin;
|
||||
this.sched = this.plugin.getServer().getScheduler();
|
||||
this.settings = settings;
|
||||
this.processService = processService;
|
||||
this.dataSource = dataSource;
|
||||
this.playerCache = playerCache;
|
||||
|
||||
// FIXME don't pass settings anymore -> go through the service in the processes
|
||||
this.settings = processService.getSettings();
|
||||
}
|
||||
|
||||
public void performLogin(final Player player, final String password, final boolean forceLogin) {
|
||||
@ -39,7 +47,7 @@ public class Management {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousLogin(player, password, forceLogin, plugin, plugin.getDataSource(), settings)
|
||||
new AsynchronousLogin(player, password, forceLogin, plugin, dataSource, settings)
|
||||
.process();
|
||||
}
|
||||
});
|
||||
@ -60,7 +68,7 @@ public class Management {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncRegister(player, password, email, plugin, plugin.getDataSource(), settings).process();
|
||||
new AsyncRegister(player, password, email, plugin, dataSource, settings).process();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -76,14 +84,7 @@ public class Management {
|
||||
}
|
||||
|
||||
public void performJoin(final Player player) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousJoin(player, plugin, plugin.getDataSource()).process();
|
||||
}
|
||||
|
||||
});
|
||||
runTask(new AsynchronousJoin(player, plugin, dataSource, playerCache, processService));
|
||||
}
|
||||
|
||||
public void performQuit(final Player player, final boolean isKick) {
|
||||
@ -91,28 +92,26 @@ public class Management {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousQuit(player, plugin, plugin.getDataSource(), isKick).process();
|
||||
new AsynchronousQuit(player, plugin, dataSource, isKick).process();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void performAddEmail(final Player player, final String newEmail) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncAddEmail(player, plugin, newEmail, plugin.getDataSource(),
|
||||
PlayerCache.getInstance(), settings).process();
|
||||
}
|
||||
});
|
||||
runTask(new AsyncAddEmail(player, newEmail, dataSource, playerCache, processService));
|
||||
}
|
||||
|
||||
public void performChangeEmail(final Player player, final String oldEmail, final String newEmail) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncChangeEmail(player, plugin, oldEmail, newEmail, plugin.getDataSource(), PlayerCache.getInstance(), settings).process();
|
||||
new AsyncChangeEmail(player, plugin, oldEmail, newEmail, dataSource, playerCache, settings).process();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void runTask(Process process) {
|
||||
sched.runTaskAsynchronously(plugin, process);
|
||||
}
|
||||
}
|
||||
|
8
src/main/java/fr/xephi/authme/process/Process.java
Normal file
8
src/main/java/fr/xephi/authme/process/Process.java
Normal file
@ -0,0 +1,8 @@
|
||||
package fr.xephi.authme.process;
|
||||
|
||||
/**
|
||||
* Common interface for AuthMe processes.
|
||||
*/
|
||||
public interface Process extends Runnable {
|
||||
|
||||
}
|
63
src/main/java/fr/xephi/authme/process/ProcessService.java
Normal file
63
src/main/java/fr/xephi/authme/process/ProcessService.java
Normal file
@ -0,0 +1,63 @@
|
||||
package fr.xephi.authme.process;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
/**
|
||||
* Service for asynchronous and synchronous processes.
|
||||
*/
|
||||
public class ProcessService {
|
||||
|
||||
private final NewSetting settings;
|
||||
private final Messages messages;
|
||||
private final AuthMe authMe;
|
||||
|
||||
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe) {
|
||||
this.settings = settings;
|
||||
this.messages = messages;
|
||||
this.authMe = authMe;
|
||||
}
|
||||
|
||||
public <T> T getProperty(Property<T> property) {
|
||||
return settings.getProperty(property);
|
||||
}
|
||||
|
||||
public NewSetting getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public void send(CommandSender sender, MessageKey key) {
|
||||
messages.send(sender, key);
|
||||
}
|
||||
|
||||
public String retrieveMessage(MessageKey key) {
|
||||
return messages.retrieveSingle(key);
|
||||
}
|
||||
|
||||
public BukkitTask runTask(Runnable task) {
|
||||
return authMe.getServer().getScheduler().runTask(authMe, task);
|
||||
}
|
||||
|
||||
public BukkitTask runTaskLater(Runnable task, long delay) {
|
||||
return authMe.getServer().getScheduler().runTaskLater(authMe, task, delay);
|
||||
}
|
||||
|
||||
public int scheduleSyncDelayedTask(Runnable task) {
|
||||
return authMe.getServer().getScheduler().scheduleSyncDelayedTask(authMe, task);
|
||||
}
|
||||
|
||||
public void callEvent(Event event) {
|
||||
authMe.getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
public AuthMe getAuthMe() {
|
||||
return authMe;
|
||||
}
|
||||
|
||||
}
|
@ -1,40 +1,38 @@
|
||||
package fr.xephi.authme.process.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.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Async task to add an email to an account.
|
||||
*/
|
||||
public class AsyncAddEmail {
|
||||
public class AsyncAddEmail implements Process {
|
||||
|
||||
private final Player player;
|
||||
private final String email;
|
||||
private final Messages messages;
|
||||
private final ProcessService service;
|
||||
private final DataSource dataSource;
|
||||
private final PlayerCache playerCache;
|
||||
private final NewSetting settings;
|
||||
|
||||
public AsyncAddEmail(Player player, AuthMe plugin, String email, DataSource dataSource,
|
||||
PlayerCache playerCache, NewSetting settings) {
|
||||
this.messages = plugin.getMessages();
|
||||
public AsyncAddEmail(Player player, String email, DataSource dataSource, PlayerCache playerCache,
|
||||
ProcessService service) {
|
||||
this.player = player;
|
||||
this.email = email;
|
||||
this.dataSource = dataSource;
|
||||
this.playerCache = playerCache;
|
||||
this.settings = settings;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
String playerName = player.getName().toLowerCase();
|
||||
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
@ -42,19 +40,19 @@ public class AsyncAddEmail {
|
||||
final String currentEmail = auth.getEmail();
|
||||
|
||||
if (currentEmail != null && !"your@email.com".equals(currentEmail)) {
|
||||
messages.send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
} else if (!Utils.isEmailCorrect(email, settings)) {
|
||||
messages.send(player, MessageKey.INVALID_EMAIL);
|
||||
service.send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
} else if (!Utils.isEmailCorrect(email, service.getSettings())) {
|
||||
service.send(player, MessageKey.INVALID_EMAIL);
|
||||
} else if (dataSource.isEmailStored(email)) {
|
||||
messages.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
} else {
|
||||
auth.setEmail(email);
|
||||
if (dataSource.updateEmail(auth)) {
|
||||
playerCache.updatePlayer(auth);
|
||||
messages.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
service.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
} else {
|
||||
ConsoleLogger.showError("Could not save email for player '" + player + "'");
|
||||
messages.send(player, MessageKey.ERROR);
|
||||
service.send(player, MessageKey.ERROR);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -64,11 +62,11 @@ public class AsyncAddEmail {
|
||||
|
||||
private void sendUnloggedMessage(DataSource dataSource) {
|
||||
if (dataSource.isAuthAvailable(player.getName())) {
|
||||
messages.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else if (Settings.emailRegistration) {
|
||||
messages.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
service.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else if (service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)) {
|
||||
service.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
} else {
|
||||
messages.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
service.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,66 +11,71 @@ import fr.xephi.authme.events.ProtectInventoryEvent;
|
||||
import fr.xephi.authme.events.SpawnTeleportEvent;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
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.Spawn;
|
||||
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.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.Utils.GroupType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
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 AsynchronousJoin {
|
||||
public class AsynchronousJoin implements Process {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final Player player;
|
||||
private final DataSource database;
|
||||
private final String name;
|
||||
private final Messages m;
|
||||
private final BukkitScheduler sched;
|
||||
private final ProcessService service;
|
||||
private final PlayerCache playerCache;
|
||||
|
||||
public AsynchronousJoin(Player player, AuthMe plugin, DataSource database) {
|
||||
this.m = plugin.getMessages();
|
||||
public AsynchronousJoin(Player player, AuthMe plugin, DataSource database, PlayerCache playerCache,
|
||||
ProcessService service) {
|
||||
this.player = player;
|
||||
this.plugin = plugin;
|
||||
this.sched = plugin.getServer().getScheduler();
|
||||
this.database = database;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.service = service;
|
||||
this.playerCache = playerCache;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Utils.isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.checkVeryGames) {
|
||||
if (service.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK)) {
|
||||
plugin.getVerygamesIp(player);
|
||||
}
|
||||
|
||||
if (plugin.ess != null && Settings.disableSocialSpy) {
|
||||
if (plugin.ess != null && service.getProperty(HooksSettings.DISABLE_SOCIAL_SPY)) {
|
||||
plugin.ess.getUser(player).setSocialSpyEnabled(false);
|
||||
}
|
||||
|
||||
final String ip = plugin.getIP(player);
|
||||
|
||||
|
||||
if (Settings.isAllowRestrictedIp && isNameRestricted(name, ip, player.getAddress().getHostName())) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
if (isNameRestricted(name, ip, player.getAddress().getHostName(), service.getSettings())) {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
|
||||
player.kickPlayer(m.retrieveSingle(MessageKey.NOT_OWNER_ERROR));
|
||||
player.kickPlayer(service.retrieveMessage(MessageKey.NOT_OWNER_ERROR));
|
||||
if (Settings.banUnsafeIp) {
|
||||
plugin.getServer().banIP(ip);
|
||||
}
|
||||
@ -78,38 +83,34 @@ public class AsynchronousJoin {
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (Settings.getMaxJoinPerIp > 0
|
||||
if (service.getProperty(RestrictionSettings.MAX_JOIN_PER_IP) > 0
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
&& !ip.equalsIgnoreCase("127.0.0.1")
|
||||
&& !ip.equalsIgnoreCase("localhost")
|
||||
&& plugin.hasJoinedIp(player.getName(), ip)) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
&& !"127.0.0.1".equalsIgnoreCase(ip)
|
||||
&& !"localhost".equalsIgnoreCase(ip)
|
||||
&& hasJoinedIp(player.getName(), ip, service.getSettings(), service.getAuthMe())) {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.kickPlayer("A player with the same IP is already in game!");
|
||||
}
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
final Location spawnLoc = plugin.getSpawnLocation(player);
|
||||
final Location spawnLoc = Spawn.getInstance().getSpawnLocation(player);
|
||||
final boolean isAuthAvailable = database.isAuthAvailable(name);
|
||||
if (isAuthAvailable) {
|
||||
if (!Settings.noTeleport) {
|
||||
if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, playerCache.isAuthenticated(name));
|
||||
service.callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null
|
||||
&& tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -123,12 +124,12 @@ public class AsynchronousJoin {
|
||||
if (ev.isCancelled()) {
|
||||
plugin.inventoryProtector.sendInventoryPacket(player);
|
||||
if (!Settings.noConsoleSpam) {
|
||||
ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + " ...");
|
||||
ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + "...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.isSessionsEnabled && (PlayerCache.getInstance().isAuthenticated(name) || database.isLogged(name))) {
|
||||
if (service.getProperty(PluginSettings.SESSIONS_ENABLED) && (playerCache.isAuthenticated(name) || database.isLogged(name))) {
|
||||
if (plugin.sessions.containsKey(name)) {
|
||||
plugin.sessions.get(name).cancel();
|
||||
plugin.sessions.remove(name);
|
||||
@ -137,11 +138,11 @@ public class AsynchronousJoin {
|
||||
database.setUnlogged(name);
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
if (auth != null && auth.getIp().equals(ip)) {
|
||||
m.send(player, MessageKey.SESSION_RECONNECTION);
|
||||
service.send(player, MessageKey.SESSION_RECONNECTION);
|
||||
plugin.getManagement().performLogin(player, "dontneed", true);
|
||||
return;
|
||||
} else if (Settings.sessionExpireOnIpChange) {
|
||||
m.send(player, MessageKey.SESSION_EXPIRED);
|
||||
service.send(player, MessageKey.SESSION_EXPIRED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -154,21 +155,18 @@ public class AsynchronousJoin {
|
||||
|
||||
if (!Settings.noTeleport && !needFirstSpawn() && Settings.isTeleportToSpawnEnabled
|
||||
|| (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null
|
||||
&& tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
|
||||
service.callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null
|
||||
&& tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
@ -176,9 +174,9 @@ public class AsynchronousJoin {
|
||||
}
|
||||
Utils.setGroup(player, isAuthAvailable ? GroupType.NOTLOGGEDIN : GroupType.UNREGISTERED);
|
||||
|
||||
final int timeOut = Settings.getRegistrationTimeout * 20;
|
||||
final int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * 20;
|
||||
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.setOp(false);
|
||||
@ -186,40 +184,35 @@ public class AsynchronousJoin {
|
||||
player.setFlySpeed(0.0f);
|
||||
player.setWalkSpeed(0.0f);
|
||||
}
|
||||
player.setNoDamageTicks(timeOut);
|
||||
if (Settings.useEssentialsMotd) {
|
||||
player.setNoDamageTicks(registrationTimeout);
|
||||
if (service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) {
|
||||
player.performCommand("motd");
|
||||
}
|
||||
if (Settings.applyBlindEffect) {
|
||||
int blindTimeOut;
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
// Allow infinite blindness effect
|
||||
if (timeOut <= 0) {
|
||||
blindTimeOut = 99999;
|
||||
} else {
|
||||
blindTimeOut = timeOut;
|
||||
}
|
||||
int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout;
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
int msgInterval = Settings.getWarnMessageInterval;
|
||||
if (timeOut > 0) {
|
||||
BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
int msgInterval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
if (registrationTimeout > 0) {
|
||||
BukkitTask id = service.runTaskLater(new TimeoutTask(plugin, name, player), registrationTimeout);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
|
||||
}
|
||||
|
||||
String[] msg;
|
||||
MessageKey msg;
|
||||
if (isAuthAvailable) {
|
||||
msg = m.retrieve(MessageKey.LOGIN_MESSAGE);
|
||||
msg = MessageKey.LOGIN_MESSAGE;
|
||||
} else {
|
||||
msg = Settings.emailRegistration
|
||||
? m.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE)
|
||||
: m.retrieve(MessageKey.REGISTER_MESSAGE);
|
||||
? MessageKey.REGISTER_EMAIL_MESSAGE
|
||||
: MessageKey.REGISTER_MESSAGE;
|
||||
}
|
||||
if (msgInterval > 0 && LimboCache.getInstance().getLimboPlayer(name) != null) {
|
||||
BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval));
|
||||
BukkitTask msgTask = service.runTask(new MessageTask(plugin, name, msg, msgInterval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask);
|
||||
}
|
||||
}
|
||||
@ -235,13 +228,11 @@ public class AsynchronousJoin {
|
||||
if (!tpEvent.isCancelled()) {
|
||||
if (player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) {
|
||||
final Location fLoc = tpEvent.getTo();
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.teleport(fLoc);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -249,25 +240,23 @@ public class AsynchronousJoin {
|
||||
}
|
||||
|
||||
private void placePlayerSafely(final Player player, final Location spawnLoc) {
|
||||
if (spawnLoc == null)
|
||||
return;
|
||||
if (!Settings.noTeleport)
|
||||
if (spawnLoc == null || service.getProperty(RestrictionSettings.NO_TELEPORT))
|
||||
return;
|
||||
if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName())))
|
||||
return;
|
||||
if (!player.hasPlayedBefore())
|
||||
return;
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (spawnLoc.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
Material cur = player.getLocation().getBlock().getType();
|
||||
Material top = player.getLocation().add(0D, 1D, 0D).getBlock().getType();
|
||||
Material top = player.getLocation().add(0, 1, 0).getBlock().getType();
|
||||
if (cur == Material.PORTAL || cur == Material.ENDER_PORTAL
|
||||
|| top == Material.PORTAL || top == Material.ENDER_PORTAL) {
|
||||
m.send(player, MessageKey.UNSAFE_QUIT_LOCATION);
|
||||
service.send(player, MessageKey.UNSAFE_QUIT_LOCATION);
|
||||
player.teleport(spawnLoc);
|
||||
}
|
||||
}
|
||||
@ -281,12 +270,17 @@ public class AsynchronousJoin {
|
||||
* @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) {
|
||||
private static boolean isNameRestricted(String name, String ip, String domain, NewSetting settings) {
|
||||
if (!settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean nameFound = false;
|
||||
for (String entry : Settings.getRestrictedIp) {
|
||||
for (String entry : settings.getProperty(RestrictionSettings.ALLOWED_RESTRICTED_USERS)) {
|
||||
String[] args = entry.split(";");
|
||||
String testName = args[0];
|
||||
String testIp = args[1];
|
||||
@ -301,4 +295,12 @@ public class AsynchronousJoin {
|
||||
return nameFound;
|
||||
}
|
||||
|
||||
private boolean hasJoinedIp(String name, String ip, NewSetting settings, AuthMe authMe) {
|
||||
int count = 0;
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(authMe.getIP(player)) && !player.getName().equalsIgnoreCase(name))
|
||||
count++;
|
||||
}
|
||||
return count >= settings.getProperty(RestrictionSettings.MAX_JOIN_PER_IP);
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ public class AsynchronousLogin {
|
||||
} else {
|
||||
msg = m.retrieve(MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
BukkitTask msgT = Bukkit.getScheduler().runTaskAsynchronously(plugin,
|
||||
BukkitTask msgT = Bukkit.getScheduler().runTask(plugin,
|
||||
new MessageTask(plugin, name, msg, settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
|
||||
}
|
||||
@ -175,7 +175,7 @@ public class AsynchronousLogin {
|
||||
displayOtherAccounts(auth);
|
||||
|
||||
if (Settings.recallEmail && (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email))) {
|
||||
m.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
m.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
@ -185,7 +185,6 @@ public class AsynchronousLogin {
|
||||
// makes player isLoggedin via API
|
||||
PlayerCache.getInstance().addPlayer(auth);
|
||||
database.setLogged(name);
|
||||
plugin.otherAccounts.addPlayer(player.getUniqueId());
|
||||
|
||||
// As the scheduling executes the Task most likely after the current
|
||||
// task, we schedule it in the end
|
||||
@ -232,8 +231,8 @@ public class AsynchronousLogin {
|
||||
String message = "[AuthMe] " + StringUtils.join(", ", auths) + ".";
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (plugin.getPermissionsManager().hasPermission(player, AdminPermission.SEE_OTHER_ACCOUNTS)
|
||||
|| (player.getName().equals(this.player.getName())
|
||||
&& plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OWN_ACCOUNTS))) {
|
||||
|| (player.getName().equals(this.player.getName())
|
||||
&& plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OWN_ACCOUNTS))) {
|
||||
player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has " + auths.size() + " accounts");
|
||||
player.sendMessage(message);
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
private final String name;
|
||||
private final PlayerAuth auth;
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private final PluginManager pm;
|
||||
private final JsonCache playerCache;
|
||||
private final NewSetting settings;
|
||||
@ -54,7 +53,6 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
public ProcessSyncPlayerLogin(Player player, AuthMe plugin,
|
||||
DataSource database, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
this.database = database;
|
||||
this.pm = plugin.getServer().getPluginManager();
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
|
@ -74,21 +74,24 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler sched = player.getServer().getScheduler();
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
|
||||
}
|
||||
BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), interval));
|
||||
BukkitTask msgT = sched.runTask(plugin, new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null)
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null) {
|
||||
player.getVehicle().eject();
|
||||
if (Settings.applyBlindEffect)
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, Settings.getRegistrationTimeout * 20, 2));
|
||||
}
|
||||
if (Settings.applyBlindEffect) {
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
}
|
||||
player.setOp(false);
|
||||
restoreSpeedEffect();
|
||||
// Player is now logout... Time to fire event !
|
||||
Bukkit.getServer().getPluginManager().callEvent(new LogoutEvent(player));
|
||||
if (Settings.bungee)
|
||||
if (Settings.bungee) {
|
||||
sendBungeeMessage();
|
||||
}
|
||||
m.send(player, MessageKey.LOGOUT_SUCCESS);
|
||||
ConsoleLogger.info(player.getName() + " logged out");
|
||||
}
|
||||
|
@ -5,34 +5,26 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.datasource.CacheDataSource;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AsynchronousQuit {
|
||||
|
||||
protected final AuthMe plugin;
|
||||
protected final DataSource database;
|
||||
protected final Player player;
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private boolean isOp = false;
|
||||
private boolean needToChange = false;
|
||||
private boolean isKick = false;
|
||||
|
||||
/**
|
||||
* Constructor for AsynchronousQuit.
|
||||
*
|
||||
* @param p Player
|
||||
* @param plugin AuthMe
|
||||
* @param database DataSource
|
||||
* @param isKick boolean
|
||||
*/
|
||||
public AsynchronousQuit(Player p, AuthMe plugin, DataSource database,
|
||||
boolean isKick) {
|
||||
this.player = p;
|
||||
@ -43,9 +35,7 @@ public class AsynchronousQuit {
|
||||
}
|
||||
|
||||
public void process() {
|
||||
if (player == null)
|
||||
return;
|
||||
if (Utils.isUnrestricted(player)) {
|
||||
if (player == null || Utils.isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,7 +44,9 @@ public class AsynchronousQuit {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
if (Settings.isSaveQuitLocationEnabled) {
|
||||
Location loc = player.getLocation();
|
||||
PlayerAuth auth = new PlayerAuth(name, loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName(), player.getName());
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name).location(loc)
|
||||
.realName(player.getName()).build();
|
||||
database.updateQuitLoc(auth);
|
||||
}
|
||||
PlayerAuth auth = new PlayerAuth(name, ip, System.currentTimeMillis(), player.getName());
|
||||
@ -63,14 +55,11 @@ public class AsynchronousQuit {
|
||||
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (limbo != null) {
|
||||
if (limbo.getGroup() != null && !limbo.getGroup().isEmpty())
|
||||
if (!StringUtils.isEmpty(limbo.getGroup())) {
|
||||
Utils.addNormal(player, limbo.getGroup());
|
||||
}
|
||||
needToChange = true;
|
||||
isOp = limbo.getOperator();
|
||||
if (limbo.getTimeoutTaskId() != null)
|
||||
limbo.getTimeoutTaskId().cancel();
|
||||
if (limbo.getMessageTaskId() != null)
|
||||
limbo.getMessageTaskId().cancel();
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
}
|
||||
if (Settings.isSessionsEnabled && !isKick) {
|
||||
@ -100,12 +89,15 @@ public class AsynchronousQuit {
|
||||
if (plugin.isEnabled()) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, player, isOp, needToChange));
|
||||
}
|
||||
// remove player from cache
|
||||
if (database instanceof CacheDataSource) {
|
||||
((CacheDataSource) database).getCachedAuths().invalidate(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void postLogout() {
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
if (database.isLogged(name))
|
||||
database.setUnlogged(name);
|
||||
database.setUnlogged(name);
|
||||
plugin.sessions.remove(name);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
package fr.xephi.authme.process.register;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
@ -13,8 +18,6 @@ import fr.xephi.authme.security.crypts.TwoFactor;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*/
|
||||
@ -74,13 +77,16 @@ public class AsyncRegister {
|
||||
if (database.isAuthAvailable(name)) {
|
||||
m.send(player, MessageKey.NAME_ALREADY_REGISTERED);
|
||||
return false;
|
||||
} else if (Settings.getmaxRegPerIp > 0
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
} else if(Settings.getmaxRegPerIp > 0
|
||||
&& !ip.equalsIgnoreCase("127.0.0.1")
|
||||
&& !ip.equalsIgnoreCase("localhost")
|
||||
&& database.getAllAuthsByIp(ip).size() >= Settings.getmaxRegPerIp) {
|
||||
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
|
||||
return false;
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) {
|
||||
Integer maxReg = Settings.getmaxRegPerIp;
|
||||
List<String> otherAccounts = database.getAllAuthsByIp(ip);
|
||||
if (otherAccounts.size() >= maxReg) {
|
||||
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), Integer.toString(otherAccounts.size()), otherAccounts.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -96,11 +102,16 @@ public class AsyncRegister {
|
||||
}
|
||||
|
||||
private void emailRegister() {
|
||||
if (Settings.getmaxRegPerEmail > 0
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
&& database.countAuthsByEmail(email) >= Settings.getmaxRegPerEmail) {
|
||||
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
|
||||
return;
|
||||
if(Settings.getmaxRegPerEmail > 0
|
||||
&& !ip.equalsIgnoreCase("127.0.0.1")
|
||||
&& !ip.equalsIgnoreCase("localhost")
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) {
|
||||
Integer maxReg = Settings.getmaxRegPerIp;
|
||||
List<String> otherAccounts = database.getAllAuthsByIp(ip);
|
||||
if (otherAccounts.size() >= maxReg) {
|
||||
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), Integer.toString(otherAccounts.size()), otherAccounts.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
final HashedPassword hashedPassword = plugin.getPasswordSecurity().computeHash(password, name);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
@ -146,7 +157,6 @@ public class AsyncRegister {
|
||||
plugin.getManagement().performLogin(player, "dontneed", true);
|
||||
}
|
||||
|
||||
plugin.otherAccounts.addPlayer(player.getUniqueId());
|
||||
ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin, settings);
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, sync);
|
||||
|
||||
|
@ -52,14 +52,13 @@ public class ProcessSyncEmailRegister implements Runnable {
|
||||
int msgInterval = Settings.getWarnMessageInterval;
|
||||
|
||||
BukkitScheduler sched = plugin.getServer().getScheduler();
|
||||
if (time != 0 && limbo != null) {
|
||||
limbo.getTimeoutTaskId().cancel();
|
||||
BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), time);
|
||||
limbo.setTimeoutTaskId(id);
|
||||
}
|
||||
|
||||
if (limbo != null) {
|
||||
limbo.getMessageTaskId().cancel();
|
||||
BukkitTask nwMsg = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), msgInterval));
|
||||
if (time != 0) {
|
||||
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), time);
|
||||
limbo.setTimeoutTaskId(id);
|
||||
}
|
||||
BukkitTask nwMsg = sched.runTask(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), msgInterval));
|
||||
limbo.setMessageTaskId(nwMsg);
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,7 @@
|
||||
package fr.xephi.authme.process.register;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
@ -19,10 +10,17 @@ import fr.xephi.authme.events.LoginEvent;
|
||||
import fr.xephi.authme.events.RestoreInventoryEvent;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
/**
|
||||
*/
|
||||
@ -37,8 +35,8 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
/**
|
||||
* Constructor for ProcessSyncPasswordRegister.
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public ProcessSyncPasswordRegister(Player player, AuthMe plugin, NewSetting settings) {
|
||||
@ -77,11 +75,10 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
BukkitScheduler sched = plugin.getServer().getScheduler();
|
||||
BukkitTask task;
|
||||
if (delay != 0) {
|
||||
task = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay);
|
||||
task = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), delay);
|
||||
cache.getLimboPlayer(name).setTimeoutTaskId(task);
|
||||
}
|
||||
task = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name,
|
||||
m.retrieve(MessageKey.LOGIN_MESSAGE), interval));
|
||||
task = sched.runTask(plugin, new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
cache.getLimboPlayer(name).setMessageTaskId(task);
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null) {
|
||||
player.getVehicle().eject();
|
||||
@ -158,7 +155,7 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
|
||||
// Register is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
|
||||
sendTo();
|
||||
}
|
||||
|
||||
|
@ -73,12 +73,11 @@ public class AsynchronousUnregister {
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler scheduler = plugin.getServer().getScheduler();
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = scheduler.runTaskLaterAsynchronously(plugin,
|
||||
new TimeoutTask(plugin, name, player), timeOut);
|
||||
BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
limboPlayer.setTimeoutTaskId(id);
|
||||
}
|
||||
limboPlayer.setMessageTaskId(scheduler.runTaskAsynchronously(plugin,
|
||||
new MessageTask(plugin, name, m.retrieve(MessageKey.REGISTER_MESSAGE), interval)));
|
||||
limboPlayer.setMessageTaskId(scheduler.runTask(plugin,
|
||||
new MessageTask(plugin, name, MessageKey.REGISTER_MESSAGE, interval)));
|
||||
m.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
return;
|
||||
|
@ -82,4 +82,13 @@ public abstract class CustomConfiguration extends YamlConfiguration {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsAll(String... paths) {
|
||||
for (String path : paths) {
|
||||
if (!contains(path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,96 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class OtherAccounts extends CustomConfiguration {
|
||||
|
||||
private static OtherAccounts others = null;
|
||||
|
||||
public OtherAccounts() {
|
||||
super(new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "otheraccounts.yml"));
|
||||
others = this;
|
||||
load();
|
||||
save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getInstance.
|
||||
*
|
||||
* @return OtherAccounts
|
||||
*/
|
||||
public static OtherAccounts getInstance() {
|
||||
if (others == null) {
|
||||
others = new OtherAccounts();
|
||||
}
|
||||
return others;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method clear.
|
||||
*
|
||||
* @param uuid UUID
|
||||
*/
|
||||
public void clear(UUID uuid) {
|
||||
set(uuid.toString(), new ArrayList<String>());
|
||||
save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method addPlayer.
|
||||
*
|
||||
* @param uuid UUID
|
||||
*/
|
||||
public void addPlayer(UUID uuid) {
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null)
|
||||
return;
|
||||
if (!this.getStringList(uuid.toString()).contains(player.getName())) {
|
||||
this.getStringList(uuid.toString()).add(player.getName());
|
||||
save();
|
||||
}
|
||||
} catch (NoSuchMethodError | Exception e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method removePlayer.
|
||||
*
|
||||
* @param uuid UUID
|
||||
*/
|
||||
public void removePlayer(UUID uuid) {
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null)
|
||||
return;
|
||||
if (this.getStringList(uuid.toString()).contains(player.getName())) {
|
||||
this.getStringList(uuid.toString()).remove(player.getName());
|
||||
save();
|
||||
}
|
||||
} catch (NoSuchMethodError | Exception e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAllPlayersByUUID.
|
||||
*
|
||||
* @param uuid UUID
|
||||
*
|
||||
* @return StringList
|
||||
*/
|
||||
public List<String> getAllPlayersByUUID(UUID uuid) {
|
||||
return this.getStringList(uuid.toString());
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ public final class Settings {
|
||||
useCaptcha, emailRegistration, multiverse, bungee,
|
||||
banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange,
|
||||
disableSocialSpy, useEssentialsMotd, usePurge,
|
||||
purgePlayerDat, purgeEssentialsFile, supportOldPassword,
|
||||
purgePlayerDat, purgeEssentialsFile,
|
||||
purgeLimitedCreative, purgeAntiXray, purgePermissions,
|
||||
enableProtection, enableAntiBot, recallEmail, useWelcomeMessage,
|
||||
broadcastWelcomeMessage, forceRegKick, forceRegLogin,
|
||||
@ -72,19 +72,16 @@ public final class Settings {
|
||||
getMySQLColumnGroup, unRegisteredGroup,
|
||||
backupWindowsPath, getRegisteredGroup,
|
||||
rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld,
|
||||
getPhpbbPrefix, getWordPressPrefix,
|
||||
spawnPriority, crazyloginFileName, getPassRegex, sendPlayerTo;
|
||||
public static int getWarnMessageInterval, getSessionTimeout,
|
||||
getRegistrationTimeout, getMaxNickLength, getMinNickLength,
|
||||
getPasswordMinLen, getMovementRadius, getmaxRegPerIp,
|
||||
getNonActivatedGroup, passwordMaxLength, getRecoveryPassLength,
|
||||
getMailPort, maxLoginTry, captchaLength, saltLength,
|
||||
getmaxRegPerEmail, bCryptLog2Rounds, getPhpbbGroup,
|
||||
getmaxRegPerEmail, bCryptLog2Rounds,
|
||||
antiBotSensibility, antiBotDuration, delayRecall, getMaxLoginPerIp,
|
||||
getMaxJoinPerIp;
|
||||
protected static FileConfiguration configFile;
|
||||
private static AuthMe plugin;
|
||||
private static Settings instance;
|
||||
|
||||
/**
|
||||
* Constructor for Settings.
|
||||
@ -92,29 +89,27 @@ public final class Settings {
|
||||
* @param pl AuthMe
|
||||
*/
|
||||
public Settings(AuthMe pl) {
|
||||
instance = this;
|
||||
plugin = pl;
|
||||
configFile = plugin.getConfig();
|
||||
configFile = pl.getConfig();
|
||||
loadVariables();
|
||||
}
|
||||
|
||||
public static void loadVariables() {
|
||||
private static void loadVariables() {
|
||||
isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK);
|
||||
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
|
||||
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
|
||||
isTeleportToSpawnEnabled = configFile.getBoolean("settings.restrictions.teleportUnAuthedToSpawn", false);
|
||||
getWarnMessageInterval = configFile.getInt("settings.registration.messageInterval", 5);
|
||||
isSessionsEnabled = configFile.getBoolean("settings.sessions.enabled", false);
|
||||
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 = configFile.getInt("settings.restrictions.timeout", 30);
|
||||
isChatAllowed = configFile.getBoolean("settings.restrictions.allowChat", false);
|
||||
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 = configFile.getBoolean("settings.restrictions.AllowRestrictedUser", false);
|
||||
getRestrictedIp = configFile.getStringList("settings.restrictions.AllowedRestrictedUser");
|
||||
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);
|
||||
@ -172,7 +167,7 @@ public final class Settings {
|
||||
useCaptcha = configFile.getBoolean("Security.captcha.useCaptcha", false);
|
||||
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
|
||||
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
|
||||
emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
|
||||
emailRegistration = load(RegistrationSettings.USE_EMAIL_REGISTRATION);
|
||||
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
|
||||
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
|
||||
multiverse = load(HooksSettings.MULTIVERSE);
|
||||
@ -190,10 +185,6 @@ public final class Settings {
|
||||
purgePlayerDat = configFile.getBoolean("Purge.removePlayerDat", false);
|
||||
purgeEssentialsFile = configFile.getBoolean("Purge.removeEssentialsFile", false);
|
||||
defaultWorld = configFile.getString("Purge.defaultWorld", "world");
|
||||
getPhpbbPrefix = configFile.getString("ExternalBoardOptions.phpbbTablePrefix", "phpbb_");
|
||||
getPhpbbGroup = configFile.getInt("ExternalBoardOptions.phpbbActivatedGroupId", 2);
|
||||
supportOldPassword = configFile.getBoolean("settings.security.supportOldPasswordHash", false);
|
||||
getWordPressPrefix = configFile.getString("ExternalBoardOptions.wordpressTablePrefix", "wp_");
|
||||
purgeLimitedCreative = configFile.getBoolean("Purge.removeLimitedCreativesInventories", false);
|
||||
purgeAntiXray = configFile.getBoolean("Purge.removeAntiXRayFile", false);
|
||||
purgePermissions = configFile.getBoolean("Purge.removePermissions", false);
|
||||
@ -211,15 +202,15 @@ public final class Settings {
|
||||
countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist");
|
||||
broadcastWelcomeMessage = configFile.getBoolean("settings.broadcastWelcomeMessage", false);
|
||||
forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false);
|
||||
forceRegLogin = configFile.getBoolean("settings.registration.forceLoginAfterRegister", false);
|
||||
forceRegLogin = load(RegistrationSettings.FORCE_LOGIN_AFTER_REGISTER);
|
||||
spawnPriority = load(RestrictionSettings.SPAWN_PRIORITY);
|
||||
getMaxLoginPerIp = configFile.getInt("settings.restrictions.maxLoginPerIp", 0);
|
||||
getMaxJoinPerIp = configFile.getInt("settings.restrictions.maxJoinPerIp", 0);
|
||||
checkVeryGames = configFile.getBoolean("VeryGames.enableIpCheck", false);
|
||||
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 = configFile.getBoolean("settings.restrictions.noTeleport", false);
|
||||
noTeleport = load(RestrictionSettings.NO_TELEPORT);
|
||||
crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
|
||||
applyBlindEffect = configFile.getBoolean("settings.applyBlindEffect", false);
|
||||
|
@ -2,7 +2,6 @@ package fr.xephi.authme.settings;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -73,34 +72,32 @@ public class Spawn extends CustomConfiguration {
|
||||
}
|
||||
|
||||
public Location getSpawn() {
|
||||
try {
|
||||
if (containsAll("spawn.world", "spawn.x", "spawn.y", "spawn.z", "spawn.yaw", "spawn.pitch")) {
|
||||
String worldName = getString("spawn.world");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (StringUtils.isEmpty(worldName) || world == null) {
|
||||
return null;
|
||||
if (!StringUtils.isEmpty(worldName) && world != null) {
|
||||
return new Location(
|
||||
world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"),
|
||||
Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch"))
|
||||
);
|
||||
}
|
||||
return new Location(world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"),
|
||||
Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch")));
|
||||
} catch (NumberFormatException e) {
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Location getFirstSpawn() {
|
||||
try {
|
||||
String worldName;
|
||||
World world;
|
||||
if (StringUtils.isEmpty(worldName = getString("firstspawn.world")) ||
|
||||
(world = Bukkit.getWorld(worldName)) == null) {
|
||||
return null;
|
||||
if (containsAll("firstspawn.world", "firstspawn.x", "firstspawn.y",
|
||||
"firstspawn.z", "firstspawn.yaw", "firstspawn.pitch")) {
|
||||
String worldName = getString("firstspawn.world");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (!StringUtils.isEmpty(worldName) && world != null) {
|
||||
return new Location(
|
||||
world, getDouble("firstspawn.x"), getDouble("firstspawn.y"), getDouble("firstspawn.z"),
|
||||
Float.parseFloat(getString("firstspawn.yaw")), Float.parseFloat(getString("firstspawn.pitch"))
|
||||
);
|
||||
}
|
||||
return new Location(world, getDouble("firstspawn.x"), getDouble("firstspawn.y"), getDouble("firstspawn.z"),
|
||||
Float.parseFloat(getString("firstspawn.yaw")), Float.parseFloat(getString("firstspawn.pitch")));
|
||||
} catch (NumberFormatException e) {
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return the spawn location of a player
|
||||
|
@ -39,7 +39,7 @@ public class RegistrationSettings implements SettingsClass {
|
||||
newProperty("settings.registration.doubleEmailCheck", false);
|
||||
|
||||
@Comment({
|
||||
"Do we force kicking player after a successful registration?",
|
||||
"Do we force kick a player after a successful registration?",
|
||||
"Do not use with login feature below"})
|
||||
public static final Property<Boolean> FORCE_KICK_AFTER_REGISTER =
|
||||
newProperty("settings.registration.forceKickAfterRegister", false);
|
||||
|
@ -64,7 +64,7 @@ public class RestrictionSettings implements SettingsClass {
|
||||
|
||||
@Comment({
|
||||
"To activate the restricted user feature you need",
|
||||
"to enable this option and configure the AllowedRestrctedUser field."})
|
||||
"to enable this option and configure the AllowedRestrictedUser field."})
|
||||
public static final Property<Boolean> ENABLE_RESTRICTED_USERS =
|
||||
newProperty("settings.restrictions.AllowRestrictedUser", false);
|
||||
|
||||
|
@ -53,12 +53,12 @@ public class ChangePasswordTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Forward");
|
||||
out.writeUTF("ALL");
|
||||
out.writeUTF("AuthMe");
|
||||
out.writeUTF("changepassword;" + name + ";" + hash + ";" + salt);
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Forward");
|
||||
out.writeUTF("ALL");
|
||||
out.writeUTF("AuthMe");
|
||||
out.writeUTF("changepassword;" + name + ";" + hash + ";" + salt);
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ 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 org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
@ -24,32 +25,31 @@ public class MessageTask implements Runnable {
|
||||
* @param strings String[]
|
||||
* @param interval int
|
||||
*/
|
||||
public MessageTask(AuthMe plugin, String name, String[] strings,
|
||||
int interval) {
|
||||
public MessageTask(AuthMe plugin, String name, String[] strings, int interval) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.msg = strings;
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
public MessageTask(AuthMe plugin, String name, MessageKey messageKey, int interval) {
|
||||
this(plugin, name, plugin.getMessages().retrieve(messageKey), interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name))
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (player.getName().toLowerCase().equals(name)) {
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
for (String ms : msg) {
|
||||
player.sendMessage(ms);
|
||||
}
|
||||
BukkitTask late = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, this, interval * 20);
|
||||
BukkitTask nextTask = plugin.getServer().getScheduler().runTaskLater(plugin, this, interval * 20);
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(late);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(nextTask);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -4,14 +4,10 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TimeoutTask implements Runnable {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final String name;
|
||||
private final Messages m;
|
||||
private final Player player;
|
||||
@ -25,38 +21,14 @@ public class TimeoutTask implements Runnable {
|
||||
*/
|
||||
public TimeoutTask(AuthMe plugin, String name, Player player) {
|
||||
this.m = plugin.getMessages();
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getName.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
if (!PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.kickPlayer(m.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR));
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (player.isOnline()) {
|
||||
player.kickPlayer(m.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.converter.ForceFlatToSqlite;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.datasource.FlatFile;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.SHA256;
|
||||
@ -58,12 +60,17 @@ public final class MigrationService {
|
||||
if (DataSourceType.FILE == settings.getProperty(DatabaseSettings.BACKEND)) {
|
||||
ConsoleLogger.showError("FlatFile backend has been detected and is now deprecated; it will be changed "
|
||||
+ "to SQLite... Connection will be impossible until conversion is done!");
|
||||
ForceFlatToSqlite converter = new ForceFlatToSqlite(dataSource, settings);
|
||||
DataSource result = converter.run();
|
||||
if (result == null) {
|
||||
throw new IllegalStateException("Error during conversion from flatfile to SQLite");
|
||||
} else {
|
||||
return result;
|
||||
FlatFile flatFile = (FlatFile) dataSource;
|
||||
try {
|
||||
SQLite sqlite = new SQLite(settings);
|
||||
ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, sqlite);
|
||||
converter.run();
|
||||
settings.setProperty(DatabaseSettings.BACKEND, DataSourceType.SQLITE);
|
||||
settings.save();
|
||||
return sqlite;
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.logException("Error during conversion from Flatfile to SQLite", e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -2,15 +2,13 @@ package fr.xephi.authme.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public class Profiler {
|
||||
|
||||
/**
|
||||
* Defines the past time in milliseconds.
|
||||
*/
|
||||
private long time = 0;
|
||||
|
||||
/**
|
||||
* Defines the time in milliseconds the profiler last started at.
|
||||
*/
|
||||
|
@ -154,8 +154,7 @@ public final class Utils {
|
||||
|
||||
public static boolean isUnrestricted(Player player) {
|
||||
return Settings.isAllowRestrictedIp
|
||||
&& !Settings.getUnrestrictedName.isEmpty()
|
||||
&& (Settings.getUnrestrictedName.contains(player.getName().toLowerCase()));
|
||||
&& Settings.getUnrestrictedName.contains(player.getName().toLowerCase());
|
||||
}
|
||||
|
||||
public static void packCoords(double x, double y, double z, String w, final Player pl) {
|
||||
@ -216,8 +215,7 @@ public final class Utils {
|
||||
ConsoleLogger.showError("Unknown list of online players of type " + type);
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
ConsoleLogger.showError("Could not retrieve list of online players: ["
|
||||
+ e.getClass().getName() + "] " + e.getMessage());
|
||||
ConsoleLogger.logException("Could not retrieve list of online players:", e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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>"'
|
||||
usage_log: '&cBenutze: /login <passwort>'
|
||||
@ -9,11 +9,11 @@ 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!'
|
||||
user_regged: '&cBenutzername ist schon vergeben'
|
||||
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.'
|
||||
no_perm: '&4Du hast keine Rechte, um diese Aktion auszuführen!'
|
||||
error: '&4Ein Fehler ist aufgetreten. Bitte kontaktiere einen Administrator'
|
||||
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>"'
|
||||
@ -21,44 +21,43 @@ 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_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'
|
||||
reg_only: '&4Nur für registrierte Spieler! Bitte besuche http://example.com zum Registrieren'
|
||||
logged_in: '&cBereits eingeloggt!'
|
||||
logout: '&2Erfolgreich ausgeloggt'
|
||||
same_nick: '&4Jemand mit diesem Namen spielt bereits auf dem Server!'
|
||||
registered: '&2Erfolgreich registriert!'
|
||||
pass_len: '&cDein Passwort ist zu kurz oder zu lang!'
|
||||
reload: '&2Konfiguration und Datenbank wurden erfolgreich neu geladen'
|
||||
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'
|
||||
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>'
|
||||
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'
|
||||
valid_captcha: '&2Das Captcha ist korrekt!'
|
||||
kick_forvip: '&3Ein VIP Spieler hat den vollen Server betreten!'
|
||||
kick_forvip: '&3Ein VIP-Spieler hat den vollen Server betreten!'
|
||||
kick_fullserver: '&4Der Server ist momentan voll, Sorry!'
|
||||
usage_email_add: '&cBenutze: /email add <email> <bestätigeEmail>'
|
||||
usage_email_change: '&cBenutze: /email change <alteEmail> <neueEmail>'
|
||||
usage_email_recovery: '&cBenutze: /email recovery <Email>'
|
||||
new_email_invalid: '&cDie neue Email ist ungültig!'
|
||||
old_email_invalid: '&cDie alte Email ist ungültig!'
|
||||
email_invalid: '&cUngültige Email'
|
||||
email_added: '&2Email hinzugefügt!'
|
||||
email_confirm: '&cBitte bestätige deine Email!'
|
||||
email_changed: '&2Email aktualisiert!'
|
||||
email_send: '&2Wiederherstellungs-Email wurde gesendet!'
|
||||
email_exists: '&cEine Wiederherstellungs-Email wurde bereits versandt! Nutze folgenden Befehl um eine neue Email zu versenden:'
|
||||
country_banned: '&4Dein Land ist gesperrt'
|
||||
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_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'
|
||||
# TODO two_factor_create: Missing tag %url
|
||||
two_factor_create: '&2Dein geheimer Code ist %code'
|
||||
# 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!'
|
||||
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.'
|
||||
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.'
|
||||
not_owner_error: 'Du bist nicht der Besitzer dieses Accounts. Bitte wähle einen anderen Namen!'
|
||||
|
@ -12,7 +12,7 @@ login: '&2Successful login!'
|
||||
vb_nonActiv: '&cYour account isn''t activated yet, please check your emails!'
|
||||
user_regged: '&cYou already have registered this username!'
|
||||
usage_reg: '&cUsage: /register <password> <ConfirmPassword>'
|
||||
max_reg: '&cYou have exceeded the maximum number of registrations for your connection!'
|
||||
max_reg: '&cYou have exceeded the maximum number of registrations (%reg_count/%max_acc %reg_names) for your connection!'
|
||||
no_perm: '&4You don''t have the permission to perform this action!'
|
||||
error: '&4An unexpected error occurred, please contact an administrator!'
|
||||
login_msg: '&cPlease, login with the command "/login <password>"'
|
||||
@ -59,5 +59,5 @@ antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number
|
||||
antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m minutes!'
|
||||
email_already_used: '&4The email address is already being used'
|
||||
two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
|
||||
not_owner_error: 'You are not the owner of this account. Please try another name!'
|
||||
not_owner_error: 'You are not the owner of this account. Please choose another name!'
|
||||
invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
package fr.xephi.authme;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
@ -1,14 +1,13 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
|
||||
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.junit.Assert.fail;
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -17,13 +16,12 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
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 static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
|
||||
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.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test for {@link CommandInitializer} to guarantee the integrity of the defined commands.
|
||||
@ -241,15 +239,11 @@ public class CommandInitializerTest {
|
||||
public void shouldNotHavePlayerPermissionIfDefaultsToOpOnly() {
|
||||
// given
|
||||
BiConsumer adminPermissionChecker = new BiConsumer() {
|
||||
// The only exception to this check is the force login command, which should default to OP_ONLY
|
||||
// but semantically it is a player permission
|
||||
final List<String> forceLoginLabels = Arrays.asList("forcelogin", "login");
|
||||
|
||||
@Override
|
||||
public void accept(CommandDescription command, int depth) {
|
||||
CommandPermissions permissions = command.getCommandPermissions();
|
||||
if (permissions != null && OP_ONLY.equals(permissions.getDefaultPermission())) {
|
||||
if (!hasAdminNode(permissions) && !command.getLabels().equals(forceLoginLabels)) {
|
||||
if (!hasAdminNode(permissions)) {
|
||||
fail("The command with labels " + command.getLabels() + " has OP_ONLY default "
|
||||
+ "permission but no permission node on admin level");
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.FlatFile;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Test for {@link ForceFlatToSqlite}.
|
||||
*/
|
||||
public class ForceFlatToSqliteTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
private FlatFile flatFile;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void copyFile() throws IOException {
|
||||
File source = TestHelper.getJarFile("/datasource-integration/flatfile-test.txt");
|
||||
File destination = temporaryFolder.newFile();
|
||||
Files.copy(source, destination);
|
||||
flatFile = new FlatFile(destination);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertToSqlite() {
|
||||
// given
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, dataSource);
|
||||
|
||||
// when
|
||||
converter.run();
|
||||
|
||||
// then
|
||||
ArgumentCaptor<PlayerAuth> authCaptor = ArgumentCaptor.forClass(PlayerAuth.class);
|
||||
verify(dataSource, times(7)).saveAuth(authCaptor.capture());
|
||||
List<PlayerAuth> auths = authCaptor.getAllValues();
|
||||
assertThat(auths, hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89")));
|
||||
assertThat(auths, hasItem(hasAuthLocation(1.05, 2.1, 4.2, "world")));
|
||||
assertThat(auths, hasItem(hasAuthBasicData("user", "user", "user@example.org", "34.56.78.90")));
|
||||
assertThat(auths, hasItem(hasAuthLocation(124.1, 76.3, -127.8, "nether")));
|
||||
assertThat(auths, hasItem(hasAuthBasicData("eightfields", "eightFields", "your@email.com", "6.6.6.66")));
|
||||
assertThat(auths, hasItem(hasAuthLocation(8.8, 17.6, 26.4, "eightworld")));
|
||||
}
|
||||
|
||||
}
|
@ -4,15 +4,18 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.datasource.AuthMeMatchers.equalToHash;
|
||||
import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthBasicData;
|
||||
import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthLocation;
|
||||
import static fr.xephi.authme.AuthMeMatchers.equalToHash;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
/**
|
||||
* Abstract class for data source integration tests.
|
||||
@ -126,15 +129,9 @@ public abstract class AbstractDataSourceIntegrationTest {
|
||||
// then
|
||||
assertThat(response, equalTo(true));
|
||||
assertThat(authList, hasSize(2));
|
||||
assertThat(authList, hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89")));
|
||||
assertThat(newAuthList, hasSize(3));
|
||||
boolean hasBobby = false;
|
||||
for (PlayerAuth auth : authList) {
|
||||
if (auth.getNickname().equals("bobby")) {
|
||||
hasBobby = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertThat(hasBobby, equalTo(true));
|
||||
assertThat(newAuthList, hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -201,4 +198,106 @@ public abstract class AbstractDataSourceIntegrationTest {
|
||||
assertThat(dataSource.getAuth("user"), hasAuthLocation(143, -42.12, 29.47, "the_end"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeletePlayers() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
List<String> playersToDelete = Arrays.asList("bobby", "doesNotExist");
|
||||
assumeThat(dataSource.getAccountsRegistered(), equalTo(2));
|
||||
|
||||
// when
|
||||
dataSource.purgeBanned(playersToDelete);
|
||||
|
||||
// then
|
||||
assertThat(dataSource.getAccountsRegistered(), equalTo(1));
|
||||
assertThat(dataSource.isAuthAvailable("bobby"), equalTo(false));
|
||||
assertThat(dataSource.isAuthAvailable("user"), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateEmail() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
String email = "new-user@mail.tld";
|
||||
PlayerAuth userAuth = PlayerAuth.builder().name("user").email(email).build();
|
||||
PlayerAuth invalidAuth = PlayerAuth.builder().name("invalid").email("addr@example.com").build();
|
||||
|
||||
// when
|
||||
boolean response1 = dataSource.updateEmail(userAuth);
|
||||
boolean response2 = dataSource.updateEmail(invalidAuth);
|
||||
|
||||
// then
|
||||
assertThat(response1 && response2, equalTo(true));
|
||||
assertThat(dataSource.getAllAuths(), hasItem(hasAuthBasicData("user", "user", email, "34.56.78.90")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateIp() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
String ip = "250.230.67.73";
|
||||
|
||||
// when
|
||||
boolean response1 = dataSource.updateIp("bobby", ip);
|
||||
boolean response2 = dataSource.updateIp("bogus", "123.123.123.123");
|
||||
|
||||
|
||||
// then
|
||||
assertThat(response1 && response2, equalTo(true));
|
||||
assertThat(dataSource.getAllAuths(), hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", ip)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCountAuths() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
|
||||
// when
|
||||
int initialCount = dataSource.getAccountsRegistered();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
dataSource.saveAuth(PlayerAuth.builder().name("test-" + i).build());
|
||||
}
|
||||
int endCount = dataSource.getAccountsRegistered();
|
||||
|
||||
// then
|
||||
assertThat(initialCount, equalTo(2));
|
||||
assertThat(endCount, equalTo(6));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetAllUsersByIp() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
|
||||
// when
|
||||
List<String> initialList = dataSource.getAllAuthsByIp("123.45.67.89");
|
||||
List<String> emptyList = dataSource.getAllAuthsByIp("8.8.8.8");
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
dataSource.saveAuth(PlayerAuth.builder().name("test-" + i).ip("123.45.67.89").build());
|
||||
}
|
||||
List<String> updatedList = dataSource.getAllAuthsByIp("123.45.67.89");
|
||||
|
||||
// then
|
||||
assertThat(initialList, hasSize(1));
|
||||
assertThat(initialList.get(0), equalTo("bobby"));
|
||||
assertThat(emptyList, hasSize(0));
|
||||
assertThat(updatedList, hasSize(4));
|
||||
assertThat(updatedList, hasItem(equalTo("bobby")));
|
||||
assertThat(updatedList, hasItem(equalTo("test-1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateRealName() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
|
||||
// when
|
||||
boolean response1 = dataSource.updateRealName("bobby", "BOBBY");
|
||||
boolean response2 = dataSource.updateRealName("notExists", "NOTEXISTS");
|
||||
|
||||
// then
|
||||
assertThat(response1 && response2, equalTo(true));
|
||||
assertThat(dataSource.getAuth("bobby"), hasAuthBasicData("bobby", "BOBBY", "your@email.com", "123.45.67.89"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,321 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Test class which runs through a datasource implementation and verifies that all
|
||||
* instances of {@link AutoCloseable} that are created in the calls are closed again.
|
||||
* <p>
|
||||
* Instead of an actual connection to a datasource, we pass a mock Connection object
|
||||
* which is set to create additional mocks on demand for Statement and ResultSet objects.
|
||||
* This test ensures that all such objects that are created will be closed again by
|
||||
* keeping a list of mocks ({@link #closeables}) and then verifying that all have been
|
||||
* closed {@link #verifyHaveMocksBeenClosed()}.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public abstract class AbstractResourceClosingTest {
|
||||
|
||||
/** List of DataSource method names not to test. */
|
||||
private static final Set<String> IGNORED_METHODS = ImmutableSet.of("reload", "close", "getType");
|
||||
|
||||
/** Collection of values to use to call methods with the parameters they expect. */
|
||||
private static final Map<Class<?>, Object> PARAM_VALUES = getDefaultParameters();
|
||||
|
||||
/**
|
||||
* Custom list of hash algorithms to use to test a method. By default we define {@link HashAlgorithm#XFBCRYPT} as
|
||||
* algorithms we use as a lot of methods execute additional statements in {@link MySQL}. If other algorithms
|
||||
* have custom behaviors, they can be supplied in this map so it will be tested as well.
|
||||
*/
|
||||
private static final Map<String, HashAlgorithm[]> CUSTOM_ALGORITHMS = getCustomAlgorithmList();
|
||||
|
||||
/** Mock of a settings instance. */
|
||||
private static NewSetting settings;
|
||||
|
||||
/** The datasource to test. */
|
||||
private DataSource dataSource;
|
||||
|
||||
/** The DataSource method to test. */
|
||||
private Method method;
|
||||
|
||||
/** Keeps track of the closeables which are created during the tested call. */
|
||||
private List<AutoCloseable> closeables = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor for the test instance verifying the given method with the given hash algorithm.
|
||||
*
|
||||
* @param method The DataSource method to test
|
||||
* @param name The name of the method
|
||||
* @param algorithm The hash algorithm to use
|
||||
*/
|
||||
public AbstractResourceClosingTest(Method method, String name, HashAlgorithm algorithm) {
|
||||
// Note ljacqu 20160227: The name parameter is necessary as we pass it from the @Parameters method;
|
||||
// we use the method name in the annotation to name the test sensibly
|
||||
this.method = method;
|
||||
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(algorithm);
|
||||
}
|
||||
|
||||
/** Initialize the settings mock and makes it return the default of any given property by default. */
|
||||
@BeforeClass
|
||||
public static void initializeSettings() throws IOException, ClassNotFoundException {
|
||||
settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(any(Property.class))).willAnswer(new Answer() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
return ((Property) invocation.getArguments()[0]).getDefaultValue();
|
||||
}
|
||||
});
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
/** Initialize the dataSource implementation to test based on a mock connection. */
|
||||
@Before
|
||||
public void setUpMockConnection() throws Exception {
|
||||
Connection connection = initConnection();
|
||||
dataSource = createDataSource(settings, connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual test -- executes the method given through the constructor and then verifies that all
|
||||
* AutoCloseable mocks it constructed have been closed.
|
||||
*/
|
||||
@Test
|
||||
public void shouldCloseResources() throws IllegalAccessException, InvocationTargetException {
|
||||
method.invoke(dataSource, buildParamListForMethod(method));
|
||||
verifyHaveMocksBeenClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization method -- provides the parameters to run the test with by scanning all DataSource
|
||||
* methods. By default, we run one test per method with the default hash algorithm, XFBCRYPT.
|
||||
* If the map of custom algorithms has an entry for the method name, we add an entry for each algorithm
|
||||
* supplied by the map.
|
||||
*
|
||||
* @return Test parameters
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{1}({2})")
|
||||
public static Collection<Object[]> data() {
|
||||
List<Method> methods = getDataSourceMethods();
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
// Use XFBCRYPT if nothing else specified as there is a lot of specific behavior to this hash algorithm in MySQL
|
||||
final HashAlgorithm[] defaultAlgorithm = new HashAlgorithm[]{HashAlgorithm.XFBCRYPT};
|
||||
for (Method method : methods) {
|
||||
HashAlgorithm[] algorithms = Objects.firstNonNull(CUSTOM_ALGORITHMS.get(method.getName()), defaultAlgorithm);
|
||||
for (HashAlgorithm algorithm : algorithms) {
|
||||
data.add(new Object[]{method, method.getName(), algorithm});
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Create a DataSource instance with the given mock settings and mock connection. */
|
||||
protected abstract DataSource createDataSource(NewSetting settings, Connection connection) throws Exception;
|
||||
|
||||
/* Get all methods of the DataSource interface, minus the ones in the ignored list. */
|
||||
private static List<Method> getDataSourceMethods() {
|
||||
List<Method> publicMethods = new ArrayList<>();
|
||||
for (Method method : DataSource.class.getDeclaredMethods()) {
|
||||
if (!IGNORED_METHODS.contains(method.getName())) {
|
||||
publicMethods.add(method);
|
||||
}
|
||||
}
|
||||
return publicMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that all AutoCloseables that have been created during the method execution have been closed.
|
||||
*/
|
||||
private void verifyHaveMocksBeenClosed() {
|
||||
if (closeables.isEmpty()) {
|
||||
System.out.println("Note: detected no AutoCloseables for method '" + method.getName() + "'");
|
||||
}
|
||||
try {
|
||||
for (AutoCloseable autoCloseable : closeables) {
|
||||
verify(autoCloseable).close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Error verifying if autoCloseable was closed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for building a list of test values to satisfy a method's signature.
|
||||
*
|
||||
* @param method The method to create a valid parameter list for
|
||||
* @return Parameter list to invoke the given method with
|
||||
*/
|
||||
private static Object[] buildParamListForMethod(Method method) {
|
||||
List<Object> params = new ArrayList<>();
|
||||
int index = 0;
|
||||
for (Class<?> paramType : method.getParameterTypes()) {
|
||||
// Checking List.class == paramType instead of Class#isAssignableFrom means we really only accept List,
|
||||
// but that is a sensible assumption and makes our life much easier later on when juggling with Type
|
||||
Object param = (List.class == paramType)
|
||||
? getTypedList(method.getGenericParameterTypes()[index])
|
||||
: PARAM_VALUES.get(paramType);
|
||||
Preconditions.checkNotNull(param, "No param type for " + paramType);
|
||||
params.add(param);
|
||||
++index;
|
||||
}
|
||||
return params.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list with some test elements that correspond to the given list type's generic type.
|
||||
*
|
||||
* @param type The list type to process and build a test list for
|
||||
* @return Test list with sample elements of the correct type
|
||||
*/
|
||||
private static List<?> getTypedList(Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
Preconditions.checkArgument(List.class == parameterizedType.getRawType(), type + " should be a List");
|
||||
Type genericType = parameterizedType.getActualTypeArguments()[0];
|
||||
|
||||
Object element = PARAM_VALUES.get(genericType);
|
||||
Preconditions.checkNotNull(element, "No sample element for list of generic type " + genericType);
|
||||
return Arrays.asList(element, element, element);
|
||||
}
|
||||
throw new IllegalStateException("Cannot build list for unexpected Type: " + type);
|
||||
}
|
||||
|
||||
/* Initialize the map of test values to pass to methods to satisfy their signature. */
|
||||
private static Map<Class<?>, Object> getDefaultParameters() {
|
||||
HashedPassword hash = new HashedPassword("test", "test");
|
||||
return ImmutableMap.<Class<?>, Object>builder()
|
||||
.put(String.class, "test")
|
||||
.put(int.class, 3)
|
||||
.put(long.class, 102L)
|
||||
.put(PlayerAuth.class, PlayerAuth.builder().name("test").realName("test").password(hash).build())
|
||||
.put(HashedPassword.class, hash)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the custom list of hash algorithms to test a method with to execute code specific to
|
||||
* one hash algorithm. By default, XFBCRYPT is used. Only MySQL has code specific to algorithms
|
||||
* but for technical reasons the custom list will be used for all tested classes.
|
||||
*
|
||||
* @return List of custom algorithms by method
|
||||
*/
|
||||
private static Map<String, HashAlgorithm[]> getCustomAlgorithmList() {
|
||||
// We use XFBCRYPT as default encryption method so we don't have to list many of the special cases for it
|
||||
return ImmutableMap.<String, HashAlgorithm[]>builder()
|
||||
.put("saveAuth", new HashAlgorithm[]{HashAlgorithm.PHPBB, HashAlgorithm.WORDPRESS})
|
||||
.build();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// Mock initialization
|
||||
// ---------------------
|
||||
/**
|
||||
* Initialize the connection mock which produces additional AutoCloseable mocks and records them.
|
||||
*
|
||||
* @return Connection mock
|
||||
*/
|
||||
private Connection initConnection() {
|
||||
Connection connection = mock(Connection.class);
|
||||
try {
|
||||
given(connection.prepareStatement(anyString())).willAnswer(preparedStatementAnswer());
|
||||
given(connection.createStatement()).willAnswer(preparedStatementAnswer());
|
||||
given(connection.createBlob()).willReturn(mock(Blob.class));
|
||||
return connection;
|
||||
} catch (SQLException e) {
|
||||
throw new IllegalStateException("Could not initialize connection mock", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create Answer that returns a PreparedStatement mock. */
|
||||
private Answer<PreparedStatement> preparedStatementAnswer() {
|
||||
return new Answer<PreparedStatement>() {
|
||||
@Override
|
||||
public PreparedStatement answer(InvocationOnMock invocation) throws SQLException {
|
||||
PreparedStatement pst = mock(PreparedStatement.class);
|
||||
closeables.add(pst);
|
||||
given(pst.executeQuery()).willAnswer(resultSetAnswer());
|
||||
given(pst.executeQuery(anyString())).willAnswer(resultSetAnswer());
|
||||
return pst;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Create Answer that returns a ResultSet mock. */
|
||||
private Answer<ResultSet> resultSetAnswer() throws SQLException {
|
||||
return new Answer<ResultSet>() {
|
||||
@Override
|
||||
public ResultSet answer(InvocationOnMock invocation) throws Throwable {
|
||||
ResultSet rs = initResultSet();
|
||||
closeables.add(rs);
|
||||
return rs;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Create a ResultSet mock. */
|
||||
private ResultSet initResultSet() throws SQLException {
|
||||
ResultSet rs = mock(ResultSet.class);
|
||||
// Return true for ResultSet#next the first time to make sure we execute all code
|
||||
given(rs.next()).willAnswer(new Answer<Boolean>() {
|
||||
boolean isInitial = true;
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocation) {
|
||||
if (isInitial) {
|
||||
isInitial = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
given(rs.getString(anyInt())).willReturn("test");
|
||||
given(rs.getString(anyString())).willReturn("test");
|
||||
|
||||
Blob blob = mock(Blob.class);
|
||||
given(blob.getBytes(anyLong(), anyInt())).willReturn(new byte[]{});
|
||||
given(blob.length()).willReturn(0L);
|
||||
given(rs.getBlob(anyInt())).willReturn(blob);
|
||||
given(rs.getBlob(anyString())).willReturn(blob);
|
||||
return rs;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.AuthMeMatchers.equalToHash;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation;
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Integration test for the deprecated {@link FlatFile} datasource. The flatfile datasource is no longer used.
|
||||
* Essentially, the only time we use it is in {@link fr.xephi.authme.converter.ForceFlatToSqlite},
|
||||
* which requires {@link FlatFile#getAllAuths()}.
|
||||
*/
|
||||
public class FlatFileIntegrationTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
@Before
|
||||
public void copyFileToTemporaryFolder() throws IOException {
|
||||
File originalFile = TestHelper.getJarFile("/datasource-integration/flatfile-test.txt");
|
||||
File copy = temporaryFolder.newFile();
|
||||
Files.copy(originalFile, copy);
|
||||
dataSource = new FlatFile(copy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnIfAuthIsAvailableOrNot() {
|
||||
// given / when
|
||||
boolean isBobbyAvailable = dataSource.isAuthAvailable("bobby");
|
||||
boolean isChrisAvailable = dataSource.isAuthAvailable("chris");
|
||||
boolean isUserAvailable = dataSource.isAuthAvailable("USER");
|
||||
|
||||
// then
|
||||
assertThat(isBobbyAvailable, equalTo(true));
|
||||
assertThat(isChrisAvailable, equalTo(false));
|
||||
assertThat(isUserAvailable, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnAllAuths() {
|
||||
// given / when
|
||||
List<PlayerAuth> authList = dataSource.getAllAuths();
|
||||
|
||||
// then
|
||||
assertThat(authList, hasSize(7));
|
||||
assertThat(getName("bobby", authList), hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89"));
|
||||
assertThat(getName("bobby", authList), hasAuthLocation(1.05, 2.1, 4.2, "world"));
|
||||
assertThat(getName("bobby", authList).getPassword(), equalToHash("$SHA$11aa0706173d7272$dbba966"));
|
||||
assertThat(getName("twofields", authList), hasAuthBasicData("twofields", "twoFields", "your@email.com", "127.0.0.1"));
|
||||
assertThat(getName("twofields", authList).getPassword(), equalToHash("hash1234"));
|
||||
assertThat(getName("threefields", authList), hasAuthBasicData("threefields", "threeFields", "your@email.com", "33.33.33.33"));
|
||||
assertThat(getName("fourfields", authList), hasAuthBasicData("fourfields", "fourFields", "your@email.com", "4.4.4.4"));
|
||||
assertThat(getName("fourfields", authList).getLastLogin(), equalTo(404040404L));
|
||||
assertThat(getName("sevenfields", authList), hasAuthLocation(7.7, 14.14, 21.21, "world"));
|
||||
assertThat(getName("eightfields", authList), hasAuthLocation(8.8, 17.6, 26.4, "eightworld"));
|
||||
assertThat(getName("eightfields", authList).getLastLogin(), equalTo(1234567888L));
|
||||
assertThat(getName("eightfields", authList).getPassword(), equalToHash("hash8168"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddAuth() {
|
||||
// given / when
|
||||
boolean response = dataSource.saveAuth(
|
||||
PlayerAuth.builder().name("Test").email("user@EXAMPLE.org").ip("123.45.67.77").build());
|
||||
List<PlayerAuth> authList = dataSource.getAllAuths();
|
||||
|
||||
// then
|
||||
assertThat(response, equalTo(true));
|
||||
assertThat(authList, hasSize(8));
|
||||
assertThat(authList, hasItem(hasAuthBasicData("test", "test", "user@EXAMPLE.org", "123.45.67.77")));
|
||||
}
|
||||
|
||||
private static PlayerAuth getName(String name, Collection<PlayerAuth> auths) {
|
||||
for (PlayerAuth auth : auths) {
|
||||
if (name.equals(auth.getNickname())) {
|
||||
return auth;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Did not find auth with name '" + name + "'");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link MySQL}.
|
||||
*/
|
||||
public class MySqlResourceClosingTest extends AbstractResourceClosingTest {
|
||||
|
||||
public MySqlResourceClosingTest(Method method, String name, HashAlgorithm algorithm) {
|
||||
super(method, name, algorithm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSource createDataSource(NewSetting settings, Connection connection) throws Exception {
|
||||
HikariDataSource hikariDataSource = mock(HikariDataSource.class);
|
||||
given(hikariDataSource.getConnection()).willReturn(connection);
|
||||
return new MySQL(settings, hikariDataSource);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link SQLite}.
|
||||
*/
|
||||
public class SQLiteResourceClosingTest extends AbstractResourceClosingTest {
|
||||
|
||||
public SQLiteResourceClosingTest(Method method, String name, HashAlgorithm algorithm) {
|
||||
super(method, name, algorithm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSource createDataSource(NewSetting settings, Connection connection) throws Exception {
|
||||
return new SQLite(settings, connection);
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
package fr.xephi.authme.process.email;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.After;
|
||||
@ -27,11 +26,10 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
public class AsyncAddEmailTest {
|
||||
|
||||
private Messages messages;
|
||||
private Player player;
|
||||
private DataSource dataSource;
|
||||
private PlayerCache playerCache;
|
||||
private NewSetting settings;
|
||||
private ProcessService service;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
@ -42,10 +40,10 @@ public class AsyncAddEmailTest {
|
||||
// Clean up the fields to ensure that no test uses elements of another test
|
||||
@After
|
||||
public void removeFieldValues() {
|
||||
messages = null;
|
||||
player = null;
|
||||
dataSource = null;
|
||||
playerCache = null;
|
||||
service = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -61,11 +59,11 @@ public class AsyncAddEmailTest {
|
||||
given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(dataSource).updateEmail(auth);
|
||||
verify(messages).send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
verify(service).send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
verify(auth).setEmail("my.mail@example.org");
|
||||
verify(playerCache).updatePlayer(auth);
|
||||
}
|
||||
@ -83,11 +81,11 @@ public class AsyncAddEmailTest {
|
||||
given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(dataSource).updateEmail(auth);
|
||||
verify(messages).send(player, MessageKey.ERROR);
|
||||
verify(service).send(player, MessageKey.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -102,10 +100,10 @@ public class AsyncAddEmailTest {
|
||||
given(dataSource.isEmailStored("some.mail@example.org")).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
verify(service).send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@ -121,10 +119,10 @@ public class AsyncAddEmailTest {
|
||||
given(dataSource.isEmailStored("invalid_mail")).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.INVALID_EMAIL);
|
||||
verify(service).send(player, MessageKey.INVALID_EMAIL);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@ -140,10 +138,10 @@ public class AsyncAddEmailTest {
|
||||
given(dataSource.isEmailStored("player@mail.tld")).willReturn(true);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
verify(service).send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@ -156,10 +154,10 @@ public class AsyncAddEmailTest {
|
||||
given(dataSource.isAuthAvailable("Username12")).willReturn(true);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.LOGIN_MESSAGE);
|
||||
verify(service).send(player, MessageKey.LOGIN_MESSAGE);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@ -170,13 +168,13 @@ public class AsyncAddEmailTest {
|
||||
given(player.getName()).willReturn("user");
|
||||
given(playerCache.isAuthenticated("user")).willReturn(false);
|
||||
given(dataSource.isAuthAvailable("user")).willReturn(false);
|
||||
Settings.emailRegistration = true;
|
||||
given(service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
verify(service).send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@ -187,13 +185,13 @@ public class AsyncAddEmailTest {
|
||||
given(player.getName()).willReturn("user");
|
||||
given(playerCache.isAuthenticated("user")).willReturn(false);
|
||||
given(dataSource.isAuthAvailable("user")).willReturn(false);
|
||||
Settings.emailRegistration = false;
|
||||
given(service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
process.run();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.REGISTER_MESSAGE);
|
||||
verify(service).send(player, MessageKey.REGISTER_MESSAGE);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@ -204,14 +202,12 @@ public class AsyncAddEmailTest {
|
||||
* @return The created process
|
||||
*/
|
||||
private AsyncAddEmail createProcess(String email) {
|
||||
messages = mock(Messages.class);
|
||||
AuthMe authMe = mock(AuthMe.class);
|
||||
when(authMe.getMessages()).thenReturn(messages);
|
||||
player = mock(Player.class);
|
||||
dataSource = mock(DataSource.class);
|
||||
playerCache = mock(PlayerCache.class);
|
||||
settings = mock(NewSetting.class);
|
||||
return new AsyncAddEmail(player, authMe, email, dataSource, playerCache, settings);
|
||||
service = mock(ProcessService.class);
|
||||
when(service.getSettings()).thenReturn(mock(NewSetting.class));
|
||||
return new AsyncAddEmail(player, email, dataSource, playerCache, service);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
Bobby:$SHA$11aa0706173d7272$dbba966:123.45.67.89:1449136800:1.05:2.1:4.2:world:your@email.com
|
||||
user:b28c32f624a4eb161d6adc9acb5bfc5b:34.56.78.90:1453242857:124.1:76.3:-127.8:nether:user@example.org
|
||||
twoFields:hash1234
|
||||
threeFields:hash369:33.33.33.33
|
||||
fourFields:$hash$4444:4.4.4.4:404040404
|
||||
sevenFields:hash7749:5.5.5.55:1414141414:7.7:14.14:21.21
|
||||
eightFields:hash8168:6.6.6.66:1234567888:8.8:17.6:26.4:eightworld
|
Loading…
Reference in New Issue
Block a user