mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-10-05 01:48:08 +02:00
commit
4d967563dd
@ -4,7 +4,7 @@
|
||||
|
||||
#####News:
|
||||
|
||||
- We are going to release a stable (and working!) version of AuthMeBungee, in the meantime, a fixed version of the unofficial AuthMeBridgeBukkit plugin can be found at: https://github.com/Xephi/AuthMeReloaded/issues/557 Thanks to @beetle2k
|
||||
- Latest version of AuthMeBridge is finally compatible with latest AuthMe snapshots! ;)
|
||||
|
||||
#####Development tools:
|
||||
|
||||
@ -62,7 +62,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>
|
||||
|
143
pom.xml
143
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-R0.1-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,15 @@
|
||||
</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 -->
|
||||
<configuration>
|
||||
<failOnServiceError>false</failOnServiceError>
|
||||
</configuration>
|
||||
<!-- The secret token is provided by console! -->
|
||||
</plugin>
|
||||
<!-- Javadocs settings -->
|
||||
<plugin>
|
||||
@ -293,6 +268,8 @@
|
||||
<charset>UTF-8</charset>
|
||||
<docencoding>UTF-8</docencoding>
|
||||
<docfilessubdirs>true</docfilessubdirs>
|
||||
<show>public</show>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
@ -359,7 +336,7 @@
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<version>2.4.5</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -371,8 +348,8 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.7.16</version>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.20</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@ -413,7 +390,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>
|
||||
@ -687,7 +664,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>
|
||||
|
@ -2,92 +2,106 @@ package fr.xephi.authme;
|
||||
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_MINUTE;
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
|
||||
|
||||
/**
|
||||
* The AntiBot Service Management class.
|
||||
*/
|
||||
public class AntiBot {
|
||||
|
||||
private static final Wrapper wrapper = Wrapper.getInstance();
|
||||
private static final AuthMe plugin = wrapper.getAuthMe();
|
||||
private static final Messages messages = wrapper.getMessages();
|
||||
private static final List<String> antibotPlayers = new ArrayList<>();
|
||||
private static AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED;
|
||||
private final NewSetting settings;
|
||||
private final Messages messages;
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final BukkitService bukkitService;
|
||||
private final List<String> antibotPlayers = new ArrayList<>();
|
||||
private AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED;
|
||||
|
||||
public static void setupAntiBotService() {
|
||||
if (!Settings.enableAntiBot) {
|
||||
return;
|
||||
public AntiBot(NewSetting settings, Messages messages, PermissionsManager permissionsManager,
|
||||
BukkitService bukkitService) {
|
||||
this.settings = settings;
|
||||
this.messages = messages;
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.bukkitService = bukkitService;
|
||||
|
||||
setupAntiBotService();
|
||||
}
|
||||
|
||||
private void setupAntiBotService() {
|
||||
if (settings.getProperty(ProtectionSettings.ENABLE_ANTIBOT)) {
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
antiBotStatus = AntiBotStatus.LISTENING;
|
||||
}
|
||||
}, 2 * TICKS_PER_MINUTE);
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
|
||||
public void overrideAntiBotStatus(boolean activated) {
|
||||
if (antiBotStatus != AntiBotStatus.DISABLED) {
|
||||
if (activated) {
|
||||
antiBotStatus = AntiBotStatus.ACTIVE;
|
||||
} else {
|
||||
antiBotStatus = AntiBotStatus.LISTENING;
|
||||
}
|
||||
}, 2400);
|
||||
}
|
||||
|
||||
public static void overrideAntiBotStatus(boolean activated) {
|
||||
if (antiBotStatus == AntiBotStatus.DISABLED) {
|
||||
return;
|
||||
}
|
||||
if (activated) {
|
||||
antiBotStatus = AntiBotStatus.ACTIVE;
|
||||
} else {
|
||||
antiBotStatus = AntiBotStatus.LISTENING;
|
||||
}
|
||||
}
|
||||
|
||||
public static AntiBotStatus getAntiBotStatus() {
|
||||
public AntiBotStatus getAntiBotStatus() {
|
||||
return antiBotStatus;
|
||||
}
|
||||
|
||||
public static void activateAntiBot() {
|
||||
public void activateAntiBot() {
|
||||
antiBotStatus = AntiBotStatus.ACTIVE;
|
||||
for (String s : messages.retrieve(MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE)) {
|
||||
Bukkit.broadcastMessage(s);
|
||||
bukkitService.broadcastMessage(s);
|
||||
}
|
||||
|
||||
wrapper.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
final int duration = settings.getProperty(ProtectionSettings.ANTIBOT_DURATION);
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (antiBotStatus == AntiBotStatus.ACTIVE) {
|
||||
antiBotStatus = AntiBotStatus.LISTENING;
|
||||
antibotPlayers.clear();
|
||||
for (String s : messages.retrieve(MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE)) {
|
||||
Bukkit.broadcastMessage(s.replace("%m", "" + Settings.antiBotDuration));
|
||||
bukkitService.broadcastMessage(s.replace("%m", Integer.toString(duration)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, Settings.antiBotDuration * 1200);
|
||||
}, duration * TICKS_PER_MINUTE);
|
||||
}
|
||||
|
||||
public static void checkAntiBot(final Player player) {
|
||||
public void checkAntiBot(final Player player) {
|
||||
if (antiBotStatus == AntiBotStatus.ACTIVE || antiBotStatus == AntiBotStatus.DISABLED) {
|
||||
return;
|
||||
}
|
||||
if (plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)) {
|
||||
if (permissionsManager.hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
antibotPlayers.add(player.getName().toLowerCase());
|
||||
if (antibotPlayers.size() > Settings.antiBotSensibility) {
|
||||
if (antibotPlayers.size() > settings.getProperty(ProtectionSettings.ANTIBOT_SENSIBILITY)) {
|
||||
activateAntiBot();
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
antibotPlayers.remove(player.getName().toLowerCase());
|
||||
}
|
||||
}, 300);
|
||||
}, 15 * TICKS_PER_SECOND);
|
||||
}
|
||||
|
||||
public enum AntiBotStatus {
|
||||
|
@ -1,11 +1,8 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Resources;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.api.NewAPI;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.JsonCache;
|
||||
@ -24,7 +21,7 @@ import fr.xephi.authme.datasource.FlatFile;
|
||||
import fr.xephi.authme.datasource.MySQL;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.hooks.BungeeCordMessage;
|
||||
import fr.xephi.authme.hooks.EssSpawn;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.listener.AuthMeBlockListener;
|
||||
import fr.xephi.authme.listener.AuthMeEntityListener;
|
||||
import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter;
|
||||
@ -42,24 +39,29 @@ 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.SpawnLoader;
|
||||
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.PurgeSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import fr.xephi.authme.util.MigrationService;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import net.minelink.ctplus.CombatTagPlus;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@ -72,8 +74,6 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@ -111,7 +111,7 @@ public class AuthMe extends JavaPlugin {
|
||||
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
|
||||
@ -119,26 +119,26 @@ 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
|
||||
*/
|
||||
public Essentials ess;
|
||||
public MultiverseCore multiverse;
|
||||
public CombatTagPlus combatTagPlus;
|
||||
public AuthMeInventoryPacketAdapter inventoryProtector;
|
||||
public AuthMeTabCompletePacketAdapter tabComplete;
|
||||
public AuthMeTablistPacketAdapter tablistHider;
|
||||
private Management management;
|
||||
private CommandHandler commandHandler = null;
|
||||
private PermissionsManager permsMan = null;
|
||||
private CommandHandler commandHandler;
|
||||
private PermissionsManager permsMan;
|
||||
private NewSetting newSettings;
|
||||
private Messages messages;
|
||||
private JsonCache playerBackup;
|
||||
private PasswordSecurity passwordSecurity;
|
||||
private DataSource database;
|
||||
private IpAddressManager ipAddressManager;
|
||||
private PluginHooks pluginHooks;
|
||||
private SpawnLoader spawnLoader;
|
||||
private AntiBot antiBot;
|
||||
private boolean autoPurging;
|
||||
|
||||
/**
|
||||
* Get the plugin's instance.
|
||||
@ -248,16 +248,24 @@ public class AuthMe extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
pluginHooks = new PluginHooks(server.getPluginManager());
|
||||
|
||||
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
|
||||
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings.getProperty(SecuritySettings.PASSWORD_HASH),
|
||||
Bukkit.getPluginManager(), newSettings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH));
|
||||
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager());
|
||||
ipAddressManager = new IpAddressManager(newSettings);
|
||||
|
||||
// Initialize spawn loader
|
||||
spawnLoader = new SpawnLoader(getDataFolder(), newSettings, pluginHooks);
|
||||
|
||||
|
||||
// Set up the permissions manager and command handler
|
||||
permsMan = initializePermissionsManager();
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings);
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager,
|
||||
pluginHooks, spawnLoader, antiBot);
|
||||
|
||||
// Setup otherAccounts file
|
||||
this.otherAccounts = OtherAccounts.getInstance();
|
||||
// AntiBot delay
|
||||
BukkitService bukkitService = new BukkitService(this);
|
||||
antiBot = new AntiBot(newSettings, messages, permsMan, bukkitService);
|
||||
|
||||
// Set up Metrics
|
||||
MetricsStarter.setupMetrics(plugin, newSettings);
|
||||
@ -265,25 +273,12 @@ public class AuthMe extends JavaPlugin {
|
||||
// Set console filter
|
||||
setupConsoleFilter();
|
||||
|
||||
// AntiBot delay
|
||||
AntiBot.setupAntiBotService();
|
||||
|
||||
// Download and load GeoIp.dat file if absent
|
||||
GeoLiteAPI.isDataAvailable();
|
||||
|
||||
// Set up the mail API
|
||||
setupMailApi();
|
||||
|
||||
// Hooks
|
||||
// Check Combat Tag Plus Version
|
||||
checkCombatTagPlus();
|
||||
|
||||
// Check Multiverse
|
||||
checkMultiverse();
|
||||
|
||||
// Check Essentials
|
||||
checkEssentials();
|
||||
|
||||
// Check if the ProtocolLib is available. If so we could listen for
|
||||
// inventory protection
|
||||
checkProtocolLib();
|
||||
@ -297,26 +292,24 @@ public class AuthMe extends JavaPlugin {
|
||||
playerBackup = new JsonCache();
|
||||
|
||||
// Set the DataManager
|
||||
dataManager = new DataManager(this);
|
||||
dataManager = new DataManager(this, pluginHooks);
|
||||
|
||||
// Set up the new API
|
||||
setupApi();
|
||||
|
||||
// Set up the management
|
||||
management = new Management(this, newSettings);
|
||||
ProcessService processService = new ProcessService(newSettings, messages, this, database, ipAddressManager,
|
||||
passwordSecurity, pluginHooks, spawnLoader);
|
||||
management = new Management(this, processService, database, PlayerCache.getInstance());
|
||||
|
||||
// Set up the BungeeCord hook
|
||||
setupBungeeCordHook();
|
||||
setupBungeeCordHook(newSettings, ipAddressManager);
|
||||
|
||||
// Reload support hook
|
||||
reloadSupportHook();
|
||||
|
||||
// Register event listeners
|
||||
registerEventListeners();
|
||||
|
||||
// Purge on start if enabled
|
||||
autoPurge();
|
||||
|
||||
registerEventListeners(messages, database, management, pluginHooks, spawnLoader, antiBot);
|
||||
// Start Email recall task if needed
|
||||
scheduleRecallEmailTask();
|
||||
|
||||
@ -330,6 +323,26 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
// Successful message
|
||||
ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " correctly enabled!");
|
||||
|
||||
// Purge on start if enabled
|
||||
runAutoPurge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload certain components.
|
||||
*
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
public void reload() throws Exception {
|
||||
newSettings.reload();
|
||||
// We do not change database type for consistency issues, but we'll output a note in the logs
|
||||
if (!newSettings.getProperty(DatabaseSettings.BACKEND).equals(database.getType())) {
|
||||
ConsoleLogger.info("Note: cannot change database type during /authme reload");
|
||||
}
|
||||
database.reload();
|
||||
messages.reload(newSettings.getMessagesFile());
|
||||
passwordSecurity.reload(newSettings);
|
||||
spawnLoader.initialize(newSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,15 +374,16 @@ public class AuthMe extends JavaPlugin {
|
||||
/**
|
||||
* Register all event listeners.
|
||||
*/
|
||||
private void registerEventListeners() {
|
||||
private void registerEventListeners(Messages messages, DataSource dataSource, Management management,
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot) {
|
||||
// Get the plugin manager instance
|
||||
PluginManager pluginManager = server.getPluginManager();
|
||||
|
||||
// Register event listeners
|
||||
pluginManager.registerEvents(new AuthMePlayerListener(this), this);
|
||||
pluginManager.registerEvents(new AuthMePlayerListener(this, messages, dataSource, antiBot, management), this);
|
||||
pluginManager.registerEvents(new AuthMeBlockListener(), this);
|
||||
pluginManager.registerEvents(new AuthMeEntityListener(), this);
|
||||
pluginManager.registerEvents(new AuthMeServerListener(this), this);
|
||||
pluginManager.registerEvents(new AuthMeServerListener(this, messages, pluginHooks, spawnLoader), this);
|
||||
|
||||
// Try to register 1.6 player listeners
|
||||
try {
|
||||
@ -407,20 +421,23 @@ public class AuthMe extends JavaPlugin {
|
||||
/**
|
||||
* Set up the BungeeCord hook.
|
||||
*/
|
||||
private void setupBungeeCordHook() {
|
||||
if (newSettings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
private void setupBungeeCordHook(NewSetting settings, IpAddressManager ipAddressManager) {
|
||||
if (settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordMessage(this));
|
||||
Bukkit.getMessenger().registerIncomingPluginChannel(
|
||||
this, "BungeeCord", new BungeeCordMessage(this, ipAddressManager));
|
||||
}
|
||||
}
|
||||
|
||||
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
|
||||
PasswordSecurity passwordSecurity, NewSetting settings) {
|
||||
PasswordSecurity passwordSecurity, NewSetting settings,
|
||||
IpAddressManager ipAddressManager, PluginHooks pluginHooks,
|
||||
SpawnLoader spawnLoader, AntiBot antiBot) {
|
||||
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
|
||||
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
|
||||
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
|
||||
CommandService commandService = new CommandService(
|
||||
this, mapper, helpProvider, messages, passwordSecurity, permissionsManager, settings);
|
||||
CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity,
|
||||
permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot);
|
||||
return new CommandHandler(commandService);
|
||||
}
|
||||
|
||||
@ -455,8 +472,10 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
private NewSetting createNewSetting() {
|
||||
File configFile = new File(getDataFolder(), "config.yml");
|
||||
return SettingsMigrationService.copyFileFromResource(configFile, "config.yml")
|
||||
? new NewSetting(configFile, getDataFolder())
|
||||
PropertyMap properties = SettingsFieldRetriever.getAllPropertyFields();
|
||||
SettingsMigrationService migrationService = new SettingsMigrationService();
|
||||
return FileUtils.copyFileFromResource(configFile, "config.yml")
|
||||
? new NewSetting(configFile, getDataFolder(), properties, migrationService)
|
||||
: null;
|
||||
}
|
||||
|
||||
@ -546,6 +565,8 @@ public class AuthMe extends JavaPlugin {
|
||||
*
|
||||
* @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
|
||||
* @see AuthMe#database
|
||||
*/
|
||||
public void setupDatabase(NewSetting settings) throws ClassNotFoundException, SQLException {
|
||||
@ -600,80 +621,20 @@ public class AuthMe extends JavaPlugin {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions manager instance.
|
||||
*
|
||||
* @return Permissions Manager instance.
|
||||
*/
|
||||
public PermissionsManager getPermissionsManager() {
|
||||
return this.permsMan;
|
||||
}
|
||||
|
||||
// Set the console filter to remove the passwords
|
||||
private void setLog4JFilter() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger();
|
||||
coreLogger.addFilter(new Log4JFilter());
|
||||
org.apache.logging.log4j.core.Logger logger;
|
||||
logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger();
|
||||
logger.addFilter(new Log4JFilter());
|
||||
logger = (org.apache.logging.log4j.core.Logger) LogManager.getLogger("net.minecraft");
|
||||
logger.addFilter(new Log4JFilter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get the Multiverse plugin
|
||||
public void checkMultiverse() {
|
||||
if (Settings.multiverse && server.getPluginManager().isPluginEnabled("Multiverse-Core")) {
|
||||
try {
|
||||
multiverse = (MultiverseCore) server.getPluginManager().getPlugin("Multiverse-Core");
|
||||
ConsoleLogger.info("Hooked correctly with Multiverse-Core");
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
multiverse = null;
|
||||
}
|
||||
} else {
|
||||
multiverse = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the Essentials plugin
|
||||
public void checkEssentials() {
|
||||
if (server.getPluginManager().isPluginEnabled("Essentials")) {
|
||||
try {
|
||||
ess = (Essentials) server.getPluginManager().getPlugin("Essentials");
|
||||
ConsoleLogger.info("Hooked correctly with Essentials");
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
ess = null;
|
||||
}
|
||||
} else {
|
||||
ess = null;
|
||||
}
|
||||
if (server.getPluginManager().isPluginEnabled("EssentialsSpawn")) {
|
||||
try {
|
||||
essentialsSpawn = new EssSpawn().getLocation();
|
||||
ConsoleLogger.info("Hooked correctly with EssentialsSpawn");
|
||||
} catch (Exception e) {
|
||||
essentialsSpawn = null;
|
||||
ConsoleLogger.showError("Can't read the /plugins/Essentials/spawn.yml file!");
|
||||
}
|
||||
} else {
|
||||
essentialsSpawn = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the presence of CombatTag
|
||||
public void checkCombatTagPlus() {
|
||||
if (server.getPluginManager().isPluginEnabled("CombatTagPlus")) {
|
||||
try {
|
||||
combatTagPlus = (CombatTagPlus) server.getPluginManager().getPlugin("CombatTagPlus");
|
||||
ConsoleLogger.info("Hooked correctly with CombatTagPlus");
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
combatTagPlus = null;
|
||||
}
|
||||
} else {
|
||||
combatTagPlus = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the presence of the ProtocolLib plugin
|
||||
public void checkProtocolLib() {
|
||||
if (!server.getPluginManager().isPluginEnabled("ProtocolLib")) {
|
||||
@ -716,7 +677,10 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
String name = player.getName().toLowerCase();
|
||||
if (PlayerCache.getInstance().isAuthenticated(name) && !player.isDead() && Settings.isSaveQuitLocationEnabled) {
|
||||
final PlayerAuth auth = new PlayerAuth(player.getName().toLowerCase(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player.getWorld().getName(), player.getName());
|
||||
final PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(player.getName().toLowerCase())
|
||||
.realName(player.getName())
|
||||
.location(player.getLocation()).build();
|
||||
database.updateQuitLoc(auth);
|
||||
}
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
@ -726,8 +690,8 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
Utils.addNormal(player, limbo.getGroup());
|
||||
player.setOp(limbo.getOperator());
|
||||
limbo.getTimeoutTaskId().cancel();
|
||||
player.setOp(limbo.isOperator());
|
||||
limbo.getTimeoutTask().cancel();
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
if (this.playerBackup.doesCacheExist(player)) {
|
||||
this.playerBackup.removeCache(player);
|
||||
@ -747,34 +711,43 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
// Purge inactive players from the database, as defined in the configuration
|
||||
private void autoPurge() {
|
||||
if (!Settings.usePurge) {
|
||||
private void runAutoPurge() {
|
||||
if (!newSettings.getProperty(PurgeSettings.USE_AUTO_PURGE) || autoPurging) {
|
||||
return;
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DATE, -(Settings.purgeDelay));
|
||||
long until = calendar.getTimeInMillis();
|
||||
List<String> cleared = database.autoPurgeDatabase(until);
|
||||
if (CollectionUtils.isEmpty(cleared)) {
|
||||
return;
|
||||
}
|
||||
ConsoleLogger.info("AutoPurging the Database: " + cleared.size() + " accounts removed!");
|
||||
if (Settings.purgeEssentialsFile && this.ess != null)
|
||||
dataManager.purgeEssentials(cleared);
|
||||
if (Settings.purgePlayerDat)
|
||||
dataManager.purgeDat(cleared);
|
||||
if (Settings.purgeLimitedCreative)
|
||||
dataManager.purgeLimitedCreative(cleared);
|
||||
if (Settings.purgeAntiXray)
|
||||
dataManager.purgeAntiXray(cleared);
|
||||
if (Settings.purgePermissions)
|
||||
dataManager.purgePermissions(cleared);
|
||||
autoPurging = true;
|
||||
server.getScheduler().runTaskAsynchronously(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ConsoleLogger.info("AutoPurging the Database...");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DATE, -newSettings.getProperty(PurgeSettings.DAYS_BEFORE_REMOVE_PLAYER));
|
||||
long until = calendar.getTimeInMillis();
|
||||
List<String> cleared = database.autoPurgeDatabase(until);
|
||||
if (CollectionUtils.isEmpty(cleared)) {
|
||||
return;
|
||||
}
|
||||
ConsoleLogger.info("AutoPurging the Database: " + cleared.size() + " accounts removed!");
|
||||
if (newSettings.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES) && pluginHooks.isEssentialsAvailable())
|
||||
dataManager.purgeEssentials(cleared);
|
||||
if (newSettings.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
|
||||
dataManager.purgeDat(cleared);
|
||||
if (newSettings.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
|
||||
dataManager.purgeLimitedCreative(cleared);
|
||||
if (newSettings.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
|
||||
dataManager.purgeAntiXray(cleared);
|
||||
if (newSettings.getProperty(PurgeSettings.REMOVE_PERMISSIONS))
|
||||
dataManager.purgePermissions(cleared);
|
||||
ConsoleLogger.info("AutoPurge Finished!");
|
||||
autoPurging = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Return the spawn location of a player
|
||||
@Deprecated
|
||||
public Location getSpawnLocation(Player player) {
|
||||
return Spawn.getInstance().getSpawnLocation(player);
|
||||
return spawnLoader.getSpawnLocation(player);
|
||||
}
|
||||
|
||||
private void scheduleRecallEmailTask() {
|
||||
@ -786,7 +759,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);
|
||||
@ -794,77 +767,37 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1, 1200 * Settings.delayRecall);
|
||||
}, 1, 1200 * newSettings.getProperty(EmailSettings.DELAY_RECALL));
|
||||
}
|
||||
|
||||
public String replaceAllInfo(String message, Player player) {
|
||||
String playersOnline = Integer.toString(Utils.getOnlinePlayers().size());
|
||||
String ipAddress = ipAddressManager.getPlayerIp(player);
|
||||
return message
|
||||
.replace("&", "\u00a7")
|
||||
.replace("{PLAYER}", player.getName())
|
||||
.replace("{ONLINE}", playersOnline)
|
||||
.replace("{MAXPLAYERS}", Integer.toString(server.getMaxPlayers()))
|
||||
.replace("{IP}", getIP(player))
|
||||
.replace("{IP}", ipAddress)
|
||||
.replace("{LOGINS}", Integer.toString(PlayerCache.getInstance().getLogged()))
|
||||
.replace("{WORLD}", player.getWorld().getName())
|
||||
.replace("{SERVER}", server.getServerName())
|
||||
.replace("{VERSION}", server.getBukkitVersion())
|
||||
.replace("{COUNTRY}", GeoLiteAPI.getCountryName(getIP(player)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a player's real IP through VeryGames method.
|
||||
*
|
||||
* @param player The player to process.
|
||||
*/
|
||||
@Deprecated
|
||||
public void getVerygamesIp(final Player player) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String currentIp = player.getAddress().getAddress().getHostAddress();
|
||||
if (realIp.containsKey(name)) {
|
||||
currentIp = realIp.get(name);
|
||||
}
|
||||
String sUrl = "http://monitor-1.verygames.net/api/?action=ipclean-real-ip&out=raw&ip=%IP%&port=%PORT%";
|
||||
sUrl = sUrl.replace("%IP%", currentIp).replace("%PORT%", "" + player.getAddress().getPort());
|
||||
try {
|
||||
String result = Resources.toString(new URL(sUrl), Charsets.UTF_8);
|
||||
if (!StringUtils.isEmpty(result) && !result.equalsIgnoreCase("error") && !result.contains("error")) {
|
||||
currentIp = result;
|
||||
realIp.put(name, currentIp);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError("Could not fetch Very Games API with URL '" +
|
||||
sUrl + "' - " + StringUtils.formatException(e));
|
||||
}
|
||||
}
|
||||
|
||||
public String getIP(final Player player) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String ip = player.getAddress().getAddress().getHostAddress();
|
||||
if (realIp.containsKey(name)) {
|
||||
ip = realIp.get(name);
|
||||
}
|
||||
return ip;
|
||||
.replace("{COUNTRY}", GeoLiteAPI.getCountryName(ipAddress));
|
||||
}
|
||||
|
||||
public boolean isLoggedIp(String name, String ip) {
|
||||
int count = 0;
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(getIP(player)) && database.isLogged(player.getName().toLowerCase()) && !player.getName().equalsIgnoreCase(name))
|
||||
count++;
|
||||
if (ip.equalsIgnoreCase(ipAddressManager.getPlayerIp(player))
|
||||
&& database.isLogged(player.getName().toLowerCase())
|
||||
&& !player.getName().equalsIgnoreCase(name)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
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.
|
||||
*
|
||||
@ -888,6 +821,15 @@ public class AuthMe extends JavaPlugin {
|
||||
return commandHandler.processCommand(sender, commandLabel, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions manager instance.
|
||||
*
|
||||
* @return Permissions Manager instance.
|
||||
*/
|
||||
public PermissionsManager getPermissionsManager() {
|
||||
return this.permsMan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the management instance.
|
||||
*
|
||||
@ -905,4 +847,8 @@ public class AuthMe extends JavaPlugin {
|
||||
return passwordSecurity;
|
||||
}
|
||||
|
||||
public PluginHooks getPluginHooks() {
|
||||
return pluginHooks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,161 +1,112 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.properties.PurgeSettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class DataManager {
|
||||
|
||||
public final AuthMe plugin;
|
||||
private final AuthMe plugin;
|
||||
private final PluginHooks pluginHooks;
|
||||
|
||||
/**
|
||||
* Constructor for DataManager.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
* @param plugin The plugin instance
|
||||
* @param pluginHooks Plugin hooks instance
|
||||
*/
|
||||
public DataManager(AuthMe plugin) {
|
||||
public DataManager(AuthMe plugin, PluginHooks pluginHooks) {
|
||||
this.plugin = plugin;
|
||||
this.pluginHooks = pluginHooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getOfflinePlayer.
|
||||
*
|
||||
* @param name String
|
||||
*
|
||||
* @return OfflinePlayer
|
||||
*/
|
||||
public synchronized OfflinePlayer getOfflinePlayer(final String name) {
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
Future<OfflinePlayer> result = executor.submit(new Callable<OfflinePlayer>() {
|
||||
|
||||
public synchronized OfflinePlayer call() throws Exception {
|
||||
OfflinePlayer result = null;
|
||||
try {
|
||||
for (OfflinePlayer op : Bukkit.getOfflinePlayers())
|
||||
if (op.getName().equalsIgnoreCase(name)) {
|
||||
result = op;
|
||||
break;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
private List<OfflinePlayer> getOfflinePlayers(List<String> names) {
|
||||
List<OfflinePlayer> result = new ArrayList<>();
|
||||
for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {
|
||||
for (String name : names) {
|
||||
if (name.equalsIgnoreCase(op.getName())) {
|
||||
result.add(op);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
try {
|
||||
return result.get();
|
||||
} catch (Exception e) {
|
||||
return (null);
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method purgeAntiXray.
|
||||
*
|
||||
* @param cleared List of String
|
||||
*/
|
||||
public synchronized void purgeAntiXray(List<String> cleared) {
|
||||
public void purgeAntiXray(List<String> cleared) {
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
try {
|
||||
org.bukkit.OfflinePlayer player = getOfflinePlayer(name);
|
||||
if (player == null)
|
||||
continue;
|
||||
String playerName = player.getName();
|
||||
File playerFile = new File("." + File.separator + "plugins" + File.separator + "AntiXRayData" + File.separator + "PlayerData" + File.separator + playerName);
|
||||
if (playerFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
File dataFolder = new File("." + File.separator + "plugins" + File.separator + "AntiXRayData"
|
||||
+ File.separator + "PlayerData");
|
||||
if (!dataFolder.exists() || !dataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
for (String file : dataFolder.list()) {
|
||||
if (cleared.contains(file.toLowerCase())) {
|
||||
File playerFile = new File(dataFolder, file);
|
||||
if (playerFile.exists() && playerFile.delete()) {
|
||||
i++;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " AntiXRayData Files");
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " AntiXRayData Files");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method purgeLimitedCreative.
|
||||
*
|
||||
* @param cleared List of String
|
||||
*/
|
||||
public synchronized void purgeLimitedCreative(List<String> cleared) {
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
try {
|
||||
org.bukkit.OfflinePlayer player = getOfflinePlayer(name);
|
||||
if (player == null)
|
||||
continue;
|
||||
String playerName = player.getName();
|
||||
File playerFile = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative" + File.separator + "inventories" + File.separator + playerName + ".yml");
|
||||
if (playerFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
i++;
|
||||
}
|
||||
playerFile = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative" + File.separator + "inventories" + File.separator + playerName + "_creative.yml");
|
||||
if (playerFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
i++;
|
||||
}
|
||||
playerFile = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative" + File.separator + "inventories" + File.separator + playerName + "_adventure.yml");
|
||||
if (playerFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
i++;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " LimitedCreative Survival, Creative and Adventure files");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method purgeDat.
|
||||
*
|
||||
* @param cleared List of String
|
||||
*/
|
||||
public synchronized void purgeDat(List<String> cleared) {
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
try {
|
||||
org.bukkit.OfflinePlayer player = getOfflinePlayer(name);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
File playerFile = new File(plugin.getServer().getWorldContainer() + File.separator + Settings.defaultWorld + File.separator + "players" + File.separator + player.getUniqueId() + ".dat");
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
i++;
|
||||
} catch (Exception ignore) {
|
||||
File playerFile = new File(plugin.getServer().getWorldContainer() + File.separator + Settings.defaultWorld + File.separator + "players" + File.separator + player.getName() + ".dat");
|
||||
if (playerFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
i++;
|
||||
File dataFolder = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative"
|
||||
+ File.separator + "inventories");
|
||||
for (String file : dataFolder.list()) {
|
||||
String name = file;
|
||||
int idx;
|
||||
idx = file.lastIndexOf("_creative.yml");
|
||||
if (idx != -1) {
|
||||
name = name.substring(0, idx);
|
||||
} else {
|
||||
idx = file.lastIndexOf("_adventure.yml");
|
||||
if (idx != -1) {
|
||||
name = name.substring(0, idx);
|
||||
} else {
|
||||
idx = file.lastIndexOf(".yml");
|
||||
if (idx != -1) {
|
||||
name = name.substring(0, idx);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
if (name.equals(file)) {
|
||||
continue;
|
||||
}
|
||||
if (cleared.contains(name.toLowerCase())) {
|
||||
File dataFile = new File(dataFolder, file);
|
||||
if (dataFile.exists() && dataFile.delete()) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " .dat Files");
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " LimitedCreative Survival, Creative and Adventure files");
|
||||
}
|
||||
|
||||
public synchronized void purgeDat(List<String> cleared) {
|
||||
int i = 0;
|
||||
File dataFolder = new File(plugin.getServer().getWorldContainer()
|
||||
+ File.separator + plugin.getSettings().getProperty(PurgeSettings.DEFAULT_WORLD)
|
||||
+ File.separator + "players");
|
||||
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
|
||||
for (OfflinePlayer player : offlinePlayers) {
|
||||
File playerFile = new File(dataFolder, Utils.getUUIDorName(player) + ".dat");
|
||||
if (playerFile.delete()) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " .dat Files");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,107 +114,49 @@ public class DataManager {
|
||||
*
|
||||
* @param cleared List of String
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void purgeEssentials(List<String> cleared) {
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
try {
|
||||
File playerFile = new File(plugin.ess.getDataFolder() + File.separator + "userdata" + File.separator + plugin.getServer().getOfflinePlayer(name).getUniqueId() + ".yml");
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
File essentialsDataFolder = pluginHooks.getEssentialsDataFolder();
|
||||
if (essentialsDataFolder == null) {
|
||||
ConsoleLogger.info("Cannot purge Essentials: plugin is not loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
final File userDataFolder = new File(essentialsDataFolder, "userdata");
|
||||
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
|
||||
for (OfflinePlayer player : offlinePlayers) {
|
||||
File playerFile = new File(userDataFolder, Utils.getUUIDorName(player) + ".yml");
|
||||
if (playerFile.exists() && playerFile.delete()) {
|
||||
i++;
|
||||
} catch (Exception e) {
|
||||
File playerFile = new File(plugin.ess.getDataFolder() + File.separator + "userdata" + File.separator + name + ".yml");
|
||||
if (playerFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
playerFile.delete();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " EssentialsFiles");
|
||||
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " EssentialsFiles");
|
||||
}
|
||||
|
||||
// TODO: What is this method for? Is it correct?
|
||||
|
||||
/**
|
||||
* @param cleared Cleared players.
|
||||
*/
|
||||
// TODO: Make it work with OfflinePlayers group data.
|
||||
public synchronized void purgePermissions(List<String> cleared) {
|
||||
// Get the permissions manager, and make sure it's valid
|
||||
PermissionsManager permsMan = this.plugin.getPermissionsManager();
|
||||
if (permsMan == null)
|
||||
PermissionsManager permsMan = plugin.getPermissionsManager();
|
||||
if (permsMan == null) {
|
||||
ConsoleLogger.showError("Unable to access permissions manager instance!");
|
||||
assert permsMan != null;
|
||||
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
try {
|
||||
permsMan.removeAllGroups(this.getOnlinePlayerLower(name.toLowerCase()));
|
||||
i++;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
permsMan.removeAllGroups(getOnlinePlayerLower(name));
|
||||
i++;
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Removed " + i + "permissions");
|
||||
|
||||
/*int i = 0;
|
||||
for (String name : cleared) {
|
||||
try {
|
||||
OfflinePlayer p = this.getOfflinePlayer(name);
|
||||
for (String group : permission.getPlayerGroups((Player) p)) {
|
||||
permission.playerRemoveGroup(null, p, group);
|
||||
}
|
||||
i++;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " Permissions");*/
|
||||
ConsoleLogger.info("AutoPurge: Removed permissions from " + i + " player(s).");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isOnline.
|
||||
*
|
||||
* @param player Player
|
||||
* @param name String
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isOnline(Player player, final String name) {
|
||||
if (player.isOnline())
|
||||
return true;
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
Future<Boolean> result = executor.submit(new Callable<Boolean>() {
|
||||
|
||||
@Override
|
||||
public synchronized Boolean call() throws Exception {
|
||||
for (OfflinePlayer op : Utils.getOnlinePlayers())
|
||||
if (op.getName().equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
try {
|
||||
return result.get();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getOnlinePlayerLower.
|
||||
*
|
||||
* @param name String
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getOnlinePlayerLower(String name) {
|
||||
private Player getOnlinePlayerLower(String name) {
|
||||
name = name.toLowerCase();
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (player.getName().equalsIgnoreCase(name))
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -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) {
|
||||
@ -65,11 +69,20 @@ public class NewAPI {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the version number of the plugin.
|
||||
* This can be used to determine whether certain API features are available or not.
|
||||
*
|
||||
* @return Plugin version identifier as a string.
|
||||
*/
|
||||
public String getPluginVersion() {
|
||||
return AuthMe.getPluginVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 +90,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 +114,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 +141,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 +148,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 +169,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 +187,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 +197,7 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a player to unregister.
|
||||
* Unregister a player from AuthMe.
|
||||
*
|
||||
* @param player The player to unregister
|
||||
*/
|
||||
|
81
src/main/java/fr/xephi/authme/cache/CaptchaManager.java
vendored
Normal file
81
src/main/java/fr/xephi/authme/cache/CaptchaManager.java
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
package fr.xephi.authme.cache;
|
||||
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Manager for the handling of captchas.
|
||||
*/
|
||||
public class CaptchaManager {
|
||||
|
||||
private final int threshold;
|
||||
private final int captchaLength;
|
||||
private final ConcurrentHashMap<String, Integer> playerCounts;
|
||||
private final ConcurrentHashMap<String, String> captchaCodes;
|
||||
|
||||
public CaptchaManager(NewSetting settings) {
|
||||
this.playerCounts = new ConcurrentHashMap<>();
|
||||
this.captchaCodes = new ConcurrentHashMap<>();
|
||||
this.threshold = settings.getProperty(SecuritySettings.MAX_LOGIN_TRIES_BEFORE_CAPTCHA);
|
||||
this.captchaLength = settings.getProperty(SecuritySettings.CAPTCHA_LENGTH);
|
||||
}
|
||||
|
||||
public void increaseCount(String player) {
|
||||
String playerLower = player.toLowerCase();
|
||||
Integer currentCount = playerCounts.get(playerLower);
|
||||
if (currentCount == null) {
|
||||
playerCounts.put(playerLower, 1);
|
||||
} else {
|
||||
playerCounts.put(playerLower, currentCount + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given player is required to solve a captcha.
|
||||
*
|
||||
* @param player The player to verify
|
||||
* @return True if the player has to solve a captcha, false otherwise
|
||||
*/
|
||||
public boolean isCaptchaRequired(String player) {
|
||||
Integer count = playerCounts.get(player.toLowerCase());
|
||||
return count != null && count >= threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the captcha code for the player. Creates one if none present, so call only after
|
||||
* checking with {@link #isCaptchaRequired}.
|
||||
*
|
||||
* @param player The player
|
||||
* @return The code required for the player
|
||||
*/
|
||||
public String getCaptchaCode(String player) {
|
||||
String code = captchaCodes.get(player.toLowerCase());
|
||||
if (code == null) {
|
||||
code = RandomString.generate(captchaLength);
|
||||
captchaCodes.put(player.toLowerCase(), code);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the supplied code is correct for the given player.
|
||||
*
|
||||
* @param player The player to check
|
||||
* @param code The supplied code
|
||||
* @return True if the code matches or if no captcha is required for the player, false otherwise
|
||||
*/
|
||||
public boolean checkCode(String player, String code) {
|
||||
String savedCode = captchaCodes.get(player.toLowerCase());
|
||||
if (savedCode == null) {
|
||||
return true;
|
||||
} else if (savedCode.equalsIgnoreCase(code)) {
|
||||
captchaCodes.remove(player.toLowerCase());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
99
src/main/java/fr/xephi/authme/cache/IpAddressManager.java
vendored
Normal file
99
src/main/java/fr/xephi/authme/cache/IpAddressManager.java
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
package fr.xephi.authme.cache;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Resources;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Stateful manager for looking up IP address appropriately, including caching.
|
||||
*/
|
||||
public class IpAddressManager {
|
||||
|
||||
/** Whether or not to use the VeryGames API for IP lookups. */
|
||||
private final boolean useVeryGamesIpCheck;
|
||||
/** Cache for lookups via the VeryGames API. */
|
||||
private final ConcurrentHashMap<String, String> ipCache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param settings The settings instance
|
||||
*/
|
||||
public IpAddressManager(NewSetting settings) {
|
||||
this.useVeryGamesIpCheck = settings.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK);
|
||||
this.ipCache = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the player's IP address. If enabled in the settings, the IP address returned by the
|
||||
* VeryGames API will be returned.
|
||||
*
|
||||
* @param player The player to look up
|
||||
* @return The IP address of the player
|
||||
*/
|
||||
public String getPlayerIp(Player player) {
|
||||
if (useVeryGamesIpCheck) {
|
||||
final String playerName = player.getName().toLowerCase();
|
||||
final String cachedValue = ipCache.get(playerName);
|
||||
if (cachedValue != null) {
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
final String plainIp = player.getAddress().getAddress().getHostAddress();
|
||||
String veryGamesResult = getVeryGamesIp(plainIp, player.getAddress().getPort());
|
||||
if (veryGamesResult != null) {
|
||||
ipCache.put(playerName, veryGamesResult);
|
||||
return veryGamesResult;
|
||||
}
|
||||
}
|
||||
return player.getAddress().getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a player to the IP address cache.
|
||||
*
|
||||
* @param player The player to add or update the cache entry for
|
||||
* @param ip The IP address to add
|
||||
*/
|
||||
public void addCache(String player, String ip) {
|
||||
if (useVeryGamesIpCheck) {
|
||||
ipCache.put(player.toLowerCase(), ip);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a player's cache entry.
|
||||
*
|
||||
* @param player The player to remove
|
||||
*/
|
||||
public void removeCache(String player) {
|
||||
if (useVeryGamesIpCheck) {
|
||||
ipCache.remove(player.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
// returns null if IP could not be looked up
|
||||
private String getVeryGamesIp(final String plainIp, final int port) {
|
||||
final String sUrl = String.format("http://monitor-1.verygames.net/api/?action=ipclean-real-ip"
|
||||
+ "&out=raw&ip=%s&port=%d", plainIp, port);
|
||||
|
||||
try {
|
||||
String result = Resources.toString(new URL(sUrl), Charsets.UTF_8);
|
||||
if (!StringUtils.isEmpty(result) && !result.contains("error")) {
|
||||
return result;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not fetch Very Games API with URL '" + sUrl + "':", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -8,20 +8,24 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
||||
/**
|
||||
* AuthMe player data.
|
||||
*/
|
||||
public class PlayerAuth {
|
||||
|
||||
/** The player's name in lowercase, e.g. "xephi". */
|
||||
private String nickname;
|
||||
/** The player's name in the correct casing, e.g. "Xephi". */
|
||||
private String realName;
|
||||
private HashedPassword password;
|
||||
private String email;
|
||||
private String ip;
|
||||
private int groupId;
|
||||
private long lastLogin;
|
||||
// Fields storing the player's quit location
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private String world;
|
||||
private int groupId;
|
||||
private String email;
|
||||
private String realName;
|
||||
|
||||
/**
|
||||
* @param serialized String
|
||||
@ -31,92 +35,19 @@ public class PlayerAuth {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PlayerAuth.
|
||||
* Constructor. Instantiate objects with the {@link #builder() builder}.
|
||||
*
|
||||
* @param nickname String
|
||||
* @param ip String
|
||||
* @param lastLogin long
|
||||
* @param realName String
|
||||
*/
|
||||
public PlayerAuth(String nickname, String ip, long lastLogin, String realName) {
|
||||
this(nickname, new HashedPassword(""), -1, ip, lastLogin, 0, 0, 0, "world", "your@email.com", realName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PlayerAuth.
|
||||
*
|
||||
* @param nickname String
|
||||
* @param x double
|
||||
* @param y double
|
||||
* @param z double
|
||||
* @param world String
|
||||
* @param realName String
|
||||
*/
|
||||
public PlayerAuth(String nickname, double x, double y, double z, String world, String realName) {
|
||||
this(nickname, new HashedPassword(""), -1, "127.0.0.1", System.currentTimeMillis(), x, y, z, world,
|
||||
"your@email.com", realName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PlayerAuth.
|
||||
*
|
||||
* @param nickname String
|
||||
* @param hash String
|
||||
* @param ip String
|
||||
* @param lastLogin long
|
||||
* @param realName String
|
||||
*/
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin, String realName) {
|
||||
this(nickname, new HashedPassword(hash), -1, ip, lastLogin, 0, 0, 0, "world", "your@email.com", realName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PlayerAuth.
|
||||
*
|
||||
* @param nickname String
|
||||
* @param hash String
|
||||
* @param ip String
|
||||
* @param lastLogin long
|
||||
* @param email String
|
||||
* @param realName String
|
||||
*/
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin, String email, String realName) {
|
||||
this(nickname, new HashedPassword(hash), -1, ip, lastLogin, 0, 0, 0, "world", email, realName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PlayerAuth.
|
||||
*
|
||||
* @param nickname String
|
||||
* @param hash String
|
||||
* @param ip String
|
||||
* @param lastLogin long
|
||||
* @param x double
|
||||
* @param y double
|
||||
* @param z double
|
||||
* @param world String
|
||||
* @param email String
|
||||
* @param realName String
|
||||
*/
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin, double x, double y, double z,
|
||||
String world, String email, String realName) {
|
||||
this(nickname, new HashedPassword(hash), -1, ip, lastLogin, x, y, z, world, email, realName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PlayerAuth.
|
||||
*
|
||||
* @param nickname String
|
||||
* @param password String
|
||||
* @param groupId int
|
||||
* @param ip String
|
||||
* @param lastLogin long
|
||||
* @param x double
|
||||
* @param y double
|
||||
* @param z double
|
||||
* @param world String
|
||||
* @param email String
|
||||
* @param realName String
|
||||
* @param nickname all lowercase name of the player
|
||||
* @param password password
|
||||
* @param groupId the group id
|
||||
* @param ip the associated ip address
|
||||
* @param lastLogin player's last login (timestamp)
|
||||
* @param x quit location: x coordinate
|
||||
* @param y quit location: y coordinate
|
||||
* @param z quit location: z coordinate
|
||||
* @param world quit location: world name
|
||||
* @param email the associated email
|
||||
* @param realName the player's name with proper casing
|
||||
*/
|
||||
private PlayerAuth(String nickname, HashedPassword password, int groupId, String ip, long lastLogin,
|
||||
double x, double y, double z, String world, String email, String realName) {
|
||||
@ -133,24 +64,6 @@ public class PlayerAuth {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method set.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*/
|
||||
public void set(PlayerAuth auth) {
|
||||
this.setEmail(auth.getEmail());
|
||||
this.setPassword(auth.getPassword());
|
||||
this.setIp(auth.getIp());
|
||||
this.setLastLogin(auth.getLastLogin());
|
||||
this.setNickname(auth.getNickname());
|
||||
this.setQuitLocX(auth.getQuitLocX());
|
||||
this.setQuitLocY(auth.getQuitLocY());
|
||||
this.setQuitLocZ(auth.getQuitLocZ());
|
||||
this.setWorld(auth.getWorld());
|
||||
this.setRealName(auth.getRealName());
|
||||
}
|
||||
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname.toLowerCase();
|
||||
|
@ -35,29 +35,6 @@ public class JsonCache {
|
||||
.create();
|
||||
}
|
||||
|
||||
public void createCache(Player player, PlayerData playerData) {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(cacheDir, name + File.separator + "cache.json");
|
||||
if (file.exists()) {
|
||||
return;
|
||||
}
|
||||
if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String data = gson.toJson(playerData);
|
||||
Files.touch(file);
|
||||
Files.write(data, file, Charsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerData readCache(Player player) {
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(cacheDir, name + File.separator + "cache.json");
|
||||
|
@ -16,8 +16,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class LimboCache {
|
||||
|
||||
private volatile static LimboCache singleton;
|
||||
public final ConcurrentHashMap<String, LimboPlayer> cache;
|
||||
public final AuthMe plugin;
|
||||
private final ConcurrentHashMap<String, LimboPlayer> cache;
|
||||
private final AuthMe plugin;
|
||||
private final JsonCache jsonCache;
|
||||
|
||||
/**
|
||||
@ -84,7 +84,7 @@ public class LimboCache {
|
||||
checkNotNull(name);
|
||||
name = name.toLowerCase();
|
||||
if (cache.containsKey(name)) {
|
||||
cache.get(name).clearTask();
|
||||
cache.get(name).clearTasks();
|
||||
cache.remove(name);
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,16 @@ import org.bukkit.Location;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
/**
|
||||
* Represents a player which is not logged in and keeps track of certain states (like OP status, flying)
|
||||
* which may be revoked from the player until he has logged in or registered.
|
||||
*/
|
||||
public class LimboPlayer {
|
||||
|
||||
private final String name;
|
||||
private final boolean fly;
|
||||
private Location loc = null;
|
||||
private BukkitTask timeoutTaskId = null;
|
||||
private BukkitTask messageTaskId = null;
|
||||
private BukkitTask timeoutTask = null;
|
||||
private BukkitTask messageTask = null;
|
||||
private boolean operator = false;
|
||||
private String group;
|
||||
|
||||
@ -25,36 +27,36 @@ public class LimboPlayer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getName.
|
||||
* Return the name of the player.
|
||||
*
|
||||
* @return String
|
||||
* @return The player's name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getLoc.
|
||||
* Return the player's original location.
|
||||
*
|
||||
* @return Location
|
||||
* @return The player's location
|
||||
*/
|
||||
public Location getLoc() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getOperator.
|
||||
* Return whether the player is an operator or not (i.e. whether he is an OP).
|
||||
*
|
||||
* @return boolean
|
||||
* @return True if the player has OP status, false otherwise
|
||||
*/
|
||||
public boolean getOperator() {
|
||||
public boolean isOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getGroup.
|
||||
* Return the player's permissions group.
|
||||
*
|
||||
* @return String
|
||||
* @return The permissions group the player belongs to
|
||||
*/
|
||||
public String getGroup() {
|
||||
return group;
|
||||
@ -64,54 +66,61 @@ public class LimboPlayer {
|
||||
return fly;
|
||||
}
|
||||
|
||||
public BukkitTask getTimeoutTaskId() {
|
||||
return timeoutTaskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setTimeoutTaskId.
|
||||
* Return the timeout task, which kicks the player if he hasn't registered or logged in
|
||||
* after a configurable amount of time.
|
||||
*
|
||||
* @param i BukkitTask
|
||||
* @return The timeout task associated to the player
|
||||
*/
|
||||
public void setTimeoutTaskId(BukkitTask i) {
|
||||
if (this.timeoutTaskId != null) {
|
||||
this.timeoutTaskId.cancel();
|
||||
}
|
||||
this.timeoutTaskId = i;
|
||||
public BukkitTask getTimeoutTask() {
|
||||
return timeoutTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getMessageTaskId.
|
||||
* Set the timeout task of the player. The timeout task kicks the player after a configurable
|
||||
* amount of time if he hasn't logged in or registered.
|
||||
*
|
||||
* @return BukkitTask
|
||||
* @param timeoutTask The task to set
|
||||
*/
|
||||
public BukkitTask getMessageTaskId() {
|
||||
return messageTaskId;
|
||||
public void setTimeoutTask(BukkitTask timeoutTask) {
|
||||
if (this.timeoutTask != null) {
|
||||
this.timeoutTask.cancel();
|
||||
}
|
||||
this.timeoutTask = timeoutTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setMessageTaskId.
|
||||
* Return the message task reminding the player to log in or register.
|
||||
*
|
||||
* @param messageTaskId BukkitTask
|
||||
* @return The task responsible for sending the message regularly
|
||||
*/
|
||||
public void setMessageTaskId(BukkitTask messageTaskId) {
|
||||
if (this.messageTaskId != null) {
|
||||
this.messageTaskId.cancel();
|
||||
}
|
||||
this.messageTaskId = messageTaskId;
|
||||
public BukkitTask getMessageTask() {
|
||||
return messageTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method clearTask.
|
||||
* Set the messages task responsible for telling the player to log in or register.
|
||||
*
|
||||
* @param messageTask The message task to set
|
||||
*/
|
||||
public void clearTask() {
|
||||
if (messageTaskId != null) {
|
||||
messageTaskId.cancel();
|
||||
public void setMessageTask(BukkitTask messageTask) {
|
||||
if (this.messageTask != null) {
|
||||
this.messageTask.cancel();
|
||||
}
|
||||
messageTaskId = null;
|
||||
if (timeoutTaskId != null) {
|
||||
timeoutTaskId.cancel();
|
||||
this.messageTask = messageTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all tasks associated to the player.
|
||||
*/
|
||||
public void clearTasks() {
|
||||
if (messageTask != null) {
|
||||
messageTask.cancel();
|
||||
}
|
||||
timeoutTaskId = null;
|
||||
messageTask = null;
|
||||
if (timeoutTask != null) {
|
||||
timeoutTask.cancel();
|
||||
}
|
||||
timeoutTask = null;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
@ -159,7 +159,7 @@ public final class CommandInitializer {
|
||||
.labels("getip", "ip")
|
||||
.description("Get player's IP")
|
||||
.detailedDescription("Get the IP address of the specified online player.")
|
||||
.withArgument("player", "Player Name", false)
|
||||
.withArgument("player", "Player name", false)
|
||||
.permissions(OP_ONLY, AdminPermission.GET_IP)
|
||||
.executableCommand(new GetIpCommand())
|
||||
.build();
|
||||
@ -170,7 +170,6 @@ public final class CommandInitializer {
|
||||
.labels("spawn", "home")
|
||||
.description("Teleport to spawn")
|
||||
.detailedDescription("Teleport to the spawn.")
|
||||
.withArgument("player", "Player Name", false)
|
||||
.permissions(OP_ONLY, AdminPermission.SPAWN)
|
||||
.executableCommand(new SpawnCommand())
|
||||
.build();
|
||||
|
@ -1,18 +1,22 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import fr.xephi.authme.AntiBot;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -28,6 +32,10 @@ public class CommandService {
|
||||
private final PasswordSecurity passwordSecurity;
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final NewSetting settings;
|
||||
private final IpAddressManager ipAddressManager;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
private final AntiBot antiBot;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -39,10 +47,14 @@ public class CommandService {
|
||||
* @param passwordSecurity The Password Security instance
|
||||
* @param permissionsManager The permissions manager
|
||||
* @param settings The settings manager
|
||||
* @param ipAddressManager The IP address manager
|
||||
* @param pluginHooks The plugin hooks instance
|
||||
* @param spawnLoader The spawn loader
|
||||
*/
|
||||
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages,
|
||||
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager,
|
||||
NewSetting settings) {
|
||||
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings,
|
||||
IpAddressManager ipAddressManager, PluginHooks pluginHooks, SpawnLoader spawnLoader,
|
||||
AntiBot antiBot) {
|
||||
this.authMe = authMe;
|
||||
this.messages = messages;
|
||||
this.helpProvider = helpProvider;
|
||||
@ -50,6 +62,10 @@ public class CommandService {
|
||||
this.passwordSecurity = passwordSecurity;
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.settings = settings;
|
||||
this.ipAddressManager = ipAddressManager;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
this.antiBot = antiBot;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,15 +179,6 @@ public class CommandService {
|
||||
return messages.retrieve(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the messages instance to retrieve messages from the given file.
|
||||
*
|
||||
* @param file The new file to read messages from
|
||||
*/
|
||||
public void reloadMessages(File file) {
|
||||
messages.reload(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given property's value.
|
||||
*
|
||||
@ -192,4 +199,24 @@ public class CommandService {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public IpAddressManager getIpAddressManager() {
|
||||
return ipAddressManager;
|
||||
}
|
||||
|
||||
public PlayerCache getPlayerCache() {
|
||||
return PlayerCache.getInstance();
|
||||
}
|
||||
|
||||
public PluginHooks getPluginHooks() {
|
||||
return pluginHooks;
|
||||
}
|
||||
|
||||
public SpawnLoader getSpawnLoader() {
|
||||
return spawnLoader;
|
||||
}
|
||||
|
||||
public AntiBot getAntiBot() {
|
||||
return antiBot;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ import java.util.List;
|
||||
|
||||
public final class CommandUtils {
|
||||
|
||||
private CommandUtils() {
|
||||
}
|
||||
|
||||
public static int getMinNumberOfArguments(CommandDescription command) {
|
||||
int mandatoryArguments = 0;
|
||||
for (CommandArgumentDescription argument : command.getArguments()) {
|
||||
|
@ -2,7 +2,6 @@ package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
@ -41,6 +40,8 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
|
||||
commandService.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
return;
|
||||
}
|
||||
// TODO #602 20160312: The UNSAFE_PASSWORDS should be all lowercase
|
||||
// -> introduce a lowercase String list property type
|
||||
if (commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(playerPassLowerCase)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
return;
|
||||
@ -53,8 +54,8 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
|
||||
public void run() {
|
||||
DataSource dataSource = commandService.getDataSource();
|
||||
PlayerAuth auth = null;
|
||||
if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) {
|
||||
auth = PlayerCache.getInstance().getAuth(playerNameLowerCase);
|
||||
if (commandService.getPlayerCache().isAuthenticated(playerNameLowerCase)) {
|
||||
auth = commandService.getPlayerCache().getAuth(playerNameLowerCase);
|
||||
} else if (dataSource.isAuthAvailable(playerNameLowerCase)) {
|
||||
auth = dataSource.getAuth(playerNameLowerCase);
|
||||
}
|
||||
|
@ -1,27 +1,22 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Teleports the player to the first spawn.
|
||||
*/
|
||||
public class FirstSpawnCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
// Make sure the command executor is a player
|
||||
try {
|
||||
if (Spawn.getInstance().getFirstSpawn() != null) {
|
||||
player.teleport(Spawn.getInstance().getFirstSpawn());
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// TODO ljacqu 20151119: Catching NullPointerException is never a good idea. Find what can cause one instead
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (commandService.getSpawnLoader().getFirstSpawn() != null) {
|
||||
player.teleport(commandService.getSpawnLoader().getFirstSpawn());
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,16 @@ import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Returns a player's email.
|
||||
*/
|
||||
public class GetEmailCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName.toLowerCase());
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
} else {
|
||||
|
@ -1,21 +1,18 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import java.util.List;
|
||||
|
||||
public class GetIpCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
final AuthMe plugin = AuthMe.getInstance();
|
||||
|
||||
// Get the player query
|
||||
String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
|
||||
|
||||
@ -25,9 +22,12 @@ public class GetIpCommand implements ExecutableCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO ljacqu 20151212: Revise the messages (actual IP vs. real IP...?)
|
||||
sender.sendMessage(player.getName() + "'s actual IP is : " + player.getAddress().getAddress().getHostAddress()
|
||||
sender.sendMessage(player.getName() + "'s IP is: " + player.getAddress().getAddress().getHostAddress()
|
||||
+ ":" + player.getAddress().getPort());
|
||||
sender.sendMessage(player.getName() + "'s real IP is : " + plugin.getIP(player));
|
||||
|
||||
if (commandService.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK)) {
|
||||
sender.sendMessage(player.getName() + "'s real IP is: "
|
||||
+ commandService.getIpAddressManager().getPlayerIp(player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Returns the last login date of the given user.
|
||||
*/
|
||||
public class LastLoginCommand implements ExecutableCommand {
|
||||
|
||||
@ -18,23 +19,24 @@ public class LastLoginCommand implements ExecutableCommand {
|
||||
// Get the player
|
||||
String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
|
||||
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName.toLowerCase());
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.USER_NOT_REGISTERED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the last login date
|
||||
long lastLogin = auth.getLastLogin();
|
||||
final long lastLogin = auth.getLastLogin();
|
||||
final long diff = System.currentTimeMillis() - lastLogin;
|
||||
final String lastLoginMessage = (int) (diff / 86400000) + " days " + (int) (diff / 3600000 % 24) + " hours "
|
||||
+ (int) (diff / 60000 % 60) + " mins " + (int) (diff / 1000 % 60) + " secs";
|
||||
final String lastLoginMessage = (int) (diff / 86400000) + " days "
|
||||
+ (int) (diff / 3600000 % 24) + " hours "
|
||||
+ (int) (diff / 60000 % 60) + " mins "
|
||||
+ (int) (diff / 1000 % 60) + " secs";
|
||||
Date date = new Date(lastLogin);
|
||||
|
||||
// Show the player status
|
||||
sender.sendMessage("[AuthMe] " + playerName + " last login: " + date.toString());
|
||||
sender.sendMessage("[AuthMe] The player " + auth.getNickname() + " last logged in "
|
||||
+ lastLoginMessage + " ago.");
|
||||
sender.sendMessage("[AuthMe] The player " + playerName + " last logged in " + lastLoginMessage + " ago.");
|
||||
sender.sendMessage("[AuthMe] Last Player's IP: " + auth.getIp());
|
||||
}
|
||||
}
|
||||
|
@ -3,19 +3,23 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.PurgeSettings;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Command for purging data of banned players. Depending on the settings
|
||||
* it purges (deletes) data from third-party plugins as well.
|
||||
*/
|
||||
public class PurgeBannedPlayersCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// AuthMe plugin instance
|
||||
final AuthMe plugin = AuthMe.getInstance();
|
||||
final AuthMe plugin = commandService.getAuthMe();
|
||||
|
||||
// Get the list of banned players
|
||||
List<String> bannedPlayers = new ArrayList<>();
|
||||
@ -24,14 +28,15 @@ public class PurgeBannedPlayersCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
// Purge the banned players
|
||||
plugin.getDataSource().purgeBanned(bannedPlayers);
|
||||
if (Settings.purgeEssentialsFile && plugin.ess != null)
|
||||
commandService.getDataSource().purgeBanned(bannedPlayers);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)
|
||||
&& commandService.getPluginHooks().isEssentialsAvailable())
|
||||
plugin.dataManager.purgeEssentials(bannedPlayers);
|
||||
if (Settings.purgePlayerDat)
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
|
||||
plugin.dataManager.purgeDat(bannedPlayers);
|
||||
if (Settings.purgeLimitedCreative)
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
|
||||
plugin.dataManager.purgeLimitedCreative(bannedPlayers);
|
||||
if (Settings.purgeAntiXray)
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
|
||||
plugin.dataManager.purgeAntiXray(bannedPlayers);
|
||||
|
||||
// Show a status message
|
||||
|
@ -3,20 +3,23 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.PurgeSettings;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Command for purging the data of players which have not been since for a given number
|
||||
* of days. Depending on the settings, this removes player data in third-party plugins as well.
|
||||
*/
|
||||
public class PurgeCommand implements ExecutableCommand {
|
||||
|
||||
private static final int MINIMUM_LAST_SEEN_DAYS = 30;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// AuthMe plugin instance
|
||||
AuthMe plugin = AuthMe.getInstance();
|
||||
|
||||
// Get the days parameter
|
||||
String daysStr = arguments.get(0);
|
||||
|
||||
@ -30,8 +33,9 @@ public class PurgeCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
// Validate the value
|
||||
if (days < 30) {
|
||||
sender.sendMessage(ChatColor.RED + "You can only purge data older than 30 days");
|
||||
if (days < MINIMUM_LAST_SEEN_DAYS) {
|
||||
sender.sendMessage(ChatColor.RED + "You can only purge data older than "
|
||||
+ MINIMUM_LAST_SEEN_DAYS + " days");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -47,13 +51,15 @@ public class PurgeCommand implements ExecutableCommand {
|
||||
sender.sendMessage(ChatColor.GOLD + "Deleted " + purged.size() + " user accounts");
|
||||
|
||||
// Purge other data
|
||||
if (Settings.purgeEssentialsFile && plugin.ess != null)
|
||||
AuthMe plugin = commandService.getAuthMe();
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES) &&
|
||||
commandService.getPluginHooks().isEssentialsAvailable())
|
||||
plugin.dataManager.purgeEssentials(purged);
|
||||
if (Settings.purgePlayerDat)
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
|
||||
plugin.dataManager.purgeDat(purged);
|
||||
if (Settings.purgeLimitedCreative)
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
|
||||
plugin.dataManager.purgeLimitedCreative(purged);
|
||||
if (Settings.purgeAntiXray)
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
|
||||
plugin.dataManager.purgeAntiXray(purged);
|
||||
|
||||
// Show a status message
|
||||
|
@ -8,45 +8,39 @@ import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Removes the stored last position of a user or of all.
|
||||
*/
|
||||
public class PurgeLastPositionCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
String playerNameLowerCase = playerName.toLowerCase();
|
||||
|
||||
if (playerNameLowerCase.equalsIgnoreCase("*"))
|
||||
{
|
||||
for (PlayerAuth auth : commandService.getDataSource().getAllAuths())
|
||||
{
|
||||
// Set the last position
|
||||
auth.setQuitLocX(0D);
|
||||
auth.setQuitLocY(0D);
|
||||
auth.setQuitLocZ(0D);
|
||||
auth.setWorld("world");
|
||||
if ("*".equals(playerName)) {
|
||||
for (PlayerAuth auth : commandService.getDataSource().getAllAuths()) {
|
||||
resetLastPosition(auth);
|
||||
commandService.getDataSource().updateQuitLoc(auth);
|
||||
}
|
||||
sender.sendMessage("All players last position locations are now reset");
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
sender.sendMessage("All players last position locations are now reset");
|
||||
} else {
|
||||
// Get the user auth and make sure the user exists
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerNameLowerCase);
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the last position
|
||||
auth.setQuitLocX(0D);
|
||||
auth.setQuitLocY(0D);
|
||||
auth.setQuitLocZ(0D);
|
||||
auth.setWorld("world");
|
||||
resetLastPosition(auth);
|
||||
commandService.getDataSource().updateQuitLoc(auth);
|
||||
|
||||
// Show a status message
|
||||
sender.sendMessage(playerNameLowerCase + "'s last position location is now reset");
|
||||
sender.sendMessage(playerName + "'s last position location is now reset");
|
||||
}
|
||||
}
|
||||
|
||||
private static void resetLastPosition(PlayerAuth auth) {
|
||||
auth.setQuitLocX(0d);
|
||||
auth.setQuitLocY(0d);
|
||||
auth.setQuitLocZ(0d);
|
||||
auth.setWorld("world");
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -5,7 +5,6 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
@ -19,13 +18,7 @@ public class ReloadCommand implements ExecutableCommand {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
AuthMe plugin = commandService.getAuthMe();
|
||||
try {
|
||||
commandService.getSettings().reload();
|
||||
commandService.reloadMessages(commandService.getSettings().getMessagesFile());
|
||||
Spawn.reload();
|
||||
// TODO #432: We should not reload only certain plugin entities but actually reinitialize all elements,
|
||||
// i.e. here in the future we might not have setupDatabase() but Authme.onEnable(), maybe after
|
||||
// a call to some destructor method
|
||||
plugin.setupDatabase(commandService.getSettings());
|
||||
plugin.reload();
|
||||
commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage("Error occurred during reload of AuthMe: aborting");
|
||||
|
@ -1,9 +1,7 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@ -12,14 +10,10 @@ public class SetFirstSpawnCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
try {
|
||||
if (Spawn.getInstance().setFirstSpawn(player.getLocation())) {
|
||||
player.sendMessage("[AuthMe] Correctly defined new first spawn point");
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] SetFirstSpawn has failed, please retry");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (commandService.getSpawnLoader().setFirstSpawn(player.getLocation())) {
|
||||
player.sendMessage("[AuthMe] Correctly defined new first spawn point");
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] SetFirstSpawn has failed, please retry");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@ -12,14 +10,10 @@ public class SetSpawnCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
try {
|
||||
if (Spawn.getInstance().setSpawn(player.getLocation())) {
|
||||
player.sendMessage("[AuthMe] Correctly defined new spawn point");
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] SetSpawn has failed, please retry");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (commandService.getSpawnLoader().setSpawn(player.getLocation())) {
|
||||
player.sendMessage("[AuthMe] Correctly defined new spawn point");
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] SetSpawn has failed, please retry");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@ -12,14 +10,10 @@ public class SpawnCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
try {
|
||||
if (Spawn.getInstance().getSpawn() != null) {
|
||||
player.teleport(Spawn.getInstance().getSpawn());
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (commandService.getSpawnLoader().getSpawn() != null) {
|
||||
player.teleport(commandService.getSpawnLoader().getSpawn());
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ public class SwitchAntiBotCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
AntiBot antiBot = commandService.getAntiBot();
|
||||
if (arguments.isEmpty()) {
|
||||
sender.sendMessage("[AuthMe] AntiBot status: " + AntiBot.getAntiBotStatus().name());
|
||||
sender.sendMessage("[AuthMe] AntiBot status: " + antiBot.getAntiBotStatus().name());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -27,10 +28,10 @@ public class SwitchAntiBotCommand implements ExecutableCommand {
|
||||
|
||||
// Enable or disable the mod
|
||||
if ("ON".equalsIgnoreCase(newState)) {
|
||||
AntiBot.overrideAntiBotStatus(true);
|
||||
antiBot.overrideAntiBotStatus(true);
|
||||
sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!");
|
||||
} else if ("OFF".equalsIgnoreCase(newState)) {
|
||||
AntiBot.overrideAntiBotStatus(false);
|
||||
antiBot.overrideAntiBotStatus(false);
|
||||
sender.sendMessage("[AuthMe] AntiBot Manual Override: disabled!");
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Invalid AntiBot mode!");
|
||||
|
@ -8,6 +8,7 @@ import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
@ -59,14 +60,14 @@ public class UnregisterAdminCommand implements ExecutableCommand {
|
||||
BukkitScheduler scheduler = sender.getServer().getScheduler();
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, playerNameLowerCase, target), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTaskId(id);
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTask(id);
|
||||
}
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTaskId(
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTask(
|
||||
scheduler.runTask(
|
||||
plugin, new MessageTask(plugin, playerNameLowerCase, MessageKey.REGISTER_MESSAGE, interval)
|
||||
)
|
||||
);
|
||||
if (Settings.applyBlindEffect) {
|
||||
if (commandService.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
}
|
||||
commandService.send(target, MessageKey.UNREGISTERED_SUCCESS);
|
||||
|
@ -3,7 +3,7 @@ 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 fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -71,9 +71,7 @@ public class VersionCommand implements ExecutableCommand {
|
||||
* @return True if the player is online, false otherwise.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@ -18,9 +17,8 @@ public class CaptchaCommand extends PlayerCommand {
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
final String playerNameLowerCase = player.getName().toLowerCase();
|
||||
final String captcha = arguments.get(0);
|
||||
Wrapper wrapper = Wrapper.getInstance();
|
||||
final AuthMe plugin = wrapper.getAuthMe();
|
||||
PlayerCache playerCache = wrapper.getPlayerCache();
|
||||
final AuthMe plugin = commandService.getAuthMe();
|
||||
PlayerCache playerCache = PlayerCache.getInstance();
|
||||
|
||||
// Command logic
|
||||
if (playerCache.isAuthenticated(playerNameLowerCase)) {
|
||||
|
@ -8,7 +8,6 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.ChangePasswordTask;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@ -24,8 +23,7 @@ public class ChangePasswordCommand extends PlayerCommand {
|
||||
String newPassword = arguments.get(1);
|
||||
|
||||
String name = player.getName().toLowerCase();
|
||||
Wrapper wrapper = Wrapper.getInstance();
|
||||
final PlayerCache playerCache = wrapper.getPlayerCache();
|
||||
final PlayerCache playerCache = commandService.getPlayerCache();
|
||||
if (!playerCache.isAuthenticated(name)) {
|
||||
commandService.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
return;
|
||||
|
@ -7,6 +7,7 @@ import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
@ -17,7 +18,7 @@ public class RegisterCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (Settings.getPasswordHash == HashAlgorithm.TWO_FACTOR) {
|
||||
if (commandService.getProperty(SecuritySettings.PASSWORD_HASH) == HashAlgorithm.TWO_FACTOR) {
|
||||
//for two factor auth we don't need to check the usage
|
||||
commandService.getManagement().performRegister(player, "", "");
|
||||
return;
|
||||
|
@ -31,27 +31,13 @@ public class CrazyLoginConverter implements Converter {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getInstance.
|
||||
*
|
||||
* @return CrazyLoginConverter
|
||||
*/
|
||||
public CrazyLoginConverter getInstance() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
String fileName = Settings.crazyloginFileName;
|
||||
try {
|
||||
File source = new File(AuthMe.getInstance().getDataFolder() + File.separator + fileName);
|
||||
if (!source.exists()) {
|
||||
sender.sendMessage("Error while trying to import datas, please put " + fileName + " in AuthMe folder!");
|
||||
sender.sendMessage("Error while trying to import data, please put " + fileName + " in AuthMe folder!");
|
||||
return;
|
||||
}
|
||||
String line;
|
||||
@ -59,14 +45,17 @@ public class CrazyLoginConverter implements Converter {
|
||||
while ((line = users.readLine()) != null) {
|
||||
if (line.contains("|")) {
|
||||
String[] args = line.split("\\|");
|
||||
if (args.length < 2)
|
||||
if (args.length < 2 || "name".equalsIgnoreCase(args[0])) {
|
||||
continue;
|
||||
if (args[0].equalsIgnoreCase("name"))
|
||||
continue;
|
||||
String playerName = args[0].toLowerCase();
|
||||
}
|
||||
String playerName = args[0];
|
||||
String psw = args[1];
|
||||
if (psw != null) {
|
||||
PlayerAuth auth = new PlayerAuth(playerName, psw, "127.0.0.1", System.currentTimeMillis(), playerName);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(playerName.toLowerCase())
|
||||
.realName(playerName)
|
||||
.password(psw, null)
|
||||
.build();
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ import java.util.Map.Entry;
|
||||
*/
|
||||
public class RakamakConverter implements Converter {
|
||||
|
||||
public final AuthMe instance;
|
||||
public final DataSource database;
|
||||
public final CommandSender sender;
|
||||
private final AuthMe instance;
|
||||
private final DataSource database;
|
||||
private final CommandSender sender;
|
||||
|
||||
public RakamakConverter(AuthMe instance, CommandSender sender) {
|
||||
this.instance = instance;
|
||||
|
@ -5,35 +5,46 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
|
||||
public class RoyalAuthConverter implements Converter {
|
||||
|
||||
private static final String LAST_LOGIN_PATH = "timestamps.quit";
|
||||
private static final String PASSWORD_PATH = "login.password";
|
||||
private final AuthMe plugin;
|
||||
private final DataSource data;
|
||||
private final DataSource dataSource;
|
||||
|
||||
public RoyalAuthConverter(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.data = plugin.getDataSource();
|
||||
this.dataSource = plugin.getDataSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (OfflinePlayer o : plugin.getServer().getOfflinePlayers()) {
|
||||
for (OfflinePlayer player : plugin.getServer().getOfflinePlayers()) {
|
||||
try {
|
||||
String name = o.getName().toLowerCase();
|
||||
String sp = File.separator;
|
||||
File file = new File("." + sp + "plugins" + sp + "RoyalAuth" + sp + "userdata" + sp + name + ".yml");
|
||||
if (data.isAuthAvailable(name))
|
||||
String name = player.getName().toLowerCase();
|
||||
File file = new File(makePath(".", "plugins", "RoyalAuth", "userdata", name + ".yml"));
|
||||
|
||||
if (dataSource.isAuthAvailable(name) || !file.exists()) {
|
||||
continue;
|
||||
if (!file.exists())
|
||||
continue;
|
||||
RoyalAuthYamlReader ra = new RoyalAuthYamlReader(file);
|
||||
PlayerAuth auth = new PlayerAuth(name, ra.getHash(), "127.0.0.1", ra.getLastLogin(), "your@email.com", o.getName());
|
||||
data.saveAuth(auth);
|
||||
}
|
||||
FileConfiguration configuration = YamlConfiguration.loadConfiguration(file);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.password(configuration.getString(PASSWORD_PATH), null)
|
||||
.lastLogin(configuration.getLong(LAST_LOGIN_PATH))
|
||||
.realName(player.getName())
|
||||
.build();
|
||||
|
||||
dataSource.saveAuth(auth);
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.logException("Error while trying to import " + o.getName() + " RoyalAuth data", e);
|
||||
ConsoleLogger.logException("Error while trying to import " + player.getName() + " RoyalAuth data", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.settings.CustomConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
class RoyalAuthYamlReader extends CustomConfiguration {
|
||||
|
||||
public RoyalAuthYamlReader(File file) {
|
||||
super(file);
|
||||
load();
|
||||
save();
|
||||
}
|
||||
|
||||
public long getLastLogin() {
|
||||
return getLong("timestamps.quit");
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return getString("login.password");
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
|
||||
class vAuthFileReader {
|
||||
|
||||
private final AuthMe plugin;
|
||||
@ -28,7 +30,7 @@ class vAuthFileReader {
|
||||
}
|
||||
|
||||
public void convert() {
|
||||
final File file = new File(plugin.getDataFolder().getParent() + File.separator + "vAuth" + File.separator + "passwords.yml");
|
||||
final File file = new File(plugin.getDataFolder().getParent(), makePath("vAuth", "passwords.yml"));
|
||||
Scanner scanner;
|
||||
try {
|
||||
scanner = new Scanner(file);
|
||||
@ -46,9 +48,15 @@ class vAuthFileReader {
|
||||
}
|
||||
if (pname == null)
|
||||
continue;
|
||||
auth = new PlayerAuth(pname.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", pname);
|
||||
auth = PlayerAuth.builder()
|
||||
.name(pname.toLowerCase())
|
||||
.realName(pname)
|
||||
.password(password, null).build();
|
||||
} else {
|
||||
auth = new PlayerAuth(name.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", name);
|
||||
auth = PlayerAuth.builder()
|
||||
.name(name.toLowerCase())
|
||||
.realName(name)
|
||||
.password(password, null).build();
|
||||
}
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
|
@ -50,7 +50,10 @@ class xAuthToFlat {
|
||||
String pl = getIdPlayer(id);
|
||||
String psw = getPassword(id);
|
||||
if (psw != null && !psw.isEmpty() && pl != null) {
|
||||
PlayerAuth auth = new PlayerAuth(pl, psw, "192.168.0.1", 0, "your@email.com", pl);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(pl.toLowerCase())
|
||||
.realName(pl)
|
||||
.password(psw, null).build();
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
}
|
||||
@ -69,7 +72,8 @@ class xAuthToFlat {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `playername` FROM `%s` WHERE `id` = ?", xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
String sql = String.format("SELECT `playername` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, id);
|
||||
rs = ps.executeQuery();
|
||||
@ -91,7 +95,8 @@ class xAuthToFlat {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT * FROM `%s`", xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
String sql = String.format("SELECT * FROM `%s`",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
@ -112,7 +117,8 @@ class xAuthToFlat {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `password`, `pwtype` FROM `%s` WHERE `id` = ?", xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
String sql = String.format("SELECT `password`, `pwtype` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, accountId);
|
||||
rs = ps.executeQuery();
|
||||
|
@ -64,6 +64,11 @@ public class CacheDataSource implements DataSource {
|
||||
return cachedAuths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
source.reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
return getAuth(user) != null;
|
||||
@ -162,12 +167,6 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() { // unused method
|
||||
source.reload();
|
||||
cachedAuths.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateEmail(final PlayerAuth auth) {
|
||||
boolean result = source.updateEmail(auth);
|
||||
|
@ -121,8 +121,6 @@ public interface DataSource {
|
||||
*/
|
||||
void close();
|
||||
|
||||
void reload();
|
||||
|
||||
/**
|
||||
* Method purgeBanned.
|
||||
*
|
||||
@ -189,4 +187,9 @@ public interface DataSource {
|
||||
|
||||
boolean isEmailStored(String email);
|
||||
|
||||
/**
|
||||
* Reload the data source.
|
||||
*/
|
||||
void reload();
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
@ -9,6 +10,7 @@ import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
@ -18,6 +20,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Deprecated flat file datasource. The only method guaranteed to work is {@link FlatFile#getAllAuths()}
|
||||
* as to migrate the entries to {@link SQLite} when AuthMe starts.
|
||||
*/
|
||||
@Deprecated
|
||||
public class FlatFile implements DataSource {
|
||||
@ -42,7 +46,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 +54,19 @@ 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 void reload() {
|
||||
throw new UnsupportedOperationException("Flatfile no longer supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
BufferedReader br = null;
|
||||
@ -66,19 +79,11 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -100,17 +105,12 @@ public class FlatFile implements DataSource {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(source, true));
|
||||
bw.write(auth.getNickname() + ":" + auth.getPassword() + ":" + auth.getIp() + ":" + auth.getLastLogin() + ":" + auth.getQuitLocX() + ":" + auth.getQuitLocY() + ":" + auth.getQuitLocZ() + ":" + auth.getWorld() + ":" + auth.getEmail() + "\n");
|
||||
bw.write(auth.getNickname() + ":" + auth.getPassword().getHash() + ":" + auth.getIp() + ":" + auth.getLastLogin() + ":" + auth.getQuitLocX() + ":" + auth.getQuitLocY() + ":" + auth.getQuitLocZ() + ":" + auth.getWorld() + ":" + auth.getEmail() + "\n");
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(bw);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -121,6 +121,7 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
// Note ljacqu 20151230: This does not persist the salt; it is not supported in flat file.
|
||||
public boolean updatePassword(String user, HashedPassword password) {
|
||||
user = user.toLowerCase();
|
||||
if (!isAuthAvailable(user)) {
|
||||
@ -134,45 +135,18 @@ public class FlatFile implements DataSource {
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(user)) {
|
||||
// Note ljacqu 20151230: This does not persist the salt; it is not supported in flat file.
|
||||
switch (args.length) {
|
||||
case 4: {
|
||||
newAuth = new PlayerAuth(args[0], password.getHash(), args[2], Long.parseLong(args[3]), 0, 0, 0, "world", "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
newAuth = new PlayerAuth(args[0], password.getHash(), args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), "world", "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
newAuth = new PlayerAuth(args[0], password.getHash(), 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: {
|
||||
newAuth = new PlayerAuth(args[0], password.getHash(), 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;
|
||||
}
|
||||
default: {
|
||||
newAuth = new PlayerAuth(args[0], password.getHash(), args[2], 0, 0, 0, 0, "world", "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
newAuth = buildAuthFromArray(args);
|
||||
if (newAuth != null) {
|
||||
newAuth.setPassword(password);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
if (newAuth != null) {
|
||||
removeAuth(user);
|
||||
@ -194,44 +168,19 @@ public class FlatFile implements DataSource {
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equalsIgnoreCase(auth.getNickname())) {
|
||||
switch (args.length) {
|
||||
case 4: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), 0, 0, 0, "world", "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), "world", "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), args[7], "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
case 9: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), args[7], args[8], args[0]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), 0, 0, 0, "world", "your@email.com", args[0]);
|
||||
break;
|
||||
}
|
||||
newAuth = buildAuthFromArray(args);
|
||||
if (newAuth != null) {
|
||||
newAuth.setLastLogin(auth.getLastLogin());
|
||||
newAuth.setIp(auth.getIp());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
if (newAuth != null) {
|
||||
removeAuth(auth.getNickname());
|
||||
@ -253,23 +202,22 @@ public class FlatFile implements DataSource {
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equalsIgnoreCase(auth.getNickname())) {
|
||||
newAuth = new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ(), auth.getWorld(), auth.getEmail(), args[0]);
|
||||
newAuth = buildAuthFromArray(args);
|
||||
if (newAuth != null) {
|
||||
newAuth.setQuitLocX(auth.getQuitLocX());
|
||||
newAuth.setQuitLocY(auth.getQuitLocY());
|
||||
newAuth.setQuitLocZ(auth.getQuitLocZ());
|
||||
newAuth.setWorld(auth.getWorld());
|
||||
newAuth.setEmail(auth.getEmail());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
if (newAuth != null) {
|
||||
removeAuth(auth.getNickname());
|
||||
@ -301,25 +249,12 @@ public class FlatFile implements DataSource {
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
silentClose(bw);
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
@ -345,25 +280,12 @@ public class FlatFile implements DataSource {
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
silentClose(bw);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -377,35 +299,14 @@ public class FlatFile implements DataSource {
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equalsIgnoreCase(user)) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
return new PlayerAuth(args[0], args[1], "192.168.0.1", 0, "your@email.com", args[0]);
|
||||
case 3:
|
||||
return new PlayerAuth(args[0], args[1], args[2], 0, "your@email.com", args[0]);
|
||||
case 4:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), "your@email.com", args[0]);
|
||||
case 7:
|
||||
return 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]);
|
||||
case 8:
|
||||
return 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]);
|
||||
case 9:
|
||||
return 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]);
|
||||
}
|
||||
return buildAuthFromArray(args);
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -414,10 +315,6 @@ public class FlatFile implements DataSource {
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateEmail(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
@ -431,7 +328,10 @@ public class FlatFile implements DataSource {
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
newAuth = 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], auth.getEmail(), args[0]);
|
||||
newAuth = buildAuthFromArray(args);
|
||||
if (newAuth != null) {
|
||||
newAuth.setEmail(auth.getEmail());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -539,18 +439,8 @@ public class FlatFile implements DataSource {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
silentClose(bw);
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,19 +479,14 @@ public class FlatFile implements DataSource {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return result;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateRealName(String user, String realName) {
|
||||
return false;
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -618,51 +503,56 @@ 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;
|
||||
PlayerAuth auth = buildAuthFromArray(args);
|
||||
if (auth != null) {
|
||||
auths.add(auth);
|
||||
}
|
||||
}
|
||||
} 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 {
|
||||
br.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
silentClose(br);
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
return new ArrayList<>();
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmailStored(String email) {
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
|
||||
private static PlayerAuth buildAuthFromArray(String[] args) {
|
||||
// Format allows 2, 3, 4, 7, 8, 9 fields. Anything else is unknown
|
||||
if (args.length >= 2 && args.length <= 9 && args.length != 5 && args.length != 6) {
|
||||
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]);
|
||||
return builder.build();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void silentClose(Closeable closeable) {
|
||||
if (closeable != null) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (IOException ignored) {
|
||||
// silent close
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,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;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
@ -42,6 +41,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);
|
||||
@ -52,6 +55,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 {
|
||||
@ -93,6 +99,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;
|
||||
}
|
||||
|
||||
@ -122,7 +131,8 @@ public class MySQL implements DataSource {
|
||||
ConsoleLogger.info("Connection arguments loaded, Hikari ConnectionPool ready!");
|
||||
}
|
||||
|
||||
private synchronized void reloadArguments() throws RuntimeException {
|
||||
@Override
|
||||
public synchronized void reload() throws RuntimeException {
|
||||
if (ds != null) {
|
||||
ds.close();
|
||||
}
|
||||
@ -361,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);
|
||||
@ -382,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();
|
||||
@ -405,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();
|
||||
@ -419,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);
|
||||
@ -622,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;
|
||||
}
|
||||
@ -684,17 +695,6 @@ public class MySQL implements DataSource {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
try {
|
||||
reloadArguments();
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.logException("Can't reconnect to MySQL database... " +
|
||||
"Please check your MySQL configuration! Encountered", ex);
|
||||
AuthMe.getInstance().stopOrUnload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
if (ds != null && !ds.isClosed()) {
|
||||
@ -881,22 +881,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);
|
||||
}
|
||||
@ -980,12 +982,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,10 @@ 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);
|
||||
@ -55,6 +57,10 @@ public class SQLite implements DataSource {
|
||||
this.con = connection;
|
||||
}
|
||||
|
||||
private static void logSqlException(SQLException e) {
|
||||
ConsoleLogger.logException("Error while executing SQL statement:", e);
|
||||
}
|
||||
|
||||
private synchronized void connect() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
ConsoleLogger.info("SQLite driver loaded");
|
||||
@ -123,6 +129,11 @@ public class SQLite implements DataSource {
|
||||
ConsoleLogger.info("SQLite Setup finished");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
// TODO 20160309: Implement reloading
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
PreparedStatement pst = null;
|
||||
@ -277,24 +288,23 @@ public class SQLite implements DataSource {
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> list = new ArrayList<>();
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;");
|
||||
pst.setLong(1, until);
|
||||
rs = pst.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(rs.getString(col.NAME));
|
||||
String select = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
|
||||
String delete = "DELETE FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
|
||||
try (PreparedStatement selectPst = con.prepareStatement(select);
|
||||
PreparedStatement deletePst = con.prepareStatement(delete)) {
|
||||
selectPst.setLong(1, until);
|
||||
try (ResultSet rs = selectPst.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
list.add(rs.getString(col.NAME));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
deletePst.setLong(1, until);
|
||||
deletePst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -350,17 +360,14 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
private void close(Statement st) {
|
||||
if (st != null) {
|
||||
try {
|
||||
@ -421,17 +428,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,18 +511,13 @@ 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;
|
||||
}
|
||||
@ -526,7 +525,7 @@ public class SQLite implements DataSource {
|
||||
@Override
|
||||
public boolean updateRealName(String user, String realName) {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
|
||||
try(PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, realName);
|
||||
pst.setString(2, user);
|
||||
pst.executeUpdate();
|
||||
@ -540,7 +539,7 @@ public class SQLite implements DataSource {
|
||||
@Override
|
||||
public boolean updateIp(String user, String ip) {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.IP + "=? WHERE " + col.NAME + "=?;";
|
||||
try(PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, ip);
|
||||
pst.setString(2, user);
|
||||
pst.executeUpdate();
|
||||
@ -554,19 +553,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;
|
||||
}
|
||||
@ -574,19 +568,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;
|
||||
}
|
||||
@ -607,10 +596,6 @@ public class SQLite implements DataSource {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void logSqlException(SQLException e) {
|
||||
ConsoleLogger.logException("Error while executing SQL statement:", e);
|
||||
}
|
||||
|
||||
private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException {
|
||||
String salt = !col.SALT.isEmpty() ? row.getString(col.SALT) : null;
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -7,6 +7,7 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
@ -15,30 +16,33 @@ import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
*/
|
||||
public class BungeeCordMessage implements PluginMessageListener {
|
||||
|
||||
public final AuthMe plugin;
|
||||
private final AuthMe plugin;
|
||||
private final IpAddressManager ipAddressManager;
|
||||
|
||||
/**
|
||||
* Constructor for BungeeCordMessage.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
* @param plugin The plugin instance
|
||||
* @param ipAddressManager The IP address manager
|
||||
*/
|
||||
public BungeeCordMessage(AuthMe plugin) {
|
||||
public BungeeCordMessage(AuthMe plugin, IpAddressManager ipAddressManager) {
|
||||
this.plugin = plugin;
|
||||
this.ipAddressManager = ipAddressManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
|
||||
if (!channel.equals("BungeeCord")) {
|
||||
if (!"BungeeCord".equals(channel)) {
|
||||
return;
|
||||
}
|
||||
ByteArrayDataInput in = ByteStreams.newDataInput(message);
|
||||
String subChannel = in.readUTF();
|
||||
if (subChannel.equals("IP")) { // We need only the IP channel
|
||||
if ("IP".equals(subChannel)) { // We need only the IP channel
|
||||
String ip = in.readUTF();
|
||||
// Put the IP (only the ip not the port) in the hashMap
|
||||
plugin.realIp.put(player.getName().toLowerCase(), ip);
|
||||
ipAddressManager.addCache(player.getName(), ip);
|
||||
}
|
||||
if (subChannel.equalsIgnoreCase("AuthMe")) {
|
||||
if ("AuthMe".equalsIgnoreCase(subChannel)) {
|
||||
String str = in.readUTF();
|
||||
final String[] args = str.split(";");
|
||||
final String act = args[0];
|
||||
@ -65,10 +69,10 @@ public class BungeeCordMessage implements PluginMessageListener {
|
||||
ConsoleLogger.info("Player " + auth.getNickname()
|
||||
+ " has registered out from one of your server!");
|
||||
} else if ("changepassword".equals(act)) {
|
||||
final String password = args[2];
|
||||
final String password = args[2];
|
||||
final String salt = args.length >= 4 ? args[3] : null;
|
||||
auth.setPassword(new HashedPassword(password, salt));
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
auth.setPassword(new HashedPassword(password, salt));
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
dataSource.updatePassword(auth);
|
||||
}
|
||||
|
||||
|
@ -1,51 +0,0 @@
|
||||
package fr.xephi.authme.hooks;
|
||||
|
||||
import fr.xephi.authme.settings.CustomConfiguration;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class EssSpawn extends CustomConfiguration {
|
||||
|
||||
private static EssSpawn spawn;
|
||||
|
||||
public EssSpawn() {
|
||||
super(new File("." + File.separator + "plugins" + File.separator + "Essentials" + File.separator + "spawn.yml"));
|
||||
spawn = this;
|
||||
load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getInstance.
|
||||
*
|
||||
* @return EssSpawn
|
||||
*/
|
||||
public static EssSpawn getInstance() {
|
||||
if (spawn == null) {
|
||||
spawn = new EssSpawn();
|
||||
}
|
||||
return spawn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getLocation.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
try {
|
||||
if (!this.contains("spawns.default.world"))
|
||||
return null;
|
||||
if (this.getString("spawns.default.world").isEmpty() || this.getString("spawns.default.world").equals(""))
|
||||
return null;
|
||||
Location location = new Location(Bukkit.getWorld(this.getString("spawns.default.world")), this.getDouble("spawns.default.x"), this.getDouble("spawns.default.y"), this.getDouble("spawns.default.z"), Float.parseFloat(this.getString("spawns.default.yaw")), Float.parseFloat(this.getString("spawns.default.pitch")));
|
||||
return location;
|
||||
} catch (NullPointerException | NumberFormatException npe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
158
src/main/java/fr/xephi/authme/hooks/PluginHooks.java
Normal file
158
src/main/java/fr/xephi/authme/hooks/PluginHooks.java
Normal file
@ -0,0 +1,158 @@
|
||||
package fr.xephi.authme.hooks;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import net.minelink.ctplus.CombatTagPlus;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Hooks into third-party plugins and allows to perform actions on them.
|
||||
*/
|
||||
public class PluginHooks {
|
||||
|
||||
private final PluginManager pluginManager;
|
||||
private Essentials essentials;
|
||||
private MultiverseCore multiverse;
|
||||
private CombatTagPlus combatTagPlus;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pluginManager The server's plugin manager
|
||||
*/
|
||||
public PluginHooks(PluginManager pluginManager) {
|
||||
this.pluginManager = pluginManager;
|
||||
tryHookToCombatPlus();
|
||||
tryHookToEssentials();
|
||||
tryHookToMultiverse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the social spy status of the given user if Essentials is available.
|
||||
*
|
||||
* @param player The player to modify
|
||||
* @param socialSpyStatus The social spy status (enabled/disabled) to set
|
||||
*/
|
||||
public void setEssentialsSocialSpyStatus(Player player, boolean socialSpyStatus) {
|
||||
if (essentials != null) {
|
||||
essentials.getUser(player).setSocialSpyEnabled(socialSpyStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If Essentials is hooked into, return Essentials' data folder.
|
||||
*
|
||||
* @return The Essentials data folder, or null if unavailable
|
||||
*/
|
||||
public File getEssentialsDataFolder() {
|
||||
if (essentials != null) {
|
||||
return essentials.getDataFolder();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the spawn of the given world as defined by Multiverse (if available).
|
||||
*
|
||||
* @param world The world to get the Multiverse spawn for
|
||||
* @return The spawn location from Multiverse, or null if unavailable
|
||||
*/
|
||||
public Location getMultiverseSpawn(World world) {
|
||||
if (multiverse != null) {
|
||||
MVWorldManager manager = multiverse.getMVWorldManager();
|
||||
if (manager.isMVWorld(world)) {
|
||||
return manager.getMVWorld(world).getSpawnLocation();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the CombatTagPlus plugin whether the given player is an NPC.
|
||||
*
|
||||
* @param player The player to verify
|
||||
* @return True if the player is an NPC according to CombatTagPlus, false if not or if the plugin is unavailable
|
||||
*/
|
||||
public boolean isNpcInCombatTagPlus(Player player) {
|
||||
return combatTagPlus != null && combatTagPlus.getNpcPlayerHelper().isNpc(player);
|
||||
}
|
||||
|
||||
|
||||
// ------
|
||||
// "Is plugin available" methods
|
||||
// ------
|
||||
public boolean isEssentialsAvailable() {
|
||||
return essentials != null;
|
||||
}
|
||||
|
||||
public boolean isMultiverseAvailable() {
|
||||
return multiverse != null;
|
||||
}
|
||||
|
||||
public boolean isCombatTagPlusAvailable() {
|
||||
return combatTagPlus != null;
|
||||
}
|
||||
|
||||
// ------
|
||||
// Hook methods
|
||||
// ------
|
||||
public void tryHookToEssentials() {
|
||||
try {
|
||||
essentials = getPlugin(pluginManager, "Essentials", Essentials.class);
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
essentials = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void tryHookToCombatPlus() {
|
||||
try {
|
||||
combatTagPlus = getPlugin(pluginManager, "CombatTagPlus", CombatTagPlus.class);
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
combatTagPlus = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void tryHookToMultiverse() {
|
||||
try {
|
||||
multiverse = getPlugin(pluginManager, "Multiverse-Core", MultiverseCore.class);
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
multiverse = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ------
|
||||
// Unhook methods
|
||||
// ------
|
||||
public void unhookEssentials() {
|
||||
essentials = null;
|
||||
}
|
||||
public void unhookCombatPlus() {
|
||||
combatTagPlus = null;
|
||||
}
|
||||
public void unhookMultiverse() {
|
||||
multiverse = null;
|
||||
}
|
||||
|
||||
// ------
|
||||
// Helpers
|
||||
// ------
|
||||
private static <T extends Plugin> T getPlugin(PluginManager pluginManager, String name, Class<T> clazz)
|
||||
throws Exception, NoClassDefFoundError {
|
||||
if (pluginManager.isPluginEnabled(name)) {
|
||||
T plugin = clazz.cast(pluginManager.getPlugin(name));
|
||||
ConsoleLogger.info("Hooked successfully into " + name);
|
||||
return plugin;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -87,7 +87,7 @@ public class AuthMeEntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Need to check this, player can't throw snowball but the item is taken.
|
||||
// TODO #568: Need to check this, player can't throw snowball but the item is taken.
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onProjectileLaunch(ProjectileLaunchEvent event) {
|
||||
if (event.getEntity() == null) {
|
||||
@ -103,7 +103,7 @@ public class AuthMeEntityListener implements Listener {
|
||||
}
|
||||
player = (Player) shooter;
|
||||
} else {
|
||||
// TODO ljacqu 20151220: Invoking getShooter() with null but method isn't static
|
||||
// TODO #568 20151220: Invoking getShooter() with null but method isn't static
|
||||
try {
|
||||
if (getShooter == null) {
|
||||
getShooter = Projectile.class.getMethod("getShooter");
|
||||
|
@ -22,29 +22,35 @@ import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.MethodUtils;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
*/
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
public class AuthMeInventoryPacketAdapter extends PacketAdapter {
|
||||
|
||||
private static final int PLAYER_INVENTORY = 0;
|
||||
// http://wiki.vg/Inventory#Inventory (0-4 crafting, 5-8 armor, 9-35 main inventory, 36-44 hotbar)
|
||||
// http://wiki.vg/Inventory#Inventory (0-4 crafting, 5-8 armor, 9-35 main inventory, 36-44 hotbar, 45 off hand)
|
||||
// +1 because an index starts with 0
|
||||
private static final int CRAFTING_SIZE = 5;
|
||||
private static final int ARMOR_SIZE = 4;
|
||||
private static final int MAIN_SIZE = 27;
|
||||
private static final int HOTBAR_SIZE = 9;
|
||||
private static final int OFF_HAND_POSITION = 45;
|
||||
|
||||
private final boolean offHandSupported = MethodUtils
|
||||
.getAccessibleMethod(PlayerInventory.class, "getItemInOffHand", new Class[]{}) != null;
|
||||
|
||||
public AuthMeInventoryPacketAdapter(AuthMe plugin) {
|
||||
super(plugin, PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS);
|
||||
@ -90,17 +96,23 @@ public class AuthMeInventoryPacketAdapter extends PacketAdapter {
|
||||
ItemStack[] storedInventory = Arrays.copyOfRange(mainInventory, HOTBAR_SIZE, mainInventory.length);
|
||||
|
||||
// concat all parts of the inventory together
|
||||
int inventorySize = playerCrafting.length + armorContents.length + mainInventory.length;
|
||||
int inventorySize = CRAFTING_SIZE + ARMOR_SIZE + MAIN_SIZE + HOTBAR_SIZE;
|
||||
if (offHandSupported) {
|
||||
inventorySize++;
|
||||
}
|
||||
|
||||
ItemStack[] completeInventory = new ItemStack[inventorySize];
|
||||
|
||||
System.arraycopy(playerCrafting, 0, completeInventory, 0, playerCrafting.length);
|
||||
System.arraycopy(armorContents, 0, completeInventory, playerCrafting.length, armorContents.length);
|
||||
System.arraycopy(playerCrafting, 0, completeInventory, 0, CRAFTING_SIZE);
|
||||
System.arraycopy(armorContents, 0, completeInventory, CRAFTING_SIZE, ARMOR_SIZE);
|
||||
|
||||
// storedInventory and hotbar
|
||||
System.arraycopy(storedInventory, 0, completeInventory
|
||||
, playerCrafting.length + armorContents.length, storedInventory.length);
|
||||
System.arraycopy(hotbar, 0, completeInventory
|
||||
, playerCrafting.length + armorContents.length + storedInventory.length, hotbar.length);
|
||||
System.arraycopy(storedInventory, 0, completeInventory, CRAFTING_SIZE + ARMOR_SIZE, MAIN_SIZE);
|
||||
System.arraycopy(hotbar, 0, completeInventory, CRAFTING_SIZE + ARMOR_SIZE + MAIN_SIZE, HOTBAR_SIZE);
|
||||
|
||||
if (offHandSupported) {
|
||||
completeInventory[OFF_HAND_POSITION] = player.getInventory().getItemInOffHand();
|
||||
}
|
||||
|
||||
inventoryPacket.getItemArrayModifier().write(0, completeInventory);
|
||||
try {
|
||||
|
@ -9,10 +9,12 @@ 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.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
@ -58,10 +60,17 @@ public class AuthMePlayerListener implements Listener {
|
||||
public static final ConcurrentHashMap<String, Boolean> causeByAuthMe = new ConcurrentHashMap<>();
|
||||
private final AuthMe plugin;
|
||||
private final Messages m;
|
||||
private final DataSource dataSource;
|
||||
private final AntiBot antiBot;
|
||||
private final Management management;
|
||||
|
||||
public AuthMePlayerListener(AuthMe plugin) {
|
||||
this.m = plugin.getMessages();
|
||||
public AuthMePlayerListener(AuthMe plugin, Messages messages, DataSource dataSource, AntiBot antiBot,
|
||||
Management management) {
|
||||
this.plugin = plugin;
|
||||
this.m = messages;
|
||||
this.dataSource = dataSource;
|
||||
this.antiBot = antiBot;
|
||||
this.management = management;
|
||||
}
|
||||
|
||||
private void handleChat(AsyncPlayerChatEvent event) {
|
||||
@ -80,15 +89,14 @@ public class AuthMePlayerListener implements Listener {
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
sendLoginRegisterMSG(player);
|
||||
sendLoginOrRegisterMessage(player);
|
||||
}
|
||||
|
||||
// TODO: new name
|
||||
private void sendLoginRegisterMSG(final Player player) {
|
||||
private void sendLoginOrRegisterMessage(final Player player) {
|
||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (plugin.getDataSource().isAuthAvailable(player.getName().toLowerCase())) {
|
||||
if (dataSource.isAuthAvailable(player.getName().toLowerCase())) {
|
||||
m.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else {
|
||||
if (Settings.emailRegistration) {
|
||||
@ -117,7 +125,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
sendLoginRegisterMSG(event.getPlayer());
|
||||
sendLoginOrRegisterMessage(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
@ -230,14 +238,14 @@ public class AuthMePlayerListener implements Listener {
|
||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
plugin.getManagement().performJoin(player);
|
||||
management.performJoin(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
||||
PlayerAuth auth = plugin.getDataSource().getAuth(event.getName());
|
||||
PlayerAuth auth = dataSource.getAuth(event.getName());
|
||||
if (Settings.preventOtherCase && auth != null && auth.getRealName() != null) {
|
||||
String realName = auth.getRealName();
|
||||
if (!realName.isEmpty() && !realName.equals("Player") && !realName.equals(event.getName())) {
|
||||
@ -246,7 +254,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
if (realName.isEmpty() || realName.equals("Player")) {
|
||||
plugin.getDataSource().updateRealName(event.getName().toLowerCase(), event.getName());
|
||||
dataSource.updateRealName(event.getName().toLowerCase(), event.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,7 +328,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
}
|
||||
|
||||
final String name = player.getName().toLowerCase();
|
||||
boolean isAuthAvailable = plugin.getDataSource().isAuthAvailable(name);
|
||||
boolean isAuthAvailable = dataSource.isAuthAvailable(name);
|
||||
|
||||
if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) {
|
||||
if (Settings.antiBotInAction) {
|
||||
@ -346,7 +354,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
AntiBot.checkAntiBot(player);
|
||||
antiBot.checkAntiBot(player);
|
||||
|
||||
if (Settings.bungee) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
@ -367,7 +375,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
event.setQuitMessage(null);
|
||||
}
|
||||
|
||||
plugin.getManagement().performQuit(player, false);
|
||||
management.performQuit(player, false);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
@ -493,13 +501,13 @@ public class AuthMePlayerListener implements Listener {
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName().toLowerCase();
|
||||
Location spawn = plugin.getSpawnLocation(player);
|
||||
if (Settings.isSaveQuitLocationEnabled && plugin.getDataSource().isAuthAvailable(name)) {
|
||||
if (Settings.isSaveQuitLocationEnabled && dataSource.isAuthAvailable(name)) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.realName(player.getName())
|
||||
.location(spawn)
|
||||
.build();
|
||||
plugin.getDataSource().updateQuitLoc(auth);
|
||||
dataSource.updateQuitLoc(auth);
|
||||
}
|
||||
if (spawn != null && spawn.getWorld() != null) {
|
||||
event.setRespawnLocation(spawn);
|
||||
|
@ -2,9 +2,11 @@ package fr.xephi.authme.listener;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -12,18 +14,21 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.event.server.ServerListPingEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AuthMeServerListener implements Listener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final Messages m;
|
||||
private final Messages messages;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
|
||||
public AuthMeServerListener(AuthMe plugin) {
|
||||
this.m = plugin.getMessages();
|
||||
public AuthMeServerListener(AuthMe plugin, Messages messages, PluginHooks pluginHooks, SpawnLoader spawnLoader) {
|
||||
this.plugin = plugin;
|
||||
this.messages = messages;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
@ -31,11 +36,11 @@ public class AuthMeServerListener implements Listener {
|
||||
if (!Settings.countriesBlacklist.isEmpty() || !Settings.countries.isEmpty()){
|
||||
String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
|
||||
if( Settings.countriesBlacklist.contains(countryCode)) {
|
||||
event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
event.setMotd(messages.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
return;
|
||||
}
|
||||
if (Settings.enableProtection && !Settings.countries.contains(countryCode)) {
|
||||
event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
event.setMotd(messages.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,38 +52,21 @@ public class AuthMeServerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the plugin instance
|
||||
Plugin pluginInstance = event.getPlugin();
|
||||
|
||||
// Make sure it's not this plugin itself
|
||||
if (pluginInstance.equals(this.plugin)) {
|
||||
return;
|
||||
final String pluginName = event.getPlugin().getName();
|
||||
if ("Essentials".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.unhookEssentials();
|
||||
ConsoleLogger.info("Essentials has been disabled: unhooking");
|
||||
} else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.unhookMultiverse();
|
||||
ConsoleLogger.info("Multiverse-Core has been disabled: unhooking");
|
||||
} else if ("CombatTagPlus".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.unhookCombatPlus();
|
||||
ConsoleLogger.info("CombatTagPlus has been disabled: unhooking");
|
||||
} else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) {
|
||||
spawnLoader.unloadEssentialsSpawn();
|
||||
ConsoleLogger.info("EssentialsSpawn has been disabled: unhooking");
|
||||
}
|
||||
|
||||
// Call the onPluginDisable method in the permissions manager
|
||||
this.plugin.getPermissionsManager().onPluginDisable(event);
|
||||
|
||||
String pluginName = pluginInstance.getName();
|
||||
if (pluginName.equalsIgnoreCase("Essentials")) {
|
||||
plugin.ess = null;
|
||||
ConsoleLogger.info("Essentials has been disabled, unhook!");
|
||||
return;
|
||||
}
|
||||
if (pluginName.equalsIgnoreCase("EssentialsSpawn")) {
|
||||
plugin.essentialsSpawn = null;
|
||||
ConsoleLogger.info("EssentialsSpawn has been disabled, unhook!");
|
||||
return;
|
||||
}
|
||||
if (pluginName.equalsIgnoreCase("Multiverse-Core")) {
|
||||
plugin.multiverse = null;
|
||||
ConsoleLogger.info("Multiverse-Core has been disabled, unhook!");
|
||||
return;
|
||||
}
|
||||
if (pluginName.equalsIgnoreCase("CombatTagPlus")) {
|
||||
plugin.combatTagPlus = null;
|
||||
ConsoleLogger.info("CombatTagPlus has been disabled, unhook!");
|
||||
return;
|
||||
}
|
||||
if (pluginName.equalsIgnoreCase("ProtocolLib")) {
|
||||
plugin.inventoryProtector = null;
|
||||
plugin.tablistHider = null;
|
||||
@ -89,22 +77,22 @@ public class AuthMeServerListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPluginEnable(PluginEnableEvent event) {
|
||||
// Call the onPluginEnable method in the permissions manager
|
||||
this.plugin.getPermissionsManager().onPluginEnable(event);
|
||||
// Make sure the plugin instance isn't null
|
||||
if (event.getPlugin() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String pluginName = event.getPlugin().getName();
|
||||
if (pluginName.equalsIgnoreCase("Essentials") || pluginName.equalsIgnoreCase("EssentialsSpawn")) {
|
||||
plugin.checkEssentials();
|
||||
return;
|
||||
}
|
||||
if (pluginName.equalsIgnoreCase("Multiverse-Core")) {
|
||||
plugin.checkMultiverse();
|
||||
return;
|
||||
}
|
||||
if (pluginName.equalsIgnoreCase("CombatTagPlus")) {
|
||||
plugin.checkCombatTagPlus();
|
||||
return;
|
||||
final String pluginName = event.getPlugin().getName();
|
||||
if ("Essentials".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.tryHookToEssentials();
|
||||
} else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.tryHookToMultiverse();
|
||||
} else if ("CombatTagPlus".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.tryHookToCombatPlus();
|
||||
} else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) {
|
||||
spawnLoader.loadEssentialsSpawn();
|
||||
}
|
||||
|
||||
if (pluginName.equalsIgnoreCase("ProtocolLib")) {
|
||||
plugin.checkProtocolLib();
|
||||
}
|
||||
|
@ -29,11 +29,13 @@ public class AuthMeTablistPacketAdapter extends PacketAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix this in 1.9
|
||||
public void register() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||
ConsoleLogger.showError("The hideTablistBeforeLogin feature is temporarily disabled due to issues with 1.9 clients.");
|
||||
//ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
||||
//ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
||||
}
|
||||
}
|
||||
|
@ -59,13 +59,16 @@ public class Log4JFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public Result filter(Logger arg0, Level arg1, Marker arg2, String message, Object... arg4) {
|
||||
if (message == null) {
|
||||
return Result.NEUTRAL;
|
||||
}
|
||||
return validateMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, Throwable arg4) {
|
||||
if (message == null) {
|
||||
return Result.NEUTRAL;
|
||||
if (message == null) {
|
||||
return Result.NEUTRAL;
|
||||
}
|
||||
return validateMessage(message.toString());
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -24,7 +24,6 @@ import de.bananaco.bpermissions.api.CalculableType;
|
||||
import fr.xephi.authme.command.CommandDescription;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import ru.tehkode.permissions.PermissionManager;
|
||||
import ru.tehkode.permissions.PermissionUser;
|
||||
import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
|
||||
@ -38,7 +37,7 @@ import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
* Written by Tim Visée.
|
||||
* </p>
|
||||
* @author Tim Visée, http://timvisee.com
|
||||
* @version 0.2.1
|
||||
* @version 0.3
|
||||
*/
|
||||
public class PermissionsManager implements PermissionsService {
|
||||
|
||||
@ -59,9 +58,14 @@ public class PermissionsManager implements PermissionsService {
|
||||
*/
|
||||
private Logger log;
|
||||
/**
|
||||
* Type of permissions system that is currently used.
|
||||
* The permissions manager Bukkit listener instance.
|
||||
*/
|
||||
private PermissionsSystemType permsType = PermissionsSystemType.NONE;
|
||||
private PermissionsManagerBukkitListener bukkitListener;
|
||||
/**
|
||||
* Type of permissions system that is currently used.
|
||||
* Null if no permissions system is hooked and/or used.
|
||||
*/
|
||||
private PermissionsSystemType permsType = null;
|
||||
/**
|
||||
* Essentials group manager instance.
|
||||
*/
|
||||
@ -82,6 +86,21 @@ public class PermissionsManager implements PermissionsService {
|
||||
this.server = server;
|
||||
this.plugin = plugin;
|
||||
this.log = log;
|
||||
|
||||
// Create and register the Bukkit listener on the server if it's valid
|
||||
if(this.server != null) {
|
||||
// Create the Bukkit listener
|
||||
this.bukkitListener = new PermissionsManagerBukkitListener(this);
|
||||
|
||||
// Get the plugin manager instance
|
||||
PluginManager pluginManager = this.server.getPluginManager();
|
||||
|
||||
// Register the Bukkit listener
|
||||
pluginManager.registerEvents(this.bukkitListener, this.plugin);
|
||||
|
||||
// Show a status message.
|
||||
//this.log.info("Started permission plugins state listener!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +109,7 @@ public class PermissionsManager implements PermissionsService {
|
||||
* @return False if there isn't any permissions system used.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return !permsType.equals(PermissionsSystemType.NONE);
|
||||
return permsType != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,110 +127,96 @@ public class PermissionsManager implements PermissionsService {
|
||||
* @return The detected permissions system.
|
||||
*/
|
||||
public PermissionsSystemType setup() {
|
||||
// Force-unhook from current hooked permissions systems
|
||||
unhook();
|
||||
|
||||
// Define the plugin manager
|
||||
final PluginManager pm = this.server.getPluginManager();
|
||||
final PluginManager pluginManager = this.server.getPluginManager();
|
||||
|
||||
// Reset used permissions system type
|
||||
permsType = PermissionsSystemType.NONE;
|
||||
// Reset used permissions system type flag
|
||||
permsType = null;
|
||||
|
||||
// PermissionsEx, check if it's available
|
||||
try {
|
||||
Plugin pex = pm.getPlugin("PermissionsEx");
|
||||
if (pex != null) {
|
||||
PermissionManager pexPerms = PermissionsEx.getPermissionManager();
|
||||
if (pexPerms != null) {
|
||||
permsType = PermissionsSystemType.PERMISSIONS_EX;
|
||||
// Loop through all the available permissions system types
|
||||
for(PermissionsSystemType type : PermissionsSystemType.values()) {
|
||||
// Try to find and hook the current plugin if available, print an error if failed
|
||||
try {
|
||||
// Try to find the plugin for the current permissions system
|
||||
Plugin plugin = pluginManager.getPlugin(type.getPluginName());
|
||||
|
||||
System.out.println("[" + plugin.getName() + "] Hooked into PermissionsEx!");
|
||||
return permsType;
|
||||
// Make sure a plugin with this name was found
|
||||
if(plugin == null)
|
||||
continue;
|
||||
|
||||
// Make sure the plugin is enabled before hooking
|
||||
if(!plugin.isEnabled()) {
|
||||
this.log.info("Not hooking into " + type.getName() + " because it's disabled!");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
System.out.println("[" + plugin.getName() + "] Error while hooking into PermissionsEx!");
|
||||
}
|
||||
|
||||
// PermissionsBukkit, check if it's available
|
||||
try {
|
||||
Plugin bukkitPerms = pm.getPlugin("PermissionsBukkit");
|
||||
if (bukkitPerms != null) {
|
||||
permsType = PermissionsSystemType.PERMISSIONS_BUKKIT;
|
||||
System.out.println("[" + plugin.getName() + "] Hooked into PermissionsBukkit!");
|
||||
return permsType;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
System.out.println("[" + plugin.getName() + "] Error while hooking into PermissionsBukkit!");
|
||||
}
|
||||
// Use the proper method to hook this plugin
|
||||
switch(type) {
|
||||
case PERMISSIONS_EX:
|
||||
// Get the permissions manager for PermissionsEx and make sure it isn't null
|
||||
if(PermissionsEx.getPermissionManager() == null) {
|
||||
this.log.info("Failed to hook into " + type.getName() + "!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// bPermissions, check if it's available
|
||||
try {
|
||||
Plugin bPerms = pm.getPlugin("bPermissions");
|
||||
if (bPerms != null) {
|
||||
permsType = PermissionsSystemType.B_PERMISSIONS;
|
||||
System.out.println("[" + plugin.getName() + "] Hooked into bPermissions!");
|
||||
return permsType;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
System.out.println("[" + plugin.getName() + "] Error while hooking into bPermissions!");
|
||||
}
|
||||
break;
|
||||
|
||||
// Essentials Group Manager, check if it's available
|
||||
try {
|
||||
final Plugin groupManagerPlugin = pm.getPlugin("GroupManager");
|
||||
if (groupManagerPlugin != null && groupManagerPlugin.isEnabled()) {
|
||||
permsType = PermissionsSystemType.ESSENTIALS_GROUP_MANAGER;
|
||||
groupManagerPerms = (GroupManager) groupManagerPlugin;
|
||||
System.out.println("[" + plugin.getName() + "] Hooked into Essentials Group Manager!");
|
||||
return permsType;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
System.out.println("[" + plugin.getName() + "] Error while hooking into Essentials Group Manager!");
|
||||
}
|
||||
case ESSENTIALS_GROUP_MANAGER:
|
||||
// Set the plugin instance
|
||||
groupManagerPerms = (GroupManager) plugin;
|
||||
break;
|
||||
|
||||
// zPermissions, check if it's available
|
||||
try {
|
||||
Plugin zPerms = pm.getPlugin("zPermissions");
|
||||
if (zPerms != null) {
|
||||
zPermissionsService = Bukkit.getServicesManager().load(ZPermissionsService.class);
|
||||
if (zPermissionsService != null) {
|
||||
permsType = PermissionsSystemType.Z_PERMISSIONS;
|
||||
System.out.println("[" + plugin.getName() + "] Hooked into zPermissions!");
|
||||
return permsType;
|
||||
case Z_PERMISSIONS:
|
||||
// Set the zPermissions service and make sure it's valid
|
||||
zPermissionsService = Bukkit.getServicesManager().load(ZPermissionsService.class);
|
||||
if(zPermissionsService == null) {
|
||||
this.log.info("Failed to hook into " + type.getName() + "!");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VAULT:
|
||||
// Get the permissions provider service
|
||||
RegisteredServiceProvider<Permission> permissionProvider = this.server.getServicesManager().getRegistration(Permission.class);
|
||||
if (permissionProvider == null) {
|
||||
this.log.info("Failed to hook into " + type.getName() + "!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the Vault provider and make sure it's valid
|
||||
vaultPerms = permissionProvider.getProvider();
|
||||
if(vaultPerms == null) {
|
||||
this.log.info("Not using " + type.getName() + " because it's disabled!");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
// Set the hooked permissions system type
|
||||
this.permsType = type;
|
||||
|
||||
// Show a success message
|
||||
this.log.info("Hooked into " + type.getName() + "!");
|
||||
|
||||
// Return the used permissions system type
|
||||
return type;
|
||||
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
this.log.info("Error while hooking into " + type.getName() + "!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
System.out.println("[" + plugin.getName() + "] Error while hooking into zPermissions!");
|
||||
}
|
||||
|
||||
// Vault, check if it's available
|
||||
try {
|
||||
final Plugin vaultPlugin = pm.getPlugin("Vault");
|
||||
if (vaultPlugin != null && vaultPlugin.isEnabled()) {
|
||||
RegisteredServiceProvider<Permission> permissionProvider = this.server.getServicesManager().getRegistration(Permission.class);
|
||||
if (permissionProvider != null) {
|
||||
vaultPerms = permissionProvider.getProvider();
|
||||
if (vaultPerms.isEnabled()) {
|
||||
permsType = PermissionsSystemType.VAULT;
|
||||
System.out.println("[" + plugin.getName() + "] Hooked into Vault Permissions!");
|
||||
return permsType;
|
||||
} else {
|
||||
System.out.println("[" + plugin.getName() + "] Not using Vault Permissions, Vault Permissions is disabled!");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// An error occurred, show a warning message
|
||||
System.out.println("[" + plugin.getName() + "] Error while hooking into Vault Permissions!");
|
||||
}
|
||||
|
||||
// No recognized permissions system found
|
||||
permsType = PermissionsSystemType.NONE;
|
||||
System.out.println("[" + plugin.getName() + "] No supported permissions system found! Permissions disabled!");
|
||||
return PermissionsSystemType.NONE;
|
||||
// No recognized permissions system found, show a message and return
|
||||
this.log.info("No supported permissions system found! Permissions are disabled!");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,7 +224,7 @@ public class PermissionsManager implements PermissionsService {
|
||||
*/
|
||||
public void unhook() {
|
||||
// Reset the current used permissions system
|
||||
this.permsType = PermissionsSystemType.NONE;
|
||||
this.permsType = null;
|
||||
|
||||
// Print a status message to the console
|
||||
this.log.info("Unhooked from Permissions!");
|
||||
@ -277,7 +282,14 @@ public class PermissionsManager implements PermissionsService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the permissions manager Bukkit listener instance.
|
||||
*
|
||||
* @return Listener instance.
|
||||
*/
|
||||
public PermissionsManagerBukkitListener getListener() {
|
||||
return this.bukkitListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the command sender has permission for the given permissions node. If no permissions system is used or
|
||||
@ -383,13 +395,9 @@ public class PermissionsManager implements PermissionsService {
|
||||
// Vault
|
||||
return vaultPerms.has(player, permsNode);
|
||||
|
||||
case NONE:
|
||||
default:
|
||||
// Not hooked into any permissions system, return default
|
||||
return def;
|
||||
|
||||
default:
|
||||
// Something went wrong, return false to prevent problems
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,12 +424,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
// Vault
|
||||
return vaultPerms.hasGroupSupport();
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
|
||||
default:
|
||||
// Something went wrong, return false to prevent problems
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -469,12 +473,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
// Vault
|
||||
return Arrays.asList(vaultPerms.getPlayerGroups(player));
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return an empty list
|
||||
return new ArrayList<>();
|
||||
|
||||
default:
|
||||
// Something went wrong, return an empty list to prevent problems
|
||||
// Not hooked into any permissions system, return an empty list
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@ -521,12 +521,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
// Vault
|
||||
return vaultPerms.getPrimaryGroup(player);
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return null
|
||||
return null;
|
||||
|
||||
default:
|
||||
// Something went wrong, return null to prevent problems
|
||||
// Not hooked into any permissions system, return null
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -575,12 +571,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
// Vault
|
||||
return vaultPerms.playerInGroup(player, groupName);
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return an empty list
|
||||
return false;
|
||||
|
||||
default:
|
||||
// Something went wrong, return an empty list to prevent problems
|
||||
// Not hooked into any permissions system, return an empty list
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -632,12 +624,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
vaultPerms.playerAddGroup(player, groupName);
|
||||
return true;
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
|
||||
default:
|
||||
// Something went wrong, return false
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -713,12 +701,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
vaultPerms.playerRemoveGroup(player, groupName);
|
||||
return true;
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
|
||||
default:
|
||||
// Something went wrong, return false
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -802,12 +786,8 @@ public class PermissionsManager implements PermissionsService {
|
||||
vaultPerms.playerAddGroup(player, groupName);
|
||||
return true;
|
||||
|
||||
case NONE:
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
|
||||
default:
|
||||
// Something went wrong, return false
|
||||
// Not hooked into any permissions system, return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -867,6 +847,4 @@ public class PermissionsManager implements PermissionsService {
|
||||
// Remove each group
|
||||
return removeGroups(player, groupNames);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
package fr.xephi.authme.permission;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
|
||||
public class PermissionsManagerBukkitListener implements Listener {
|
||||
|
||||
/**
|
||||
* The permissions manager instance.
|
||||
*/
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
/**
|
||||
* Whether the listener is enabled or not.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Constructor.\
|
||||
*
|
||||
* @param permissionsManager Permissions manager instance.
|
||||
*/
|
||||
public PermissionsManagerBukkitListener(PermissionsManager permissionsManager) {
|
||||
this.permissionsManager = permissionsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the listener is enabled.
|
||||
*
|
||||
* @return True if the listener is enabled.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the listener is enabled.
|
||||
* Disabling the listener will stop the event handling until it's enabled again.
|
||||
*
|
||||
* @param enabled True if enabled, false if disabled.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a plugin is enabled.
|
||||
*
|
||||
* @param event Event reference.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent event) {
|
||||
// Make sure the listener is enabled
|
||||
if(!isEnabled())
|
||||
return;
|
||||
|
||||
// Make sure the permissions manager is set
|
||||
if(this.permissionsManager == null)
|
||||
return;
|
||||
|
||||
// Call the onPluginEnable method in the permissions manager
|
||||
permissionsManager.onPluginEnable(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a plugin is disabled.
|
||||
*
|
||||
* @param event Event reference.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
// Make sure the listener is enabled
|
||||
if(!isEnabled())
|
||||
return;
|
||||
|
||||
// Make sure the permissions manager is set
|
||||
if(this.permissionsManager == null)
|
||||
return;
|
||||
|
||||
// Call the onPluginDisable method in the permissions manager
|
||||
permissionsManager.onPluginDisable(event);
|
||||
}
|
||||
}
|
@ -5,32 +5,82 @@ package fr.xephi.authme.permission;
|
||||
*/
|
||||
public enum PermissionsSystemType {
|
||||
|
||||
NONE("None"),
|
||||
/**
|
||||
* Permissions Ex.
|
||||
*/
|
||||
PERMISSIONS_EX("PermissionsEx", "PermissionsEx"),
|
||||
|
||||
PERMISSIONS_EX("PermissionsEx"),
|
||||
/**
|
||||
* Permissions Bukkit.
|
||||
*/
|
||||
PERMISSIONS_BUKKIT("Permissions Bukkit", "PermissionsBukkit"),
|
||||
|
||||
PERMISSIONS_BUKKIT("Permissions Bukkit"),
|
||||
/**
|
||||
* bPermissions.
|
||||
*/
|
||||
B_PERMISSIONS("bPermissions", "bPermissions"),
|
||||
|
||||
B_PERMISSIONS("bPermissions"),
|
||||
/**
|
||||
* Essentials Group Manager.
|
||||
*/
|
||||
ESSENTIALS_GROUP_MANAGER("Essentials Group Manager", "GroupManager"),
|
||||
|
||||
ESSENTIALS_GROUP_MANAGER("Essentials Group Manager"),
|
||||
/**
|
||||
* zPermissions.
|
||||
*/
|
||||
Z_PERMISSIONS("zPermissions", "zPermissions"),
|
||||
|
||||
Z_PERMISSIONS("zPermissions"),
|
||||
/**
|
||||
* Vault.
|
||||
*/
|
||||
VAULT("Vault", "Vault");
|
||||
|
||||
VAULT("Vault");
|
||||
/**
|
||||
* The display name of the permissions system.
|
||||
*/
|
||||
public String name;
|
||||
|
||||
public final String name;
|
||||
/**
|
||||
* The name of the permissions system plugin.
|
||||
*/
|
||||
public String pluginName;
|
||||
|
||||
/**
|
||||
* Constructor for PermissionsSystemType.
|
||||
*
|
||||
* @param name The name the permissions manager goes by
|
||||
* @param name Display name of the permissions system.
|
||||
* @param pluginName Name of the plugin.
|
||||
*/
|
||||
PermissionsSystemType(String name) {
|
||||
PermissionsSystemType(String name, String pluginName) {
|
||||
this.name = name;
|
||||
this.pluginName = pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name of the permissions system.
|
||||
*
|
||||
* @return Display name.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the plugin name.
|
||||
*
|
||||
* @return Plugin name.
|
||||
*/
|
||||
public String getPluginName() {
|
||||
return this.pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the permissions system type to a string.
|
||||
*
|
||||
* @return The display name of the permissions system.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
@ -55,10 +55,10 @@ public enum PlayerPermission implements PermissionNode {
|
||||
*/
|
||||
CAN_LOGIN_BE_FORCED("authme.player.canbeforced"),
|
||||
|
||||
/**
|
||||
* Permission to use to see own other accounts.
|
||||
*/
|
||||
SEE_OWN_ACCOUNTS("authme.player.seeownaccounts");
|
||||
/**
|
||||
* Permission to use to see own other accounts.
|
||||
*/
|
||||
SEE_OWN_ACCOUNTS("authme.player.seeownaccounts");
|
||||
|
||||
/**
|
||||
* The permission node.
|
||||
|
@ -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;
|
||||
@ -10,7 +11,6 @@ import fr.xephi.authme.process.logout.AsynchronousLogout;
|
||||
import fr.xephi.authme.process.quit.AsynchronousQuit;
|
||||
import fr.xephi.authme.process.register.AsyncRegister;
|
||||
import fr.xephi.authme.process.unregister.AsynchronousUnregister;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
@ -20,99 +20,51 @@ public class Management {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final BukkitScheduler sched;
|
||||
private final NewSetting settings;
|
||||
private final ProcessService processService;
|
||||
private final DataSource dataSource;
|
||||
private final PlayerCache playerCache;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public void performLogin(final Player player, final String password, final boolean forceLogin) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousLogin(player, password, forceLogin, plugin, plugin.getDataSource(), settings)
|
||||
.process();
|
||||
}
|
||||
});
|
||||
runTask(new AsynchronousLogin(player, password, forceLogin, plugin, dataSource, processService));
|
||||
}
|
||||
|
||||
public void performLogout(final Player player) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousLogout(player, plugin, plugin.getDataSource()).process();
|
||||
}
|
||||
});
|
||||
runTask(new AsynchronousLogout(player, plugin, dataSource, processService));
|
||||
}
|
||||
|
||||
public void performRegister(final Player player, final String password, final String email) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncRegister(player, password, email, plugin, plugin.getDataSource(), settings).process();
|
||||
}
|
||||
});
|
||||
runTask(new AsyncRegister(player, password, email, plugin, dataSource, processService));
|
||||
}
|
||||
|
||||
public void performUnregister(final Player player, final String password, final boolean force) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousUnregister(player, password, force, plugin).process();
|
||||
}
|
||||
});
|
||||
runTask(new AsynchronousUnregister(player, password, force, plugin, processService));
|
||||
}
|
||||
|
||||
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) {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousQuit(player, plugin, plugin.getDataSource(), isKick).process();
|
||||
}
|
||||
|
||||
});
|
||||
runTask(new AsynchronousQuit(player, plugin, dataSource, isKick, processService));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
runTask(new AsyncChangeEmail(player, oldEmail, newEmail, dataSource, playerCache, processService));
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
}
|
202
src/main/java/fr/xephi/authme/process/ProcessService.java
Normal file
202
src/main/java/fr/xephi/authme/process/ProcessService.java
Normal file
@ -0,0 +1,202 @@
|
||||
package fr.xephi.authme.process;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.IpAddressManager;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import 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;
|
||||
private final DataSource dataSource;
|
||||
private final IpAddressManager ipAddressManager;
|
||||
private final PasswordSecurity passwordSecurity;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
|
||||
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, DataSource dataSource,
|
||||
IpAddressManager ipAddressManager, PasswordSecurity passwordSecurity, PluginHooks pluginHooks,
|
||||
SpawnLoader spawnLoader) {
|
||||
this.settings = settings;
|
||||
this.messages = messages;
|
||||
this.authMe = authMe;
|
||||
this.dataSource = dataSource;
|
||||
this.ipAddressManager = ipAddressManager;
|
||||
this.passwordSecurity = passwordSecurity;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a property's value.
|
||||
*
|
||||
* @param property the property to retrieve
|
||||
* @param <T> the property type
|
||||
* @return the property's value
|
||||
*/
|
||||
public <T> T getProperty(Property<T> property) {
|
||||
return settings.getProperty(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the settings manager.
|
||||
*
|
||||
* @return settings manager
|
||||
*/
|
||||
public NewSetting getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to the command sender.
|
||||
*
|
||||
* @param sender the command sender
|
||||
* @param key the message key
|
||||
*/
|
||||
public void send(CommandSender sender, MessageKey key) {
|
||||
messages.send(sender, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to the command sender with the given replacements.
|
||||
*
|
||||
* @param sender the command sender
|
||||
* @param key the message key
|
||||
* @param replacements the replacements to apply to the message
|
||||
*/
|
||||
public void send(CommandSender sender, MessageKey key, String... replacements) {
|
||||
messages.send(sender, key, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a message.
|
||||
*
|
||||
* @param key the key of the message
|
||||
* @return the message, split by line
|
||||
*/
|
||||
public String[] retrieveMessage(MessageKey key) {
|
||||
return messages.retrieve(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a message as one piece.
|
||||
*
|
||||
* @param key the key of the message
|
||||
* @return the message
|
||||
*/
|
||||
public String retrieveSingleMessage(MessageKey key) {
|
||||
return messages.retrieveSingle(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a task.
|
||||
*
|
||||
* @param task the task to run
|
||||
* @return the assigned task id
|
||||
*/
|
||||
public BukkitTask runTask(Runnable task) {
|
||||
return authMe.getServer().getScheduler().runTask(authMe, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a task at a later time.
|
||||
*
|
||||
* @param task the task to run
|
||||
* @param delay the delay before running the task
|
||||
* @return the assigned task id
|
||||
*/
|
||||
public BukkitTask runTaskLater(Runnable task, long delay) {
|
||||
return authMe.getServer().getScheduler().runTaskLater(authMe, task, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a synchronous delayed task.
|
||||
*
|
||||
* @param task the task to schedule
|
||||
* @return the task id
|
||||
*/
|
||||
public int scheduleSyncDelayedTask(Runnable task) {
|
||||
return authMe.getServer().getScheduler().scheduleSyncDelayedTask(authMe, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event.
|
||||
*
|
||||
* @param event the event to emit
|
||||
*/
|
||||
public void callEvent(Event event) {
|
||||
authMe.getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the plugin instance.
|
||||
*
|
||||
* @return AuthMe instance
|
||||
*/
|
||||
public AuthMe getAuthMe() {
|
||||
return authMe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IP address manager.
|
||||
*
|
||||
* @return the ip address manager
|
||||
*/
|
||||
public IpAddressManager getIpAddressManager() {
|
||||
return ipAddressManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the hash for the given password.
|
||||
*
|
||||
* @param password the password to hash
|
||||
* @param username the user to hash for
|
||||
* @return the resulting hash
|
||||
*/
|
||||
public HashedPassword computeHash(String password, String username) {
|
||||
return passwordSecurity.computeHash(password, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PluginHooks manager.
|
||||
*
|
||||
* @return PluginHooks instance
|
||||
*/
|
||||
public PluginHooks getPluginHooks() {
|
||||
return pluginHooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the spawn manager.
|
||||
*
|
||||
* @return SpawnLoader instance
|
||||
*/
|
||||
public SpawnLoader getSpawnLoader() {
|
||||
return spawnLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the plugin's datasource.
|
||||
*
|
||||
* @return the datasource
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,54 +1,52 @@
|
||||
package fr.xephi.authme.process.email;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
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 for changing the email.
|
||||
*/
|
||||
public class AsyncChangeEmail {
|
||||
public class AsyncChangeEmail implements Process {
|
||||
|
||||
private final Player player;
|
||||
private final String oldEmail;
|
||||
private final String newEmail;
|
||||
private final Messages m;
|
||||
private final NewSetting settings;
|
||||
private final ProcessService service;
|
||||
private final PlayerCache playerCache;
|
||||
private final DataSource dataSource;
|
||||
|
||||
public AsyncChangeEmail(Player player, AuthMe plugin, String oldEmail, String newEmail, DataSource dataSource,
|
||||
PlayerCache playerCache, NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
public AsyncChangeEmail(Player player, String oldEmail, String newEmail, DataSource dataSource,
|
||||
PlayerCache playerCache, ProcessService service) {
|
||||
this.player = player;
|
||||
this.oldEmail = oldEmail;
|
||||
this.newEmail = newEmail;
|
||||
this.playerCache = playerCache;
|
||||
this.dataSource = dataSource;
|
||||
this.settings = settings;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
String playerName = player.getName().toLowerCase();
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
PlayerAuth auth = playerCache.getAuth(playerName);
|
||||
final String currentEmail = auth.getEmail();
|
||||
|
||||
if (currentEmail == null) {
|
||||
m.send(player, MessageKey.USAGE_ADD_EMAIL);
|
||||
} else if (newEmail == null || !Utils.isEmailCorrect(newEmail, settings)) {
|
||||
m.send(player, MessageKey.INVALID_NEW_EMAIL);
|
||||
service.send(player, MessageKey.USAGE_ADD_EMAIL);
|
||||
} else if (newEmail == null || !Utils.isEmailCorrect(newEmail, service.getSettings())) {
|
||||
service.send(player, MessageKey.INVALID_NEW_EMAIL);
|
||||
} else if (!oldEmail.equals(currentEmail)) {
|
||||
m.send(player, MessageKey.INVALID_OLD_EMAIL);
|
||||
service.send(player, MessageKey.INVALID_OLD_EMAIL);
|
||||
} else if (dataSource.isEmailStored(newEmail)) {
|
||||
m.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
} else {
|
||||
saveNewEmail(auth);
|
||||
}
|
||||
@ -61,20 +59,20 @@ public class AsyncChangeEmail {
|
||||
auth.setEmail(newEmail);
|
||||
if (dataSource.updateEmail(auth)) {
|
||||
playerCache.updatePlayer(auth);
|
||||
m.send(player, MessageKey.EMAIL_CHANGED_SUCCESS);
|
||||
service.send(player, MessageKey.EMAIL_CHANGED_SUCCESS);
|
||||
} else {
|
||||
m.send(player, MessageKey.ERROR);
|
||||
service.send(player, MessageKey.ERROR);
|
||||
auth.setEmail(newEmail);
|
||||
}
|
||||
}
|
||||
|
||||
private void outputUnloggedMessage() {
|
||||
if (dataSource.isAuthAvailable(player.getName())) {
|
||||
m.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else if (Settings.emailRegistration) {
|
||||
m.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 {
|
||||
m.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
service.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,66 +11,64 @@ 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) {
|
||||
plugin.getVerygamesIp(player);
|
||||
if (service.getProperty(HooksSettings.DISABLE_SOCIAL_SPY)) {
|
||||
service.getPluginHooks().setEssentialsSocialSpyStatus(player, false);
|
||||
}
|
||||
|
||||
if (plugin.ess != null && Settings.disableSocialSpy) {
|
||||
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() {
|
||||
|
||||
final String ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
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.retrieveSingleMessage(MessageKey.NOT_OWNER_ERROR));
|
||||
if (Settings.banUnsafeIp) {
|
||||
plugin.getServer().banIP(ip);
|
||||
}
|
||||
@ -78,38 +76,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.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 = service.getSpawnLoader().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 +117,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 +131,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 +148,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 +167,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,28 +177,23 @@ 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.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
|
||||
int msgInterval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
if (registrationTimeout > 0) {
|
||||
BukkitTask id = service.runTaskLater(new TimeoutTask(plugin, name, player), registrationTimeout);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTask(id);
|
||||
}
|
||||
|
||||
MessageKey msg;
|
||||
@ -219,29 +205,30 @@ public class AsynchronousJoin {
|
||||
: MessageKey.REGISTER_MESSAGE;
|
||||
}
|
||||
if (msgInterval > 0 && LimboCache.getInstance().getLimboPlayer(name) != null) {
|
||||
BukkitTask msgTask = sched.runTask(plugin, new MessageTask(plugin, name, msg, msgInterval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask);
|
||||
BukkitTask msgTask = service.runTask(new MessageTask(plugin, name, msg, msgInterval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTask(msgTask);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean needFirstSpawn() {
|
||||
if (player.hasPlayedBefore())
|
||||
if (player.hasPlayedBefore()) {
|
||||
return false;
|
||||
Location firstSpawn = Spawn.getInstance().getFirstSpawn();
|
||||
if (firstSpawn == null || firstSpawn.getWorld() == null)
|
||||
}
|
||||
Location firstSpawn = service.getSpawnLoader().getFirstSpawn();
|
||||
if (firstSpawn == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), firstSpawn);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
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 +236,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 +266,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 +291,14 @@ public class AsynchronousJoin {
|
||||
return nameFound;
|
||||
}
|
||||
|
||||
private boolean hasJoinedIp(String name, String ip, NewSetting settings) {
|
||||
int count = 0;
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(service.getIpAddressManager().getPlayerIp(player))
|
||||
&& !player.getName().equalsIgnoreCase(name)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count >= settings.getProperty(RestrictionSettings.MAX_JOIN_PER_IP);
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,21 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
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.DataSource;
|
||||
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.AdminPermission;
|
||||
import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
@ -27,7 +31,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AsynchronousLogin {
|
||||
public class AsynchronousLogin implements Process {
|
||||
|
||||
private final Player player;
|
||||
private final String name;
|
||||
@ -36,23 +40,11 @@ public class AsynchronousLogin {
|
||||
private final boolean forceLogin;
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private final Messages m;
|
||||
private final String ip;
|
||||
private final NewSetting settings;
|
||||
private final ProcessService service;
|
||||
|
||||
/**
|
||||
* Constructor for AsynchronousLogin.
|
||||
*
|
||||
* @param player Player
|
||||
* @param password String
|
||||
* @param forceLogin boolean
|
||||
* @param plugin AuthMe
|
||||
* @param data DataSource
|
||||
* @param settings The settings
|
||||
*/
|
||||
public AsynchronousLogin(Player player, String password, boolean forceLogin, AuthMe plugin, DataSource data,
|
||||
NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
ProcessService service) {
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.password = password;
|
||||
@ -60,12 +52,12 @@ public class AsynchronousLogin {
|
||||
this.forceLogin = forceLogin;
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.ip = plugin.getIP(player);
|
||||
this.settings = settings;
|
||||
this.ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private boolean needsCaptcha() {
|
||||
if (Settings.useCaptcha) {
|
||||
if (service.getProperty(SecuritySettings.USE_CAPTCHA)) {
|
||||
if (!plugin.captcha.containsKey(name)) {
|
||||
plugin.captcha.putIfAbsent(name, 1);
|
||||
} else {
|
||||
@ -75,7 +67,7 @@ public class AsynchronousLogin {
|
||||
}
|
||||
if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) > Settings.maxLoginTry) {
|
||||
plugin.cap.putIfAbsent(name, RandomString.generate(Settings.captchaLength));
|
||||
m.send(player, MessageKey.USAGE_CAPTCHA, plugin.cap.get(name));
|
||||
service.send(player, MessageKey.USAGE_CAPTCHA, plugin.cap.get(name));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -90,30 +82,29 @@ public class AsynchronousLogin {
|
||||
*/
|
||||
private PlayerAuth preAuth() {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerAuth pAuth = database.getAuth(name);
|
||||
if (pAuth == null) {
|
||||
m.send(player, MessageKey.USER_NOT_REGISTERED);
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
LimboCache.getInstance().getLimboPlayer(name).getMessageTaskId().cancel();
|
||||
String[] msg;
|
||||
if (Settings.emailRegistration) {
|
||||
msg = m.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
} else {
|
||||
msg = m.retrieve(MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
BukkitTask msgT = Bukkit.getScheduler().runTask(plugin,
|
||||
new MessageTask(plugin, name, msg, settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
|
||||
service.send(player, MessageKey.USER_NOT_REGISTERED);
|
||||
|
||||
LimboPlayer limboPlayer = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (limboPlayer != null) {
|
||||
limboPlayer.getMessageTask().cancel();
|
||||
String[] msg = service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)
|
||||
? service.retrieveMessage(MessageKey.REGISTER_EMAIL_MESSAGE)
|
||||
: service.retrieveMessage(MessageKey.REGISTER_MESSAGE);
|
||||
BukkitTask messageTask = service.runTask(
|
||||
new MessageTask(plugin, name, msg, service.getProperty(RegistrationSettings.MESSAGE_INTERVAL)));
|
||||
limboPlayer.setMessageTask(messageTask);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Settings.getMySQLColumnGroup.isEmpty() && pAuth.getGroupId() == Settings.getNonActivatedGroup) {
|
||||
m.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
|
||||
if (!service.getProperty(DatabaseSettings.MYSQL_COL_GROUP).isEmpty() && pAuth.getGroupId() == Settings.getNonActivatedGroup) {
|
||||
service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -121,7 +112,7 @@ public class AsynchronousLogin {
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
&& !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost")) {
|
||||
if (plugin.isLoggedIp(name, ip)) {
|
||||
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -134,13 +125,14 @@ public class AsynchronousLogin {
|
||||
return pAuth;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth pAuth = preAuth();
|
||||
if (pAuth == null || needsCaptcha()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pAuth.getIp().equals("127.0.0.1") && !pAuth.getIp().equals(ip)) {
|
||||
if ("127.0.0.1".equals(pAuth.getIp()) && !pAuth.getIp().equals(ip)) {
|
||||
pAuth.setIp(ip);
|
||||
database.updateIp(pAuth.getNickname(), ip);
|
||||
}
|
||||
@ -159,7 +151,7 @@ public class AsynchronousLogin {
|
||||
.build();
|
||||
database.updateSession(auth);
|
||||
|
||||
if (Settings.useCaptcha) {
|
||||
if (service.getProperty(SecuritySettings.USE_CAPTCHA)) {
|
||||
if (plugin.captcha.containsKey(name)) {
|
||||
plugin.captcha.remove(name);
|
||||
}
|
||||
@ -170,12 +162,12 @@ public class AsynchronousLogin {
|
||||
|
||||
player.setNoDamageTicks(0);
|
||||
if (!forceLogin)
|
||||
m.send(player, MessageKey.LOGIN_SUCCESS);
|
||||
service.send(player, MessageKey.LOGIN_SUCCESS);
|
||||
|
||||
displayOtherAccounts(auth);
|
||||
|
||||
if (Settings.recallEmail && (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email))) {
|
||||
m.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
@ -185,35 +177,35 @@ 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
|
||||
// so that we can be sure, and have not to care if it might be
|
||||
// processed in other order.
|
||||
ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(player, plugin, database, settings);
|
||||
ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(
|
||||
player, plugin, database, service.getSettings());
|
||||
if (syncPlayerLogin.getLimbo() != null) {
|
||||
if (syncPlayerLogin.getLimbo().getTimeoutTaskId() != null) {
|
||||
syncPlayerLogin.getLimbo().getTimeoutTaskId().cancel();
|
||||
if (syncPlayerLogin.getLimbo().getTimeoutTask() != null) {
|
||||
syncPlayerLogin.getLimbo().getTimeoutTask().cancel();
|
||||
}
|
||||
if (syncPlayerLogin.getLimbo().getMessageTaskId() != null) {
|
||||
syncPlayerLogin.getLimbo().getMessageTaskId().cancel();
|
||||
if (syncPlayerLogin.getLimbo().getMessageTask() != null) {
|
||||
syncPlayerLogin.getLimbo().getMessageTask().cancel();
|
||||
}
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, syncPlayerLogin);
|
||||
} else if (player.isOnline()) {
|
||||
if (!Settings.noConsoleSpam)
|
||||
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info(realName + " used the wrong password");
|
||||
if (Settings.isKickOnWrongPasswordEnabled) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
}
|
||||
if (service.getProperty(RestrictionSettings.KICK_ON_WRONG_PASSWORD)) {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.kickPlayer(m.retrieveSingle(MessageKey.WRONG_PASSWORD));
|
||||
player.kickPlayer(service.retrieveSingleMessage(MessageKey.WRONG_PASSWORD));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
m.send(player, MessageKey.WRONG_PASSWORD);
|
||||
service.send(player, MessageKey.WRONG_PASSWORD);
|
||||
}
|
||||
} else {
|
||||
ConsoleLogger.showError("Player " + name + " wasn't online during login process, aborted... ");
|
||||
@ -232,8 +224,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();
|
||||
@ -69,7 +67,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
|
||||
private void restoreOpState() {
|
||||
player.setOp(limbo.getOperator());
|
||||
player.setOp(limbo.isOperator());
|
||||
}
|
||||
|
||||
private void packQuitLocation() {
|
||||
|
@ -6,22 +6,22 @@ import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.Utils.GroupType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AsynchronousLogout {
|
||||
public class AsynchronousLogout implements Process {
|
||||
|
||||
protected final Player player;
|
||||
protected final String name;
|
||||
protected final AuthMe plugin;
|
||||
protected final DataSource database;
|
||||
protected boolean canLogout = true;
|
||||
private final Messages m;
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private boolean canLogout = true;
|
||||
private final ProcessService service;
|
||||
|
||||
/**
|
||||
* Constructor for AsynchronousLogout.
|
||||
@ -29,29 +29,30 @@ public class AsynchronousLogout {
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param database DataSource
|
||||
* @param service The process service
|
||||
*/
|
||||
public AsynchronousLogout(Player player, AuthMe plugin, DataSource database) {
|
||||
this.m = plugin.getMessages();
|
||||
public AsynchronousLogout(Player player, AuthMe plugin, DataSource database, ProcessService service) {
|
||||
this.player = player;
|
||||
this.plugin = plugin;
|
||||
this.database = database;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private void preLogout() {
|
||||
if (!PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
m.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
service.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
canLogout = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
preLogout();
|
||||
if (!canLogout) {
|
||||
return;
|
||||
}
|
||||
final Player p = player;
|
||||
BukkitScheduler scheduler = p.getServer().getScheduler();
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
|
||||
database.updateSession(auth);
|
||||
auth.setQuitLocX(p.getLocation().getX());
|
||||
@ -62,7 +63,7 @@ public class AsynchronousLogout {
|
||||
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
database.setUnlogged(name);
|
||||
scheduler.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
service.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Utils.teleportToSpawn(p);
|
||||
@ -73,6 +74,6 @@ public class AsynchronousLogout {
|
||||
}
|
||||
LimboCache.getInstance().addLimboPlayer(player);
|
||||
Utils.setGroup(player, GroupType.NOTLOGGEDIN);
|
||||
scheduler.scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerLogout(p, plugin));
|
||||
service.scheduleSyncDelayedTask(new ProcessSynchronousPlayerLogout(p, plugin, service));
|
||||
}
|
||||
}
|
||||
|
@ -7,37 +7,40 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.events.LogoutEvent;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import org.bukkit.Bukkit;
|
||||
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 ProcessSyncronousPlayerLogout implements Runnable {
|
||||
public class ProcessSynchronousPlayerLogout implements Process {
|
||||
|
||||
protected final Player player;
|
||||
protected final AuthMe plugin;
|
||||
protected final String name;
|
||||
private final Messages m;
|
||||
private final Player player;
|
||||
private final AuthMe plugin;
|
||||
private final String name;
|
||||
private final ProcessService service;
|
||||
|
||||
/**
|
||||
* Constructor for ProcessSyncronousPlayerLogout.
|
||||
* Constructor for ProcessSynchronousPlayerLogout.
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param service The process service
|
||||
*/
|
||||
public ProcessSyncronousPlayerLogout(Player player, AuthMe plugin) {
|
||||
this.m = plugin.getMessages();
|
||||
public ProcessSynchronousPlayerLogout(Player player, AuthMe plugin, ProcessService service) {
|
||||
this.player = player;
|
||||
this.plugin = plugin;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
protected void sendBungeeMessage() {
|
||||
@ -56,11 +59,6 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
if (plugin.sessions.containsKey(name)) {
|
||||
@ -70,19 +68,18 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
|
||||
if (Settings.protectInventoryBeforeLogInEnabled) {
|
||||
plugin.inventoryProtector.sendBlankInventoryPacket(player);
|
||||
}
|
||||
int timeOut = Settings.getRegistrationTimeout * 20;
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler sched = player.getServer().getScheduler();
|
||||
int timeOut = service.getProperty(RestrictionSettings.TIMEOUT) * 20;
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
|
||||
BukkitTask id = service.runTaskLater(new TimeoutTask(plugin, name, player), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTask(id);
|
||||
}
|
||||
BukkitTask msgT = sched.runTask(plugin, new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
|
||||
BukkitTask msgT = service.runTask(new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTask(msgT);
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null) {
|
||||
player.getVehicle().eject();
|
||||
}
|
||||
if (Settings.applyBlindEffect) {
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
}
|
||||
player.setOp(false);
|
||||
@ -92,7 +89,7 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
|
||||
if (Settings.bungee) {
|
||||
sendBungeeMessage();
|
||||
}
|
||||
m.send(player, MessageKey.LOGOUT_SUCCESS);
|
||||
service.send(player, MessageKey.LOGOUT_SUCCESS);
|
||||
ConsoleLogger.info(player.getName() + " logged out");
|
||||
}
|
||||
|
@ -7,15 +7,17 @@ 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.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
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 {
|
||||
public class AsynchronousQuit implements Process {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
@ -23,33 +25,40 @@ public class AsynchronousQuit {
|
||||
private final String name;
|
||||
private boolean isOp = false;
|
||||
private boolean needToChange = false;
|
||||
private boolean isKick = false;
|
||||
private final boolean isKick;
|
||||
private final ProcessService service;
|
||||
|
||||
public AsynchronousQuit(Player p, AuthMe plugin, DataSource database,
|
||||
boolean isKick) {
|
||||
public AsynchronousQuit(Player p, AuthMe plugin, DataSource database, boolean isKick, ProcessService service) {
|
||||
this.player = p;
|
||||
this.plugin = plugin;
|
||||
this.database = database;
|
||||
this.name = p.getName().toLowerCase();
|
||||
this.isKick = isKick;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (player == null || Utils.isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String ip = plugin.getIP(player);
|
||||
String ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
if (Settings.isSaveQuitLocationEnabled) {
|
||||
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||
Location loc = player.getLocation();
|
||||
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());
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.realName(player.getName())
|
||||
.ip(ip)
|
||||
.lastLogin(System.currentTimeMillis())
|
||||
.build();
|
||||
database.updateSession(auth);
|
||||
}
|
||||
|
||||
@ -59,7 +68,7 @@ public class AsynchronousQuit {
|
||||
Utils.addNormal(player, limbo.getGroup());
|
||||
}
|
||||
needToChange = true;
|
||||
isOp = limbo.getOperator();
|
||||
isOp = limbo.isOperator();
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
}
|
||||
if (Settings.isSessionsEnabled && !isKick) {
|
||||
@ -76,7 +85,7 @@ public class AsynchronousQuit {
|
||||
|
||||
plugin.sessions.put(name, task);
|
||||
} else {
|
||||
//plugin is disable we canno schedule more tasks so run it directly here
|
||||
//plugin is disabled; we cannot schedule more tasks so run it directly here
|
||||
postLogout();
|
||||
}
|
||||
}
|
||||
@ -85,9 +94,9 @@ public class AsynchronousQuit {
|
||||
database.setUnlogged(name);
|
||||
}
|
||||
|
||||
plugin.realIp.remove(name);
|
||||
service.getIpAddressManager().removeCache(player.getName());
|
||||
if (plugin.isEnabled()) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, player, isOp, needToChange));
|
||||
service.scheduleSyncDelayedTask(new ProcessSyncronousPlayerQuit(plugin, player, isOp, needToChange));
|
||||
}
|
||||
// remove player from cache
|
||||
if (database instanceof CacheDataSource) {
|
||||
|
@ -5,20 +5,23 @@ 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.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.TwoFactor;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AsyncRegister {
|
||||
public class AsyncRegister implements Process {
|
||||
|
||||
private final Player player;
|
||||
private final String name;
|
||||
@ -27,65 +30,68 @@ public class AsyncRegister {
|
||||
private final String email;
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private final Messages m;
|
||||
private final NewSetting settings;
|
||||
private final ProcessService service;
|
||||
|
||||
public AsyncRegister(Player player, String password, String email, AuthMe plugin, DataSource data,
|
||||
NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
ProcessService service) {
|
||||
this.player = player;
|
||||
this.password = password;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.email = email;
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.ip = plugin.getIP(player);
|
||||
this.settings = settings;
|
||||
this.ip = service.getIpAddressManager().getPlayerIp(player);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private boolean preRegisterCheck() {
|
||||
String passLow = password.toLowerCase();
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return false;
|
||||
} else if (!Settings.isRegistrationEnabled) {
|
||||
m.send(player, MessageKey.REGISTRATION_DISABLED);
|
||||
service.send(player, MessageKey.REGISTRATION_DISABLED);
|
||||
return false;
|
||||
}
|
||||
|
||||
//check the password safety only if it's not a automatically generated password
|
||||
if (Settings.getPasswordHash != HashAlgorithm.TWO_FACTOR) {
|
||||
if (service.getProperty(SecuritySettings.PASSWORD_HASH) != HashAlgorithm.TWO_FACTOR) {
|
||||
if (!passLow.matches(Settings.getPassRegex)) {
|
||||
m.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
service.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
return false;
|
||||
} else if (passLow.equalsIgnoreCase(player.getName())) {
|
||||
m.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
service.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
|
||||
return false;
|
||||
} else if (password.length() < Settings.getPasswordMinLen || password.length() > Settings.passwordMaxLength) {
|
||||
m.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
service.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
|
||||
return false;
|
||||
} else if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(password.toLowerCase())) {
|
||||
m.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
service.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//check this in both possiblities so don't use 'else if'
|
||||
//check this in both possibilities so don't use 'else if'
|
||||
if (database.isAuthAvailable(name)) {
|
||||
m.send(player, MessageKey.NAME_ALREADY_REGISTERED);
|
||||
service.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)) {
|
||||
int maxReg = Settings.getmaxRegPerIp;
|
||||
List<String> otherAccounts = database.getAllAuthsByIp(ip);
|
||||
if (otherAccounts.size() >= maxReg) {
|
||||
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxReg),
|
||||
Integer.toString(otherAccounts.size()), StringUtils.join(", ", otherAccounts.toString()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (preRegisterCheck()) {
|
||||
if (!StringUtils.isEmpty(email)) {
|
||||
emailRegister();
|
||||
@ -97,12 +103,17 @@ 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;
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) {
|
||||
int maxReg = Settings.getmaxRegPerEmail;
|
||||
int otherAccounts = database.countAuthsByEmail(email);
|
||||
if (otherAccounts >= maxReg) {
|
||||
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxReg),
|
||||
Integer.toString(otherAccounts), "@");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final HashedPassword hashedPassword = plugin.getPasswordSecurity().computeHash(password, name);
|
||||
|
||||
final HashedPassword hashedPassword = service.computeHash(password, name);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.realName(player.getName())
|
||||
@ -113,19 +124,19 @@ public class AsyncRegister {
|
||||
.build();
|
||||
|
||||
if (!database.saveAuth(auth)) {
|
||||
m.send(player, MessageKey.ERROR);
|
||||
service.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
database.updateEmail(auth);
|
||||
database.updateSession(auth);
|
||||
plugin.mail.main(auth, password);
|
||||
ProcessSyncEmailRegister sync = new ProcessSyncEmailRegister(player, plugin);
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, sync);
|
||||
ProcessSyncEmailRegister sync = new ProcessSyncEmailRegister(player, service);
|
||||
service.scheduleSyncDelayedTask(sync);
|
||||
|
||||
}
|
||||
|
||||
private void passwordRegister() {
|
||||
final HashedPassword hashedPassword = plugin.getPasswordSecurity().computeHash(password, name);
|
||||
final HashedPassword hashedPassword = service.computeHash(password, name);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.realName(player.getName())
|
||||
@ -135,7 +146,7 @@ public class AsyncRegister {
|
||||
.build();
|
||||
|
||||
if (!database.saveAuth(auth)) {
|
||||
m.send(player, MessageKey.ERROR);
|
||||
service.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,14 +157,13 @@ 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);
|
||||
ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin, service);
|
||||
service.scheduleSyncDelayedTask(sync);
|
||||
|
||||
//give the user the secret code to setup their app code generation
|
||||
if (Settings.getPasswordHash == HashAlgorithm.TWO_FACTOR) {
|
||||
if (service.getProperty(SecuritySettings.PASSWORD_HASH) == HashAlgorithm.TWO_FACTOR) {
|
||||
String qrCodeUrl = TwoFactor.getQRBarcodeURL(player.getName(), Bukkit.getIp(), hashedPassword.getHash());
|
||||
m.send(player, MessageKey.TWO_FACTOR_CREATE, hashedPassword.getHash(), qrCodeUrl);
|
||||
service.send(player, MessageKey.TWO_FACTOR_CREATE, hashedPassword.getHash(), qrCodeUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,64 @@
|
||||
package fr.xephi.authme.process.register;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ProcessSyncEmailRegister implements Runnable {
|
||||
public class ProcessSyncEmailRegister implements Process {
|
||||
|
||||
protected final Player player;
|
||||
protected final String name;
|
||||
private final AuthMe plugin;
|
||||
private final Messages m;
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private final ProcessService service;
|
||||
|
||||
/**
|
||||
* Constructor for ProcessSyncEmailRegister.
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param player The player to process an email registration for
|
||||
* @param service The process service
|
||||
*/
|
||||
public ProcessSyncEmailRegister(Player player, AuthMe plugin) {
|
||||
this.m = plugin.getMessages();
|
||||
public ProcessSyncEmailRegister(Player player, ProcessService service) {
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.plugin = plugin;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (!Settings.getRegisteredGroup.isEmpty()) {
|
||||
Utils.setGroup(player, Utils.GroupType.REGISTERED);
|
||||
}
|
||||
m.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
|
||||
int time = Settings.getRegistrationTimeout * 20;
|
||||
int msgInterval = Settings.getWarnMessageInterval;
|
||||
|
||||
BukkitScheduler sched = plugin.getServer().getScheduler();
|
||||
service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
|
||||
int time = service.getProperty(RestrictionSettings.TIMEOUT) * 20;
|
||||
int msgInterval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
|
||||
if (limbo != null) {
|
||||
if (time != 0) {
|
||||
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), time);
|
||||
limbo.setTimeoutTaskId(id);
|
||||
BukkitTask id = service.runTaskLater(new TimeoutTask(service.getAuthMe(), name, player), time);
|
||||
limbo.setTimeoutTask(id);
|
||||
}
|
||||
BukkitTask nwMsg = sched.runTask(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), msgInterval));
|
||||
limbo.setMessageTaskId(nwMsg);
|
||||
BukkitTask messageTask = service.runTask(new MessageTask(
|
||||
service.getAuthMe(), name, service.retrieveMessage(MessageKey.LOGIN_MESSAGE), msgInterval));
|
||||
limbo.setMessageTask(messageTask);
|
||||
}
|
||||
|
||||
player.saveData();
|
||||
if (!Settings.noConsoleSpam) {
|
||||
ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player));
|
||||
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info(player.getName() + " registered " + service.getIpAddressManager().getPlayerIp(player));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,42 +9,34 @@ import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
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.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.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;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ProcessSyncPasswordRegister implements Runnable {
|
||||
public class ProcessSyncPasswordRegister implements Process {
|
||||
|
||||
protected final Player player;
|
||||
protected final String name;
|
||||
private final AuthMe plugin;
|
||||
private final Messages m;
|
||||
private final NewSetting settings;
|
||||
private final ProcessService service;
|
||||
|
||||
/**
|
||||
* Constructor for ProcessSyncPasswordRegister.
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public ProcessSyncPasswordRegister(Player player, AuthMe plugin, NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
public ProcessSyncPasswordRegister(Player player, AuthMe plugin, ProcessService service) {
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private void sendBungeeMessage() {
|
||||
@ -70,16 +62,15 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
Utils.teleportToSpawn(player);
|
||||
LimboCache cache = LimboCache.getInstance();
|
||||
cache.updateLimboPlayer(player);
|
||||
int delay = Settings.getRegistrationTimeout * 20;
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler sched = plugin.getServer().getScheduler();
|
||||
int delay = service.getProperty(RestrictionSettings.TIMEOUT) * 20;
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
BukkitTask task;
|
||||
if (delay != 0) {
|
||||
task = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), delay);
|
||||
cache.getLimboPlayer(name).setTimeoutTaskId(task);
|
||||
task = service.runTaskLater(new TimeoutTask(service.getAuthMe(), name, player), delay);
|
||||
cache.getLimboPlayer(name).setTimeoutTask(task);
|
||||
}
|
||||
task = sched.runTask(plugin, new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
cache.getLimboPlayer(name).setMessageTaskId(task);
|
||||
task = service.runTask(new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval));
|
||||
cache.getLimboPlayer(name).setMessageTask(task);
|
||||
if (player.isInsideVehicle() && player.getVehicle() != null) {
|
||||
player.getVehicle().eject();
|
||||
}
|
||||
@ -106,13 +97,13 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
Utils.setGroup(player, Utils.GroupType.REGISTERED);
|
||||
}
|
||||
|
||||
m.send(player, MessageKey.REGISTER_SUCCESS);
|
||||
service.send(player, MessageKey.REGISTER_SUCCESS);
|
||||
|
||||
if (!Settings.getmailAccount.isEmpty()) {
|
||||
m.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
|
||||
if (Settings.applyBlindEffect) {
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
player.removePotionEffect(PotionEffectType.BLINDNESS);
|
||||
}
|
||||
|
||||
@ -121,23 +112,23 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
player.saveData();
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player));
|
||||
ConsoleLogger.info(player.getName() + " registered " + service.getIpAddressManager().getPlayerIp(player));
|
||||
}
|
||||
|
||||
// Kick Player after Registration is enabled, kick the player
|
||||
if (Settings.forceRegKick) {
|
||||
player.kickPlayer(m.retrieveSingle(MessageKey.REGISTER_SUCCESS));
|
||||
player.kickPlayer(service.retrieveSingleMessage(MessageKey.REGISTER_SUCCESS));
|
||||
return;
|
||||
}
|
||||
|
||||
// Register is finish and player is logged, display welcome message
|
||||
if (Settings.useWelcomeMessage) {
|
||||
if (Settings.broadcastWelcomeMessage) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
if (service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
|
||||
if (service.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) {
|
||||
for (String s : service.getSettings().getWelcomeMessage()) {
|
||||
plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
} else {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
for (String s : service.getSettings().getWelcomeMessage()) {
|
||||
player.sendMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
}
|
||||
@ -160,10 +151,10 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
}
|
||||
|
||||
private void sendTo() {
|
||||
if (!settings.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
|
||||
if (!service.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(settings.getProperty(HooksSettings.BUNGEECORD_SERVER));
|
||||
out.writeUTF(service.getProperty(HooksSettings.BUNGEECORD_SERVER));
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,11 @@ import fr.xephi.authme.cache.backup.JsonCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.process.Process;
|
||||
import fr.xephi.authme.process.ProcessService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
@ -20,47 +23,46 @@ import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class AsynchronousUnregister {
|
||||
public class AsynchronousUnregister implements Process {
|
||||
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private final String password;
|
||||
private final boolean force;
|
||||
private final AuthMe plugin;
|
||||
private final Messages m;
|
||||
private final JsonCache playerCache;
|
||||
private final ProcessService service;
|
||||
|
||||
/**
|
||||
* Constructor for AsynchronousUnregister.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param password String
|
||||
* @param force boolean
|
||||
* @param plugin AuthMe
|
||||
* @param player The player to perform the action for
|
||||
* @param password The password
|
||||
* @param force True to bypass password validation
|
||||
* @param plugin The plugin instance
|
||||
* @param service The process service
|
||||
*/
|
||||
public AsynchronousUnregister(Player player, String password, boolean force, AuthMe plugin) {
|
||||
this.m = plugin.getMessages();
|
||||
public AsynchronousUnregister(Player player, String password, boolean force, AuthMe plugin,
|
||||
ProcessService service) {
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.password = password;
|
||||
this.force = force;
|
||||
this.plugin = plugin;
|
||||
this.playerCache = new JsonCache();
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
protected String getIp() {
|
||||
return plugin.getIP(player);
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth cachedAuth = PlayerCache.getInstance().getAuth(name);
|
||||
if (force || plugin.getPasswordSecurity().comparePassword(
|
||||
password, cachedAuth.getPassword(), player.getName())) {
|
||||
if (!plugin.getDataSource().removeAuth(name)) {
|
||||
m.send(player, MessageKey.ERROR);
|
||||
if (!service.getDataSource().removeAuth(name)) {
|
||||
service.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
int timeOut = Settings.getRegistrationTimeout * 20;
|
||||
int timeOut = service.getProperty(RestrictionSettings.TIMEOUT) * 20;
|
||||
if (Settings.isForcedRegistrationEnabled) {
|
||||
Utils.teleportToSpawn(player);
|
||||
player.saveData();
|
||||
@ -70,15 +72,15 @@ public class AsynchronousUnregister {
|
||||
}
|
||||
LimboCache.getInstance().addLimboPlayer(player);
|
||||
LimboPlayer limboPlayer = LimboCache.getInstance().getLimboPlayer(name);
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
BukkitScheduler scheduler = plugin.getServer().getScheduler();
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut);
|
||||
limboPlayer.setTimeoutTaskId(id);
|
||||
limboPlayer.setTimeoutTask(id);
|
||||
}
|
||||
limboPlayer.setMessageTaskId(scheduler.runTask(plugin,
|
||||
limboPlayer.setMessageTask(scheduler.runTask(plugin,
|
||||
new MessageTask(plugin, name, MessageKey.REGISTER_MESSAGE, interval)));
|
||||
m.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
return;
|
||||
}
|
||||
@ -92,14 +94,14 @@ public class AsynchronousUnregister {
|
||||
playerCache.removeCache(player);
|
||||
}
|
||||
// Apply blind effect
|
||||
if (Settings.applyBlindEffect) {
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
}
|
||||
m.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
Utils.teleportToSpawn(player);
|
||||
} else {
|
||||
m.send(player, MessageKey.WRONG_PASSWORD);
|
||||
service.send(player, MessageKey.WRONG_PASSWORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
/**
|
||||
@ -11,17 +13,16 @@ import org.bukkit.plugin.PluginManager;
|
||||
*/
|
||||
public class PasswordSecurity {
|
||||
|
||||
private HashAlgorithm algorithm;
|
||||
private boolean supportOldAlgorithm;
|
||||
private final DataSource dataSource;
|
||||
private final HashAlgorithm algorithm;
|
||||
private final PluginManager pluginManager;
|
||||
private final boolean supportOldAlgorithm;
|
||||
|
||||
public PasswordSecurity(DataSource dataSource, HashAlgorithm algorithm,
|
||||
PluginManager pluginManager, boolean supportOldAlgorithm) {
|
||||
public PasswordSecurity(DataSource dataSource, NewSetting settings, PluginManager pluginManager) {
|
||||
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||
this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH);
|
||||
this.dataSource = dataSource;
|
||||
this.algorithm = algorithm;
|
||||
this.pluginManager = pluginManager;
|
||||
this.supportOldAlgorithm = supportOldAlgorithm;
|
||||
}
|
||||
|
||||
public HashedPassword computeHash(String password, String playerName) {
|
||||
@ -46,6 +47,11 @@ public class PasswordSecurity {
|
||||
|| supportOldAlgorithm && compareWithAllEncryptionMethods(password, hashedPassword, playerLowerCase);
|
||||
}
|
||||
|
||||
public void reload(NewSetting settings) {
|
||||
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||
this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the given hash with all available encryption methods to support
|
||||
* the migration to a new encryption method. Upon a successful match, the password
|
||||
|
@ -106,8 +106,9 @@ public class BinTools {
|
||||
throw new IllegalArgumentException("Input string may only contain hex digits, but found '" + c + "'");
|
||||
}
|
||||
|
||||
// TODO ljacqu 20151219: Move to a BinToolsTest class
|
||||
private static void testUtils(String[] args) {
|
||||
// Note ljacqu 20160313: This appears to be a test method that was present in the third-party source.
|
||||
// We can keep it for troubleshooting in the future.
|
||||
private static void testUtils() {
|
||||
byte b[] = new byte[256];
|
||||
byte bb = 0;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
|
@ -1,94 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
/**
|
||||
*/
|
||||
public abstract class CustomConfiguration extends YamlConfiguration {
|
||||
|
||||
private final File configFile;
|
||||
|
||||
/**
|
||||
* Constructor for CustomConfiguration.
|
||||
*
|
||||
* @param file the config file
|
||||
*/
|
||||
public CustomConfiguration(File file) {
|
||||
this.configFile = file;
|
||||
load();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
try {
|
||||
super.load(configFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
ConsoleLogger.showError("Could not find " + configFile.getName() + ", creating new one...");
|
||||
reLoad();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError("Could not load " + configFile.getName());
|
||||
} catch (InvalidConfigurationException e) {
|
||||
ConsoleLogger.showError(configFile.getName() + " is no valid configuration file");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean reLoad() {
|
||||
boolean out = true;
|
||||
if (!configFile.exists()) {
|
||||
out = loadResource(configFile);
|
||||
}
|
||||
if (out)
|
||||
load();
|
||||
return out;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
super.save(configFile);
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError("Could not save config to " + configFile.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public File getConfigFile() {
|
||||
return configFile;
|
||||
}
|
||||
|
||||
private boolean loadResource(File file) {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
|
||||
return false;
|
||||
}
|
||||
int i = file.getPath().indexOf("AuthMe");
|
||||
if (i > -1) {
|
||||
String path = file.getPath().substring(i + 6).replace('\\', '/');
|
||||
InputStream is = AuthMe.class.getResourceAsStream(path);
|
||||
Files.copy(is, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.logException("Failed to load config from JAR", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsAll(String... paths) {
|
||||
for (String path : paths) {
|
||||
if (!contains(path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
@ -24,7 +23,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static fr.xephi.authme.settings.SettingsMigrationService.copyFileFromResource;
|
||||
import static fr.xephi.authme.util.FileUtils.copyFileFromResource;
|
||||
|
||||
/**
|
||||
* The new settings manager.
|
||||
@ -33,6 +32,8 @@ public class NewSetting {
|
||||
|
||||
private final File pluginFolder;
|
||||
private final File configFile;
|
||||
private final PropertyMap propertyMap;
|
||||
private final SettingsMigrationService migrationService;
|
||||
private FileConfiguration configuration;
|
||||
/** The file with the localized messages based on {@link PluginSettings#MESSAGES_LANGUAGE}. */
|
||||
private File messagesFile;
|
||||
@ -44,11 +45,16 @@ public class NewSetting {
|
||||
*
|
||||
* @param configFile The configuration file
|
||||
* @param pluginFolder The AuthMe plugin folder
|
||||
* @param propertyMap Collection of all available settings
|
||||
* @param migrationService Migration service to check the settings file with
|
||||
*/
|
||||
public NewSetting(File configFile, File pluginFolder) {
|
||||
public NewSetting(File configFile, File pluginFolder, PropertyMap propertyMap,
|
||||
SettingsMigrationService migrationService) {
|
||||
this.configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
this.configFile = configFile;
|
||||
this.pluginFolder = pluginFolder;
|
||||
this.propertyMap = propertyMap;
|
||||
this.migrationService = migrationService;
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
|
||||
@ -57,16 +63,21 @@ public class NewSetting {
|
||||
*
|
||||
* @param configuration The FileConfiguration object to use
|
||||
* @param configFile The file to write to
|
||||
* @param pluginFolder The plugin folder
|
||||
* @param propertyMap The property map whose properties should be verified for presence, or null to skip this
|
||||
* @param migrationService Migration service, or null to skip migration checks
|
||||
*/
|
||||
@VisibleForTesting
|
||||
NewSetting(FileConfiguration configuration, File configFile, PropertyMap propertyMap) {
|
||||
NewSetting(FileConfiguration configuration, File configFile, File pluginFolder, PropertyMap propertyMap,
|
||||
SettingsMigrationService migrationService) {
|
||||
this.configuration = configuration;
|
||||
this.configFile = configFile;
|
||||
this.pluginFolder = new File("");
|
||||
this.pluginFolder = pluginFolder;
|
||||
this.propertyMap = propertyMap;
|
||||
this.migrationService = migrationService;
|
||||
|
||||
if (propertyMap != null && SettingsMigrationService.checkAndMigrate(configuration, propertyMap, pluginFolder)) {
|
||||
save(propertyMap);
|
||||
if (propertyMap != null && migrationService != null) {
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,13 +103,6 @@ public class NewSetting {
|
||||
configuration.set(property.getPath(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the config file. Use after migrating one or more settings.
|
||||
*/
|
||||
public void save() {
|
||||
save(SettingsFieldRetriever.getAllPropertyFields());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the messages file based on the messages language config.
|
||||
*
|
||||
@ -133,7 +137,10 @@ public class NewSetting {
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
|
||||
private void save(PropertyMap propertyMap) {
|
||||
/**
|
||||
* Save the config file. Use after migrating one or more settings.
|
||||
*/
|
||||
public void save() {
|
||||
try (FileWriter writer = new FileWriter(configFile)) {
|
||||
Yaml simpleYaml = newYaml(false);
|
||||
Yaml singleQuoteYaml = newYaml(true);
|
||||
@ -186,11 +193,10 @@ public class NewSetting {
|
||||
}
|
||||
|
||||
private void validateAndLoadOptions() {
|
||||
PropertyMap propertyMap = SettingsFieldRetriever.getAllPropertyFields();
|
||||
if (SettingsMigrationService.checkAndMigrate(configuration, propertyMap, pluginFolder)) {
|
||||
if (migrationService.checkAndMigrate(configuration, propertyMap, pluginFolder)) {
|
||||
ConsoleLogger.info("Merged new config options");
|
||||
ConsoleLogger.info("Please check your config.yml file for new settings!");
|
||||
save(propertyMap);
|
||||
save();
|
||||
}
|
||||
|
||||
messagesFile = buildMessagesFile();
|
||||
@ -205,18 +211,20 @@ public class NewSetting {
|
||||
|
||||
private File buildMessagesFile() {
|
||||
String languageCode = getProperty(PluginSettings.MESSAGES_LANGUAGE);
|
||||
File messagesFile = buildMessagesFileFromCode(languageCode);
|
||||
if (messagesFile.exists()) {
|
||||
|
||||
String filePath = buildMessagesFilePathFromCode(languageCode);
|
||||
File messagesFile = new File(pluginFolder, filePath);
|
||||
if (copyFileFromResource(messagesFile, filePath)) {
|
||||
return messagesFile;
|
||||
}
|
||||
|
||||
return copyFileFromResource(messagesFile, buildMessagesFilePathFromCode(languageCode))
|
||||
? messagesFile
|
||||
: buildMessagesFileFromCode("en");
|
||||
}
|
||||
// File doesn't exist or couldn't be copied - try again with default, "en"
|
||||
String defaultFilePath = buildMessagesFilePathFromCode("en");
|
||||
File defaultFile = new File(pluginFolder, defaultFilePath);
|
||||
copyFileFromResource(defaultFile, defaultFilePath);
|
||||
|
||||
private File buildMessagesFileFromCode(String language) {
|
||||
return new File(pluginFolder, buildMessagesFilePathFromCode(language));
|
||||
// No matter the result, need to return a file
|
||||
return defaultFile;
|
||||
}
|
||||
|
||||
private static String buildMessagesFilePathFromCode(String language) {
|
||||
@ -243,7 +251,7 @@ public class NewSetting {
|
||||
final Charset charset = Charset.forName("UTF-8");
|
||||
if (copyFileFromResource(emailFile, "email.html")) {
|
||||
try {
|
||||
return StringUtils.join("", Files.readLines(emailFile, charset));
|
||||
return StringUtils.join("\n", Files.readLines(emailFile, charset));
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Failed to read file '" + emailFile.getPath() + "':", e);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
@ -41,13 +39,9 @@ public final class Settings {
|
||||
public static List<String> forceRegisterCommands;
|
||||
public static List<String> forceRegisterCommandsAsConsole;
|
||||
public static List<String> unsafePasswords;
|
||||
public static List<String> emailBlacklist;
|
||||
public static List<String> emailWhitelist;
|
||||
public static DataSourceType getDataSource;
|
||||
public static HashAlgorithm getPasswordHash;
|
||||
public static Pattern nickPattern;
|
||||
public static boolean useLogging = false;
|
||||
public static int purgeDelay = 60;
|
||||
public static boolean isChatAllowed, isPermissionCheckEnabled, isRegistrationEnabled,
|
||||
isForcedRegistrationEnabled, isTeleportToSpawnEnabled,
|
||||
isSessionsEnabled, isAllowRestrictedIp,
|
||||
@ -57,34 +51,27 @@ public final class Settings {
|
||||
isKickOnWrongPasswordEnabled, enablePasswordConfirmation,
|
||||
protectInventoryBeforeLogInEnabled, isStopEnabled, reloadSupport,
|
||||
rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts,
|
||||
useCaptcha, emailRegistration, multiverse, bungee,
|
||||
emailRegistration, multiverse, bungee,
|
||||
banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange,
|
||||
disableSocialSpy, useEssentialsMotd, usePurge,
|
||||
purgePlayerDat, purgeEssentialsFile, supportOldPassword,
|
||||
purgeLimitedCreative, purgeAntiXray, purgePermissions,
|
||||
enableProtection, enableAntiBot, recallEmail, useWelcomeMessage,
|
||||
disableSocialSpy, useEssentialsMotd,
|
||||
enableProtection, recallEmail, useWelcomeMessage,
|
||||
broadcastWelcomeMessage, forceRegKick, forceRegLogin,
|
||||
checkVeryGames, removeJoinMessage, removeLeaveMessage, delayJoinMessage,
|
||||
noTeleport, applyBlindEffect, hideTablistBeforeLogin, denyTabcompleteBeforeLogin,
|
||||
noTeleport, hideTablistBeforeLogin, denyTabcompleteBeforeLogin,
|
||||
kickPlayersBeforeStopping, allowAllCommandsIfRegIsOptional,
|
||||
customAttributes, generateImage, isRemoveSpeedEnabled, preventOtherCase;
|
||||
customAttributes, isRemoveSpeedEnabled, preventOtherCase;
|
||||
public static String getNickRegex, getUnloggedinGroup,
|
||||
getMySQLColumnGroup, unRegisteredGroup,
|
||||
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,
|
||||
antiBotSensibility, antiBotDuration, delayRecall, getMaxLoginPerIp,
|
||||
getMaxJoinPerIp;
|
||||
getmaxRegPerEmail, bCryptLog2Rounds, getMaxLoginPerIp, getMaxJoinPerIp;
|
||||
protected static FileConfiguration configFile;
|
||||
private static AuthMe plugin;
|
||||
private static Settings instance;
|
||||
|
||||
/**
|
||||
* Constructor for Settings.
|
||||
@ -92,29 +79,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);
|
||||
@ -128,8 +113,6 @@ public final class Settings {
|
||||
getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp", 1);
|
||||
getPasswordHash = load(SecuritySettings.PASSWORD_HASH);
|
||||
getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP);
|
||||
getDataSource = load(DatabaseSettings.BACKEND);
|
||||
getMySQLColumnGroup = configFile.getString("ExternalBoardOptions.mySQLColumnGroup", "");
|
||||
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
|
||||
unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup", "");
|
||||
|
||||
@ -163,16 +146,15 @@ public final class Settings {
|
||||
rakamakUsers = configFile.getString("Converter.Rakamak.fileName", "users.rak");
|
||||
rakamakUsersIp = configFile.getString("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
rakamakUseIp = configFile.getBoolean("Converter.Rakamak.useIp", false);
|
||||
noConsoleSpam = configFile.getBoolean("Security.console.noConsoleSpam", false);
|
||||
noConsoleSpam = load(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE);
|
||||
removePassword = configFile.getBoolean("Security.console.removePassword", true);
|
||||
getmailAccount = configFile.getString("Email.mailAccount", "");
|
||||
getMailPort = configFile.getInt("Email.mailPort", 465);
|
||||
getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
|
||||
displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
|
||||
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);
|
||||
@ -185,50 +167,31 @@ public final class Settings {
|
||||
disableSocialSpy = configFile.getBoolean("Hooks.disableSocialSpy", true);
|
||||
bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10);
|
||||
useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false);
|
||||
usePurge = configFile.getBoolean("Purge.useAutoPurge", false);
|
||||
purgeDelay = configFile.getInt("Purge.daysBeforeRemovePlayer", 60);
|
||||
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);
|
||||
enableProtection = configFile.getBoolean("Protection.enableProtection", false);
|
||||
countries = configFile.getStringList("Protection.countries");
|
||||
enableAntiBot = configFile.getBoolean("Protection.enableAntiBot", false);
|
||||
antiBotSensibility = configFile.getInt("Protection.antiBotSensibility", 5);
|
||||
antiBotDuration = configFile.getInt("Protection.antiBotDuration", 10);
|
||||
forceCommands = configFile.getStringList("settings.forceCommands");
|
||||
forceCommandsAsConsole = configFile.getStringList("settings.forceCommandsAsConsole");
|
||||
recallEmail = configFile.getBoolean("Email.recallPlayers", false);
|
||||
delayRecall = configFile.getInt("Email.delayRecall", 5);
|
||||
useWelcomeMessage = configFile.getBoolean("settings.useWelcomeMessage", true);
|
||||
useWelcomeMessage = load(RegistrationSettings.USE_WELCOME_MESSAGE);
|
||||
unsafePasswords = configFile.getStringList("settings.security.unsafePasswords");
|
||||
countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist");
|
||||
broadcastWelcomeMessage = configFile.getBoolean("settings.broadcastWelcomeMessage", false);
|
||||
broadcastWelcomeMessage = load(RegistrationSettings.BROADCAST_WELCOME_MESSAGE);
|
||||
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);
|
||||
emailBlacklist = configFile.getStringList("Email.emailBlacklisted");
|
||||
emailWhitelist = configFile.getStringList("Email.emailWhitelisted");
|
||||
forceRegisterCommands = configFile.getStringList("settings.forceRegisterCommands");
|
||||
forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole");
|
||||
customAttributes = configFile.getBoolean("Hooks.customAttributes");
|
||||
generateImage = configFile.getBoolean("Email.generateImage", false);
|
||||
preventOtherCase = configFile.getBoolean("settings.preventOtherCase", false);
|
||||
kickPlayersBeforeStopping = configFile.getBoolean("Security.stop.kickPlayersBeforeStopping", true);
|
||||
sendPlayerTo = configFile.getString("Hooks.sendPlayerTo", "");
|
||||
|
@ -1,7 +1,5 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
@ -10,37 +8,32 @@ import org.bukkit.configuration.file.FileConfiguration;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_LEAVE_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS;
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Service for verifying that the configuration is up-to-date.
|
||||
*/
|
||||
public final class SettingsMigrationService {
|
||||
|
||||
private SettingsMigrationService() {
|
||||
}
|
||||
public class SettingsMigrationService {
|
||||
|
||||
/**
|
||||
* Checks the config file and does any necessary migrations.
|
||||
* Checks the config file and performs any necessary migrations.
|
||||
*
|
||||
* @param configuration The file configuration to check and migrate
|
||||
* @param propertyMap The property map of all existing properties
|
||||
* @param pluginFolder The plugin folder
|
||||
* @return True if there is a change and the config must be saved, false if the config is up-to-date
|
||||
*/
|
||||
public static boolean checkAndMigrate(FileConfiguration configuration, PropertyMap propertyMap, File pluginFolder) {
|
||||
return performMigrations(configuration, pluginFolder) || hasDeprecatedProperties(configuration)
|
||||
public boolean checkAndMigrate(FileConfiguration configuration, PropertyMap propertyMap, File pluginFolder) {
|
||||
return performMigrations(configuration, pluginFolder)
|
||||
|| hasDeprecatedProperties(configuration)
|
||||
|| !containsAllSettings(configuration, propertyMap);
|
||||
}
|
||||
|
||||
private static boolean performMigrations(FileConfiguration configuration, File pluginFolder) {
|
||||
private boolean performMigrations(FileConfiguration configuration, File pluginFolder) {
|
||||
boolean changes = false;
|
||||
if ("[a-zA-Z0-9_?]*".equals(configuration.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) {
|
||||
configuration.set(ALLOWED_NICKNAME_CHARACTERS.getPath(), "[a-zA-Z0-9_]*");
|
||||
@ -54,8 +47,7 @@ public final class SettingsMigrationService {
|
||||
| migrateJoinLeaveMessages(configuration);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean containsAllSettings(FileConfiguration configuration, PropertyMap propertyMap) {
|
||||
public boolean containsAllSettings(FileConfiguration configuration, PropertyMap propertyMap) {
|
||||
for (Property<?> property : propertyMap.keySet()) {
|
||||
if (!property.isPresent(configuration)) {
|
||||
return false;
|
||||
@ -84,16 +76,16 @@ public final class SettingsMigrationService {
|
||||
* Check if {@code Email.mailText} is present and move it to the Email.html file if it doesn't exist yet.
|
||||
*
|
||||
* @param configuration The file configuration to verify
|
||||
* @param dataFolder The plugin data folder
|
||||
* @param pluginFolder The plugin data folder
|
||||
* @return True if a migration has been completed, false otherwise
|
||||
*/
|
||||
private static boolean performMailTextToFileMigration(FileConfiguration configuration, File dataFolder) {
|
||||
private static boolean performMailTextToFileMigration(FileConfiguration configuration, File pluginFolder) {
|
||||
final String oldSettingPath = "Email.mailText";
|
||||
if (!configuration.contains(oldSettingPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File emailFile = new File(dataFolder, "email.html");
|
||||
final File emailFile = new File(pluginFolder, "email.html");
|
||||
final String mailText = configuration.getString(oldSettingPath)
|
||||
.replace("<playername>", "<playername />")
|
||||
.replace("<servername>", "<servername />")
|
||||
@ -131,41 +123,4 @@ public final class SettingsMigrationService {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// -------
|
||||
// Utilities
|
||||
// -------
|
||||
|
||||
/**
|
||||
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
|
||||
*
|
||||
* @param destinationFile The file to check and copy to (outside of JAR)
|
||||
* @param resourcePath Absolute path to the resource file (path to file within JAR)
|
||||
* @return False if the file does not exist and could not be copied, true otherwise
|
||||
*/
|
||||
public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
|
||||
if (destinationFile.exists()) {
|
||||
return true;
|
||||
} else if (!destinationFile.getParentFile().exists() && !destinationFile.getParentFile().mkdirs()) {
|
||||
ConsoleLogger.showError("Cannot create parent directories for '" + destinationFile + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
|
||||
final String normalizedPath = resourcePath.replace("\\", "/");
|
||||
try (InputStream is = AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath)) {
|
||||
if (is == null) {
|
||||
ConsoleLogger.showError(format("Cannot copy resource '%s' to file '%s': cannot load resource",
|
||||
resourcePath, destinationFile.getPath()));
|
||||
} else {
|
||||
Files.copy(is, destinationFile.toPath());
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException(format("Cannot copy resource '%s' to file '%s':",
|
||||
resourcePath, destinationFile.getPath()), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,148 +0,0 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class Spawn extends CustomConfiguration {
|
||||
|
||||
private static Spawn spawn;
|
||||
private static String[] spawnPriority;
|
||||
|
||||
private Spawn() {
|
||||
super(new File(Settings.PLUGIN_FOLDER, "spawn.yml"));
|
||||
load();
|
||||
save();
|
||||
spawnPriority = Settings.spawnPriority.split(",");
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
spawn = new Spawn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getInstance.
|
||||
*
|
||||
* @return Spawn
|
||||
*/
|
||||
public static Spawn getInstance() {
|
||||
if (spawn == null) {
|
||||
spawn = new Spawn();
|
||||
}
|
||||
return spawn;
|
||||
}
|
||||
|
||||
public boolean setSpawn(Location location) {
|
||||
if (location == null || location.getWorld() == null) {
|
||||
return false;
|
||||
}
|
||||
set("spawn.world", location.getWorld().getName());
|
||||
set("spawn.x", location.getX());
|
||||
set("spawn.y", location.getY());
|
||||
set("spawn.z", location.getZ());
|
||||
set("spawn.yaw", location.getYaw());
|
||||
set("spawn.pitch", location.getPitch());
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean setFirstSpawn(Location location) {
|
||||
if (location == null || location.getWorld() == null) {
|
||||
return false;
|
||||
}
|
||||
set("firstspawn.world", location.getWorld().getName());
|
||||
set("firstspawn.x", location.getX());
|
||||
set("firstspawn.y", location.getY());
|
||||
set("firstspawn.z", location.getZ());
|
||||
set("firstspawn.yaw", location.getYaw());
|
||||
set("firstspawn.pitch", location.getPitch());
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public Location getSpawn() {
|
||||
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 new Location(
|
||||
world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"),
|
||||
Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch"))
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Location getFirstSpawn() {
|
||||
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 null;
|
||||
}
|
||||
|
||||
// Return the spawn location of a player
|
||||
public Location getSpawnLocation(Player player) {
|
||||
AuthMe plugin = AuthMe.getInstance();
|
||||
if (plugin == null || player == null || player.getWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
World world = player.getWorld();
|
||||
Location spawnLoc = null;
|
||||
for (String priority : spawnPriority) {
|
||||
switch (priority.toLowerCase()) {
|
||||
case "default":
|
||||
if (world.getSpawnLocation() != null) {
|
||||
spawnLoc = world.getSpawnLocation();
|
||||
}
|
||||
break;
|
||||
case "multiverse":
|
||||
if (Settings.multiverse && plugin.multiverse != null) {
|
||||
MVWorldManager manager = plugin.multiverse.getMVWorldManager();
|
||||
if (manager.isMVWorld(world)) {
|
||||
spawnLoc = manager.getMVWorld(world).getSpawnLocation();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "essentials":
|
||||
spawnLoc = plugin.essentialsSpawn;
|
||||
break;
|
||||
case "authme":
|
||||
String playerNameLower = player.getName().toLowerCase();
|
||||
if (PlayerCache.getInstance().isAuthenticated(playerNameLower)) {
|
||||
spawnLoc = getSpawn();
|
||||
} else if ((getFirstSpawn() != null) && (!player.hasPlayedBefore() ||
|
||||
(!plugin.getDataSource().isAuthAvailable(playerNameLower)))) {
|
||||
spawnLoc = getFirstSpawn();
|
||||
} else {
|
||||
spawnLoc = getSpawn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (spawnLoc != null) {
|
||||
return spawnLoc;
|
||||
}
|
||||
}
|
||||
return world.getSpawnLocation(); // return default location
|
||||
}
|
||||
}
|
260
src/main/java/fr/xephi/authme/settings/SpawnLoader.java
Normal file
260
src/main/java/fr/xephi/authme/settings/SpawnLoader.java
Normal file
@ -0,0 +1,260 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Manager for spawn points. It loads spawn definitions from AuthMe and third-party plugins
|
||||
* and is responsible for returning the correct spawn point as per the settings.
|
||||
* <p>
|
||||
* The spawn priority setting defines from which sources and in which order the spawn point
|
||||
* should be taken from. In AuthMe, we can distinguish between the regular spawn and a "first spawn",
|
||||
* to which players will be teleported who have joined for the first time.
|
||||
*/
|
||||
public class SpawnLoader {
|
||||
|
||||
private final File authMeConfigurationFile;
|
||||
private final PluginHooks pluginHooks;
|
||||
private FileConfiguration authMeConfiguration;
|
||||
private String[] spawnPriority;
|
||||
private Location essentialsSpawn;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pluginFolder The AuthMe data folder
|
||||
* @param settings The setting instance
|
||||
* @param pluginHooks The plugin hooks instance
|
||||
*/
|
||||
public SpawnLoader(File pluginFolder, NewSetting settings, PluginHooks pluginHooks) {
|
||||
File spawnFile = new File(pluginFolder, "spawn.yml");
|
||||
// TODO ljacqu 20160312: Check if resource could be copied and handle the case if not
|
||||
FileUtils.copyFileFromResource(spawnFile, "spawn.yml");
|
||||
this.authMeConfigurationFile = new File(pluginFolder, "spawn.yml");
|
||||
this.pluginHooks = pluginHooks;
|
||||
initialize(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the relevant settings and load the AuthMe spawn.yml file.
|
||||
*
|
||||
* @param settings The settings instance
|
||||
*/
|
||||
public void initialize(NewSetting settings) {
|
||||
spawnPriority = settings.getProperty(RestrictionSettings.SPAWN_PRIORITY).split(",");
|
||||
authMeConfiguration = YamlConfiguration.loadConfiguration(authMeConfigurationFile);
|
||||
loadEssentialsSpawn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe spawn location.
|
||||
*
|
||||
* @return The location of the regular AuthMe spawn point
|
||||
*/
|
||||
public Location getSpawn() {
|
||||
return getLocationFromConfiguration(authMeConfiguration, "spawn");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the AuthMe spawn point.
|
||||
*
|
||||
* @param location The location to use
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
public boolean setSpawn(Location location) {
|
||||
return setLocation("spawn", location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe first spawn location.
|
||||
*
|
||||
* @return The location of the AuthMe spawn point for first timers
|
||||
*/
|
||||
public Location getFirstSpawn() {
|
||||
return getLocationFromConfiguration(authMeConfiguration, "firstspawn");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the AuthMe first spawn location.
|
||||
*
|
||||
* @param location The location to use
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
public boolean setFirstSpawn(Location location) {
|
||||
return setLocation("firstspawn", location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the spawn point defined in EssentialsSpawn.
|
||||
*/
|
||||
public void loadEssentialsSpawn() {
|
||||
// EssentialsSpawn cannot run without Essentials, so it's fine to get the Essentials data folder
|
||||
File essentialsFolder = pluginHooks.getEssentialsDataFolder();
|
||||
if (essentialsFolder == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
File essentialsSpawnFile = new File(essentialsFolder, "spawn.yml");
|
||||
if (essentialsSpawnFile.exists()) {
|
||||
essentialsSpawn = getLocationFromConfiguration(
|
||||
YamlConfiguration.loadConfiguration(essentialsSpawnFile), "spawns.default");
|
||||
} else {
|
||||
essentialsSpawn = null;
|
||||
ConsoleLogger.info("Essentials spawn file not found: '" + essentialsSpawnFile.getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the spawn point defined in EssentialsSpawn.
|
||||
*/
|
||||
public void unloadEssentialsSpawn() {
|
||||
essentialsSpawn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the spawn location for the given player. The source of the spawn location varies
|
||||
* depending on the spawn priority setting.
|
||||
*
|
||||
* @param player The player to retrieve the spawn point for
|
||||
* @return The spawn location, or the default spawn location upon failure
|
||||
* @see RestrictionSettings#SPAWN_PRIORITY
|
||||
*/
|
||||
public Location getSpawnLocation(Player player) {
|
||||
AuthMe plugin = AuthMe.getInstance();
|
||||
if (plugin == null || player == null || player.getWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
World world = player.getWorld();
|
||||
Location spawnLoc = null;
|
||||
for (String priority : spawnPriority) {
|
||||
switch (priority.toLowerCase().trim()) {
|
||||
case "default":
|
||||
if (world.getSpawnLocation() != null) {
|
||||
spawnLoc = world.getSpawnLocation();
|
||||
}
|
||||
break;
|
||||
case "multiverse":
|
||||
if (Settings.multiverse) {
|
||||
spawnLoc = pluginHooks.getMultiverseSpawn(world);
|
||||
}
|
||||
break;
|
||||
case "essentials":
|
||||
spawnLoc = essentialsSpawn;
|
||||
break;
|
||||
case "authme":
|
||||
String playerNameLower = player.getName().toLowerCase();
|
||||
if (PlayerCache.getInstance().isAuthenticated(playerNameLower)) {
|
||||
spawnLoc = getSpawn();
|
||||
} else if (getFirstSpawn() != null && (!player.hasPlayedBefore() ||
|
||||
!plugin.getDataSource().isAuthAvailable(playerNameLower))) {
|
||||
spawnLoc = getFirstSpawn();
|
||||
} else {
|
||||
spawnLoc = getSpawn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (spawnLoc != null) {
|
||||
return spawnLoc;
|
||||
}
|
||||
}
|
||||
return world.getSpawnLocation(); // return default location
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the location under the given prefix.
|
||||
*
|
||||
* @param prefix The prefix to save the spawn under
|
||||
* @param location The location to persist
|
||||
* @return True upon success, false otherwise
|
||||
*/
|
||||
private boolean setLocation(String prefix, Location location) {
|
||||
if (location != null && location.getWorld() != null) {
|
||||
authMeConfiguration.set(prefix + ".world", location.getWorld().getName());
|
||||
authMeConfiguration.set(prefix + ".x", location.getX());
|
||||
authMeConfiguration.set(prefix + ".y", location.getY());
|
||||
authMeConfiguration.set(prefix + ".z", location.getZ());
|
||||
authMeConfiguration.set(prefix + ".yaw", location.getYaw());
|
||||
authMeConfiguration.set(prefix + ".pitch", location.getPitch());
|
||||
return saveAuthMeConfig();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean saveAuthMeConfig() {
|
||||
// TODO ljacqu 20160312: Investigate whether this utility should be put in a Utils class
|
||||
try {
|
||||
authMeConfiguration.save(authMeConfigurationFile);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not save spawn config (" + authMeConfigurationFile + ")", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link Location} object from the given path in the file configuration.
|
||||
*
|
||||
* @param configuration The file configuration to read from
|
||||
* @param pathPrefix The path to get the spawn point from
|
||||
* @return Location corresponding to the values in the path
|
||||
*/
|
||||
private static Location getLocationFromConfiguration(FileConfiguration configuration, String pathPrefix) {
|
||||
if (containsAllSpawnFields(configuration, pathPrefix)) {
|
||||
String prefix = pathPrefix + ".";
|
||||
String worldName = configuration.getString(prefix + "world");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (!StringUtils.isEmpty(worldName) && world != null) {
|
||||
return new Location(world, configuration.getDouble(prefix + "x"),
|
||||
configuration.getDouble(prefix + "y"), configuration.getDouble(prefix + "z"),
|
||||
getFloat(configuration, prefix + "yaw"), getFloat(configuration, prefix + "pitch"));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the file configuration contains all fields necessary to define a spawn
|
||||
* under the given path.
|
||||
*
|
||||
* @param configuration The file configuration to use
|
||||
* @param pathPrefix The path to verify
|
||||
* @return True if all spawn fields are present, false otherwise
|
||||
*/
|
||||
private static boolean containsAllSpawnFields(FileConfiguration configuration, String pathPrefix) {
|
||||
String[] fields = {"world", "x", "y", "z", "yaw", "pitch"};
|
||||
for (String field : fields) {
|
||||
if (!configuration.contains(pathPrefix + "." + field)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a property as a float from the given file configuration.
|
||||
*
|
||||
* @param configuration The file configuration to use
|
||||
* @param path The path of the property to retrieve
|
||||
* @return The float
|
||||
*/
|
||||
private static float getFloat(FileConfiguration configuration, String path) {
|
||||
Object value = configuration.get(path);
|
||||
// This behavior is consistent with FileConfiguration#getDouble
|
||||
return (value instanceof Number) ? ((Number) value).floatValue() : 0;
|
||||
}
|
||||
}
|
@ -12,6 +12,6 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Comment {
|
||||
|
||||
String[] value();
|
||||
String[] value();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Enum property.
|
||||
*
|
||||
* @param <E> The enum class
|
||||
*/
|
||||
class EnumProperty<E extends Enum<E>> extends Property<E> {
|
||||
|
||||
private Class<E> clazz;
|
||||
|
||||
public EnumProperty(Class<E> clazz, String path, E defaultValue) {
|
||||
super(path, defaultValue);
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFromFile(FileConfiguration configuration) {
|
||||
String textValue = configuration.getString(getPath());
|
||||
if (textValue == null) {
|
||||
return getDefaultValue();
|
||||
}
|
||||
E mappedValue = mapToEnum(textValue);
|
||||
return mappedValue != null ? mappedValue : getDefaultValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent(FileConfiguration configuration) {
|
||||
return super.isPresent(configuration) && mapToEnum(configuration.getString(getPath())) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
E value = getFromFile(configuration);
|
||||
return singleQuoteYaml.dump(value.name());
|
||||
}
|
||||
|
||||
private E mapToEnum(String value) {
|
||||
for (E entry : clazz.getEnumConstants()) {
|
||||
if (entry.name().equalsIgnoreCase(value)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Enum property type.
|
||||
*
|
||||
* @param <E> The enum class
|
||||
*/
|
||||
class EnumPropertyType<E extends Enum<E>> extends PropertyType<E> {
|
||||
|
||||
private Class<E> clazz;
|
||||
|
||||
public EnumPropertyType(Class<E> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFromFile(Property<E> property, FileConfiguration configuration) {
|
||||
String textValue = configuration.getString(property.getPath());
|
||||
if (textValue == null) {
|
||||
return property.getDefaultValue();
|
||||
}
|
||||
E mappedValue = mapToEnum(textValue);
|
||||
return mappedValue != null ? mappedValue : property.getDefaultValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Property<E> property, FileConfiguration configuration) {
|
||||
return super.contains(property, configuration)
|
||||
&& mapToEnum(configuration.getString(property.getPath())) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(E value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return singleQuoteYaml.dump(value.name());
|
||||
}
|
||||
|
||||
private E mapToEnum(String value) {
|
||||
for (E entry : clazz.getEnumConstants()) {
|
||||
if (entry.name().equalsIgnoreCase(value)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -10,45 +10,27 @@ import java.util.Objects;
|
||||
/**
|
||||
* Property class, representing a <i>setting</i> that is read from the config.yml file.
|
||||
*/
|
||||
public class Property<T> {
|
||||
public abstract class Property<T> {
|
||||
|
||||
private final PropertyType<T> type;
|
||||
private final String path;
|
||||
private final T defaultValue;
|
||||
|
||||
private Property(PropertyType<T> type, String path, T defaultValue) {
|
||||
protected Property(String path, T defaultValue) {
|
||||
Objects.requireNonNull(defaultValue);
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new property. See also {@link #newProperty(PropertyType, String, Object[])} for lists and
|
||||
* {@link #newProperty(Class, String, Enum)}.
|
||||
* Create a new string list property.
|
||||
*
|
||||
* @param type The property type
|
||||
* @param path The property's path
|
||||
* @param defaultValue The default value
|
||||
* @param <T> The type of the property
|
||||
* @return The created property
|
||||
*/
|
||||
public static <T> Property<T> newProperty(PropertyType<T> type, String path, T defaultValue) {
|
||||
return new Property<>(type, path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list property.
|
||||
*
|
||||
* @param type The list type of the property
|
||||
* @param path The property's path
|
||||
* @param defaultValues The default value's items
|
||||
* @param <U> The list type
|
||||
* @param defaultValues The items in the default list
|
||||
* @return The created list property
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <U> Property<List<U>> newProperty(PropertyType<List<U>> type, String path, U... defaultValues) {
|
||||
return new Property<>(type, path, Arrays.asList(defaultValues));
|
||||
public static Property<List<String>> newListProperty(String path, String... defaultValues) {
|
||||
// does not have the same name as not to clash with #newProperty(String, String)
|
||||
return new StringListProperty(path, defaultValues);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,36 +43,28 @@ public class Property<T> {
|
||||
* @return The created enum property
|
||||
*/
|
||||
public static <E extends Enum<E>> Property<E> newProperty(Class<E> clazz, String path, E defaultValue) {
|
||||
return new Property<>(new EnumPropertyType<>(clazz), path, defaultValue);
|
||||
return new EnumProperty<>(clazz, path, defaultValue);
|
||||
}
|
||||
|
||||
// -----
|
||||
// Overloaded convenience methods for specific types
|
||||
// -----
|
||||
public static Property<Boolean> newProperty(String path, boolean defaultValue) {
|
||||
return new Property<>(PropertyType.BOOLEAN, path, defaultValue);
|
||||
return new BooleanProperty(path, defaultValue);
|
||||
}
|
||||
|
||||
public static Property<Integer> newProperty(String path, int defaultValue) {
|
||||
return new Property<>(PropertyType.INTEGER, path, defaultValue);
|
||||
return new IntegerProperty(path, defaultValue);
|
||||
}
|
||||
|
||||
public static Property<String> newProperty(String path, String defaultValue) {
|
||||
return new Property<>(PropertyType.STRING, path, defaultValue);
|
||||
return new StringProperty(path, defaultValue);
|
||||
}
|
||||
|
||||
// -----
|
||||
// Hooks to the PropertyType methods
|
||||
// -----
|
||||
/**
|
||||
* Get the property value from the given configuration – guaranteed to never return null.
|
||||
*
|
||||
* @param configuration The configuration to read the value from
|
||||
* @return The value, or default if not present
|
||||
*/
|
||||
public T getFromFile(FileConfiguration configuration) {
|
||||
return type.getFromFile(this, configuration);
|
||||
}
|
||||
public abstract T getFromFile(FileConfiguration configuration);
|
||||
|
||||
/**
|
||||
* Return whether or not the given configuration file contains the property.
|
||||
@ -99,7 +73,7 @@ public class Property<T> {
|
||||
* @return True if the property is present, false otherwise
|
||||
*/
|
||||
public boolean isPresent(FileConfiguration configuration) {
|
||||
return type.contains(this, configuration);
|
||||
return configuration.contains(path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,12 +85,9 @@ public class Property<T> {
|
||||
* @return The generated YAML
|
||||
*/
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return type.toYaml(getFromFile(configuration), simpleYaml, singleQuoteYaml);
|
||||
return simpleYaml.dump(getFromFile(configuration));
|
||||
}
|
||||
|
||||
// -----
|
||||
// Trivial getters
|
||||
// -----
|
||||
/**
|
||||
* Return the default value of the property.
|
||||
*
|
||||
@ -140,4 +111,89 @@ public class Property<T> {
|
||||
return "Property '" + path + "'";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Boolean property.
|
||||
*/
|
||||
private static final class BooleanProperty extends Property<Boolean> {
|
||||
|
||||
public BooleanProperty(String path, Boolean defaultValue) {
|
||||
super(path, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getFromFile(FileConfiguration configuration) {
|
||||
return configuration.getBoolean(getPath(), getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer property.
|
||||
*/
|
||||
private static final class IntegerProperty extends Property<Integer> {
|
||||
|
||||
public IntegerProperty(String path, Integer defaultValue) {
|
||||
super(path, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getFromFile(FileConfiguration configuration) {
|
||||
return configuration.getInt(getPath(), getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String property.
|
||||
*/
|
||||
private static final class StringProperty extends Property<String> {
|
||||
|
||||
public StringProperty(String path, String defaultValue) {
|
||||
super(path, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFromFile(FileConfiguration configuration) {
|
||||
return configuration.getString(getPath(), getDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return singleQuoteYaml.dump(getFromFile(configuration));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String list property.
|
||||
*/
|
||||
private static final class StringListProperty extends Property<List<String>> {
|
||||
|
||||
public StringListProperty(String path, String[] defaultValues) {
|
||||
super(path, Arrays.asList(defaultValues));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFromFile(FileConfiguration configuration) {
|
||||
if (!configuration.isList(getPath())) {
|
||||
return getDefaultValue();
|
||||
}
|
||||
return configuration.getStringList(getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent(FileConfiguration configuration) {
|
||||
return configuration.isList(getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
List<String> value = getFromFile(configuration);
|
||||
String yaml = singleQuoteYaml.dump(value);
|
||||
// If the property is a non-empty list we need to append a new line because it will be
|
||||
// something like the following, which requires a new line:
|
||||
// - 'item 1'
|
||||
// - 'second item in list'
|
||||
return value.isEmpty() ? yaml : "\n" + yaml;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,116 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles a certain property type and provides type-specific functionality.
|
||||
*
|
||||
* @param <T> The value of the property
|
||||
* @see Property
|
||||
*/
|
||||
public abstract class PropertyType<T> {
|
||||
|
||||
public static final PropertyType<Boolean> BOOLEAN = new BooleanProperty();
|
||||
public static final PropertyType<Integer> INTEGER = new IntegerProperty();
|
||||
public static final PropertyType<String> STRING = new StringProperty();
|
||||
public static final PropertyType<List<String>> STRING_LIST = new StringListProperty();
|
||||
|
||||
/**
|
||||
* Get the property's value from the given YAML configuration.
|
||||
*
|
||||
* @param property The property to retrieve
|
||||
* @param configuration The YAML configuration to read from
|
||||
* @return The read value, or the default value if absent
|
||||
*/
|
||||
public abstract T getFromFile(Property<T> property, FileConfiguration configuration);
|
||||
|
||||
/**
|
||||
* Return whether the property is present in the given configuration.
|
||||
*
|
||||
* @param property The property to search for
|
||||
* @param configuration The configuration to verify
|
||||
* @return True if the property is present, false otherwise
|
||||
*/
|
||||
public boolean contains(Property<T> property, FileConfiguration configuration) {
|
||||
return configuration.contains(property.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the value as YAML.
|
||||
*
|
||||
* @param value The value to export
|
||||
* @param simpleYaml YAML object (default)
|
||||
* @param singleQuoteYaml YAML object set to use single quotes
|
||||
* @return The generated YAML
|
||||
*/
|
||||
public String toYaml(T value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return simpleYaml.dump(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Boolean property.
|
||||
*/
|
||||
private static final class BooleanProperty extends PropertyType<Boolean> {
|
||||
@Override
|
||||
public Boolean getFromFile(Property<Boolean> property, FileConfiguration configuration) {
|
||||
return configuration.getBoolean(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer property.
|
||||
*/
|
||||
private static final class IntegerProperty extends PropertyType<Integer> {
|
||||
@Override
|
||||
public Integer getFromFile(Property<Integer> property, FileConfiguration configuration) {
|
||||
return configuration.getInt(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String property.
|
||||
*/
|
||||
private static final class StringProperty extends PropertyType<String> {
|
||||
@Override
|
||||
public String getFromFile(Property<String> property, FileConfiguration configuration) {
|
||||
return configuration.getString(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
@Override
|
||||
public String toYaml(String value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return singleQuoteYaml.dump(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String list property.
|
||||
*/
|
||||
private static final class StringListProperty extends PropertyType<List<String>> {
|
||||
@Override
|
||||
public List<String> getFromFile(Property<List<String>> property, FileConfiguration configuration) {
|
||||
if (!configuration.isList(property.getPath())) {
|
||||
return property.getDefaultValue();
|
||||
}
|
||||
return configuration.getStringList(property.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Property<List<String>> property, FileConfiguration configuration) {
|
||||
return configuration.contains(property.getPath()) && configuration.isList(property.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(List<String> value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
String yaml = singleQuoteYaml.dump(value);
|
||||
// If the property is a non-empty list we need to append a new line because it will be
|
||||
// something like the following, which requires a new line:
|
||||
// - 'item 1'
|
||||
// - 'second item in list'
|
||||
return value.isEmpty() ? yaml : "\n" + yaml;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,26 +5,24 @@ import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING;
|
||||
|
||||
public class ConverterSettings implements SettingsClass {
|
||||
|
||||
@Comment("Rakamak file name")
|
||||
public static final Property<String> RAKAMAK_FILE_NAME =
|
||||
newProperty(STRING, "Converter.Rakamak.fileName", "users.rak");
|
||||
newProperty("Converter.Rakamak.fileName", "users.rak");
|
||||
|
||||
@Comment("Rakamak use IP?")
|
||||
public static final Property<Boolean> RAKAMAK_USE_IP =
|
||||
newProperty(BOOLEAN, "Converter.Rakamak.useIP", false);
|
||||
newProperty("Converter.Rakamak.useIP", false);
|
||||
|
||||
@Comment("Rakamak IP file name")
|
||||
public static final Property<String> RAKAMAK_IP_FILE_NAME =
|
||||
newProperty(STRING, "Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
newProperty("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
|
||||
@Comment("CrazyLogin database file name")
|
||||
public static final Property<String> CRAZYLOGIN_FILE_NAME =
|
||||
newProperty(STRING, "Converter.CrazyLogin.fileName", "accounts.db");
|
||||
newProperty("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
|
||||
private ConverterSettings() {
|
||||
}
|
||||
|
@ -6,29 +6,26 @@ import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.INTEGER;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
|
||||
public class EmailSettings implements SettingsClass {
|
||||
|
||||
@Comment("Email SMTP server host")
|
||||
public static final Property<String> SMTP_HOST =
|
||||
newProperty(STRING, "Email.mailSMTP", "smtp.gmail.com");
|
||||
newProperty("Email.mailSMTP", "smtp.gmail.com");
|
||||
|
||||
@Comment("Email SMTP server port")
|
||||
public static final Property<Integer> SMTP_PORT =
|
||||
newProperty(INTEGER, "Email.mailPort", 465);
|
||||
newProperty("Email.mailPort", 465);
|
||||
|
||||
@Comment("Email account which sends the mails")
|
||||
public static final Property<String> MAIL_ACCOUNT =
|
||||
newProperty(STRING, "Email.mailAccount", "");
|
||||
newProperty("Email.mailAccount", "");
|
||||
|
||||
@Comment("Email account password")
|
||||
public static final Property<String> MAIL_PASSWORD =
|
||||
newProperty(STRING, "Email.mailPassword", "");
|
||||
newProperty("Email.mailPassword", "");
|
||||
|
||||
@Comment("Custom sender name, replacing the mailAccount name in the email")
|
||||
public static final Property<String> MAIL_SENDER_NAME =
|
||||
@ -36,39 +33,39 @@ public class EmailSettings implements SettingsClass {
|
||||
|
||||
@Comment("Recovery password length")
|
||||
public static final Property<Integer> RECOVERY_PASSWORD_LENGTH =
|
||||
newProperty(INTEGER, "Email.RecoveryPasswordLength", 8);
|
||||
newProperty("Email.RecoveryPasswordLength", 8);
|
||||
|
||||
@Comment("Mail Subject")
|
||||
public static final Property<String> RECOVERY_MAIL_SUBJECT =
|
||||
newProperty(STRING, "Email.mailSubject", "Your new AuthMe password");
|
||||
newProperty("Email.mailSubject", "Your new AuthMe password");
|
||||
|
||||
@Comment("Like maxRegPerIP but with email")
|
||||
public static final Property<Integer> MAX_REG_PER_EMAIL =
|
||||
newProperty(INTEGER, "Email.maxRegPerEmail", 1);
|
||||
newProperty("Email.maxRegPerEmail", 1);
|
||||
|
||||
@Comment("Recall players to add an email?")
|
||||
public static final Property<Boolean> RECALL_PLAYERS =
|
||||
newProperty(BOOLEAN, "Email.recallPlayers", false);
|
||||
newProperty("Email.recallPlayers", false);
|
||||
|
||||
@Comment("Delay in minute for the recall scheduler")
|
||||
public static final Property<Integer> DELAY_RECALL =
|
||||
newProperty(INTEGER, "Email.delayRecall", 5);
|
||||
newProperty("Email.delayRecall", 5);
|
||||
|
||||
@Comment("Blacklist these domains for emails")
|
||||
public static final Property<List<String>> DOMAIN_BLACKLIST =
|
||||
newProperty(STRING_LIST, "Email.emailBlacklisted", "10minutemail.com");
|
||||
newListProperty("Email.emailBlacklisted", "10minutemail.com");
|
||||
|
||||
@Comment("Whitelist ONLY these domains for emails")
|
||||
public static final Property<List<String>> DOMAIN_WHITELIST =
|
||||
newProperty(STRING_LIST, "Email.emailWhitelisted");
|
||||
newListProperty("Email.emailWhitelisted");
|
||||
|
||||
@Comment("Send the new password drawn in an image?")
|
||||
public static final Property<Boolean> PASSWORD_AS_IMAGE =
|
||||
newProperty(BOOLEAN, "Email.generateImage", false);
|
||||
newProperty("Email.generateImage", false);
|
||||
|
||||
@Comment("The OAuth2 token")
|
||||
public static final Property<String> OAUTH2_TOKEN =
|
||||
newProperty(STRING, "Email.emailOauth2Token", "");
|
||||
newProperty("Email.emailOauth2Token", "");
|
||||
|
||||
private EmailSettings() {
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class HooksSettings implements SettingsClass {
|
||||
@ -48,7 +48,7 @@ public class HooksSettings implements SettingsClass {
|
||||
|
||||
@Comment("Other MySQL columns where we need to put the username (case-sensitive)")
|
||||
public static final Property<List<String>> MYSQL_OTHER_USERNAME_COLS =
|
||||
newProperty(PropertyType.STRING_LIST, "ExternalBoardOptions.mySQLOtherUsernameColumns");
|
||||
newListProperty("ExternalBoardOptions.mySQLOtherUsernameColumns");
|
||||
|
||||
@Comment("How much log2 rounds needed in BCrypt (do not change if you do not know what it does)")
|
||||
public static final Property<Integer> BCRYPT_LOG2_ROUND =
|
||||
|
@ -6,39 +6,37 @@ import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.INTEGER;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
|
||||
|
||||
public class ProtectionSettings implements SettingsClass {
|
||||
|
||||
@Comment("Enable some servers protection (country based login, antibot)")
|
||||
public static final Property<Boolean> ENABLE_PROTECTION =
|
||||
newProperty(BOOLEAN, "Protection.enableProtection", false);
|
||||
newProperty("Protection.enableProtection", false);
|
||||
|
||||
@Comment({"Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes",
|
||||
"PLEASE USE QUOTES!"})
|
||||
public static final Property<List<String>> COUNTRIES_WHITELIST =
|
||||
newProperty(STRING_LIST, "Protection.countries", "US", "GB", "A1");
|
||||
newListProperty("Protection.countries", "US", "GB", "A1");
|
||||
|
||||
@Comment({"Countries not allowed to join the server and register",
|
||||
"PLEASE USE QUOTES!"})
|
||||
public static final Property<List<String>> COUNTRIES_BLACKLIST =
|
||||
newProperty(STRING_LIST, "Protection.countriesBlacklist");
|
||||
newListProperty("Protection.countriesBlacklist");
|
||||
|
||||
@Comment("Do we need to enable automatic antibot system?")
|
||||
public static final Property<Boolean> ENABLE_ANTIBOT =
|
||||
newProperty(BOOLEAN, "Protection.enableAntiBot", false);
|
||||
newProperty("Protection.enableAntiBot", false);
|
||||
|
||||
@Comment("Max number of player allowed to login in 5 secs before enable AntiBot system automatically")
|
||||
@Comment("Max number of players allowed to login in 5 secs before the AntiBot system is enabled automatically")
|
||||
public static final Property<Integer> ANTIBOT_SENSIBILITY =
|
||||
newProperty(INTEGER, "Protection.antiBotSensibility", 5);
|
||||
newProperty("Protection.antiBotSensibility", 5);
|
||||
|
||||
@Comment("Duration in minutes of the antibot automatic system")
|
||||
public static final Property<Integer> ANTIBOT_DURATION =
|
||||
newProperty(INTEGER, "Protection.antiBotDuration", 10);
|
||||
newProperty("Protection.antiBotDuration", 10);
|
||||
|
||||
private ProtectionSettings() {
|
||||
}
|
||||
|
@ -5,43 +5,40 @@ import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.BOOLEAN;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.INTEGER;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING;
|
||||
|
||||
public class PurgeSettings implements SettingsClass {
|
||||
|
||||
@Comment("If enabled, AuthMe automatically purges old, unused accounts")
|
||||
public static final Property<Boolean> USE_AUTO_PURGE =
|
||||
newProperty(BOOLEAN, "Purge.useAutoPurge", false);
|
||||
newProperty("Purge.useAutoPurge", false);
|
||||
|
||||
@Comment("Number of Days an account become Unused")
|
||||
public static final Property<Integer> DAYS_BEFORE_REMOVE_PLAYER =
|
||||
newProperty(INTEGER, "Purge.daysBeforeRemovePlayer", 60);
|
||||
newProperty("Purge.daysBeforeRemovePlayer", 60);
|
||||
|
||||
@Comment("Do we need to remove the player.dat file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_PLAYER_DAT =
|
||||
newProperty(BOOLEAN, "Purge.removePlayerDat", false);
|
||||
newProperty("Purge.removePlayerDat", false);
|
||||
|
||||
@Comment("Do we need to remove the Essentials/users/player.yml file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_ESSENTIALS_FILES =
|
||||
newProperty(BOOLEAN, "Purge.removeEssentialsFile", false);
|
||||
newProperty("Purge.removeEssentialsFile", false);
|
||||
|
||||
@Comment("World where are players.dat stores")
|
||||
public static final Property<String> DEFAULT_WORLD =
|
||||
newProperty(STRING, "Purge.defaultWorld", "world");
|
||||
newProperty("Purge.defaultWorld", "world");
|
||||
|
||||
@Comment("Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ?")
|
||||
public static final Property<Boolean> REMOVE_LIMITED_CREATIVE_INVENTORIES =
|
||||
newProperty(BOOLEAN, "Purge.removeLimitedCreativesInventories", false);
|
||||
newProperty("Purge.removeLimitedCreativesInventories", false);
|
||||
|
||||
@Comment("Do we need to remove the AntiXRayData/PlayerData/player file during purge process?")
|
||||
public static final Property<Boolean> REMOVE_ANTI_XRAY_FILE =
|
||||
newProperty(BOOLEAN, "Purge.removeAntiXRayFile", false);
|
||||
newProperty("Purge.removeAntiXRayFile", false);
|
||||
|
||||
@Comment("Do we need to remove permissions?")
|
||||
public static final Property<Boolean> REMOVE_PERMISSIONS =
|
||||
newProperty(BOOLEAN, "Purge.removePermissions", false);
|
||||
newProperty("Purge.removePermissions", false);
|
||||
|
||||
private PurgeSettings() {
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class RegistrationSettings implements SettingsClass {
|
||||
@ -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);
|
||||
@ -50,21 +50,21 @@ public class RegistrationSettings implements SettingsClass {
|
||||
|
||||
@Comment("Force these commands after /login, without any '/', use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_COMMANDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceCommands");
|
||||
newListProperty("settings.forceCommands");
|
||||
|
||||
@Comment("Force these commands after /login as service console, without any '/'. "
|
||||
+ "Use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_COMMANDS_AS_CONSOLE =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceCommandsAsConsole");
|
||||
newListProperty("settings.forceCommandsAsConsole");
|
||||
|
||||
@Comment("Force these commands after /register, without any '/', use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_REGISTER_COMMANDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceRegisterCommands");
|
||||
newListProperty("settings.forceRegisterCommands");
|
||||
|
||||
@Comment("Force these commands after /register as a server console, without any '/'. "
|
||||
+ "Use %p to replace with player name")
|
||||
public static final Property<List<String>> FORCE_REGISTER_COMMANDS_AS_CONSOLE =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.forceRegisterCommandsAsConsole");
|
||||
newListProperty("settings.forceRegisterCommandsAsConsole");
|
||||
|
||||
@Comment({
|
||||
"Enable to display the welcome message (welcome.txt) after a registration or a login",
|
||||
|
@ -2,11 +2,11 @@ package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class RestrictionSettings implements SettingsClass {
|
||||
@ -26,7 +26,7 @@ public class RestrictionSettings implements SettingsClass {
|
||||
|
||||
@Comment("Allowed commands for unauthenticated players")
|
||||
public static final Property<List<String>> ALLOW_COMMANDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.restrictions.allowCommands",
|
||||
newListProperty("settings.restrictions.allowCommands",
|
||||
"login", "register", "l", "reg", "email", "captcha");
|
||||
|
||||
@Comment("Max number of allowed registrations per IP")
|
||||
@ -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);
|
||||
|
||||
@ -75,7 +75,7 @@ public class RestrictionSettings implements SettingsClass {
|
||||
" AllowedRestrictedUser:",
|
||||
" - playername;127.0.0.1"})
|
||||
public static final Property<List<String>> ALLOWED_RESTRICTED_USERS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.restrictions.AllowedRestrictedUser");
|
||||
newListProperty("settings.restrictions.AllowedRestrictedUser");
|
||||
|
||||
@Comment("Should unregistered players be kicked immediately?")
|
||||
public static final Property<Boolean> KICK_NON_REGISTERED =
|
||||
@ -148,7 +148,7 @@ public class RestrictionSettings implements SettingsClass {
|
||||
"WorldNames where we need to force the spawn location for ForceSpawnLocOnJoinEnabled",
|
||||
"Case-sensitive!"})
|
||||
public static final Property<List<String>> FORCE_SPAWN_ON_WORLDS =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.restrictions.ForceSpawnOnTheseWorlds",
|
||||
newListProperty("settings.restrictions.ForceSpawnOnTheseWorlds",
|
||||
"world", "world_nether", "world_the_end");
|
||||
|
||||
@Comment("Ban ip when the ip is not the ip registered in database")
|
||||
@ -189,7 +189,7 @@ public class RestrictionSettings implements SettingsClass {
|
||||
"It is case-sensitive!"
|
||||
})
|
||||
public static final Property<List<String>> UNRESTRICTED_NAMES =
|
||||
newProperty(PropertyType.STRING_LIST, "settings.unrestrictions.UnrestrictedName");
|
||||
newListProperty("settings.unrestrictions.UnrestrictedName");
|
||||
|
||||
|
||||
private RestrictionSettings() {
|
||||
|
@ -7,8 +7,8 @@ import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
|
||||
public class SecuritySettings implements SettingsClass {
|
||||
|
||||
@ -98,8 +98,7 @@ public class SecuritySettings implements SettingsClass {
|
||||
"- '123456'",
|
||||
"- 'password'"})
|
||||
public static final Property<List<String>> UNSAFE_PASSWORDS =
|
||||
newProperty(STRING_LIST, "settings.security.unsafePasswords",
|
||||
"123456", "password", "qwerty", "12345", "54321");
|
||||
newListProperty("settings.security.unsafePasswords", "123456", "password", "qwerty", "12345", "54321");
|
||||
|
||||
private SecuritySettings() {
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package fr.xephi.authme.settings.propertymap;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -37,14 +39,13 @@ final class Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a node to the root, creating any intermediary children that don't exist.
|
||||
* Add a child node, creating any intermediary children that don't exist.
|
||||
*
|
||||
* @param root The root to add the path to
|
||||
* @param fullPath The entire path of the node to add, separate by periods
|
||||
*/
|
||||
public static void addNode(Node root, String fullPath) {
|
||||
public void addNode(String fullPath) {
|
||||
String[] pathParts = fullPath.split("\\.");
|
||||
Node parent = root;
|
||||
Node parent = this;
|
||||
for (String part : pathParts) {
|
||||
Node child = parent.getChild(part);
|
||||
if (child == null) {
|
||||
@ -59,17 +60,16 @@ final class Node {
|
||||
* Compare two nodes by this class' sorting behavior (insertion order).
|
||||
* Note that this method assumes that both supplied paths exist in the tree.
|
||||
*
|
||||
* @param root The root of the tree
|
||||
* @param fullPath1 The full path to the first node
|
||||
* @param fullPath2 The full path to the second node
|
||||
* @return The comparison result, in the same format as {@link Comparable#compareTo}
|
||||
*/
|
||||
public static int compare(Node root, String fullPath1, String fullPath2) {
|
||||
public int compare(String fullPath1, String fullPath2) {
|
||||
String[] path1 = fullPath1.split("\\.");
|
||||
String[] path2 = fullPath2.split("\\.");
|
||||
|
||||
int commonCount = 0;
|
||||
Node commonNode = root;
|
||||
Node commonNode = this;
|
||||
while (commonCount < path1.length && commonCount < path2.length
|
||||
&& path1[commonCount].equals(path2[commonCount]) && commonNode != null) {
|
||||
commonNode = commonNode.getChild(path1[commonCount]);
|
||||
@ -77,7 +77,7 @@ final class Node {
|
||||
}
|
||||
|
||||
if (commonNode == null) {
|
||||
System.err.println("Could not find common node for '" + fullPath1 + "' at index " + commonCount);
|
||||
ConsoleLogger.showError("Could not find common node for '" + fullPath1 + "' at index " + commonCount);
|
||||
return fullPath1.compareTo(fullPath2); // fallback
|
||||
} else if (commonCount >= path1.length || commonCount >= path2.length) {
|
||||
return Integer.compare(path1.length, path2.length);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user