mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2025-04-09 21:47:02 +02:00
Merge pull request #716 from AuthMe-Team/master
Sync with the development repository
This commit is contained in:
commit
19d6179230
@ -3,7 +3,7 @@ sudo: false
|
||||
language: java
|
||||
jdk: oraclejdk7
|
||||
|
||||
script: mvn verify -B
|
||||
script: mvn clean verify -B
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
|
260
pom.xml
260
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>fr.xephi</groupId>
|
||||
<artifactId>authme</artifactId>
|
||||
<version>5.2-BETA2</version>
|
||||
<version>5.2-BETA3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>AuthMeReloaded</name>
|
||||
@ -21,9 +21,9 @@
|
||||
</organization>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/Xephi/AuthMeReloaded.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:Xephi/AuthMeReloaded.git</developerConnection>
|
||||
<url>https://github.com/Xephi/AuthMeReloaded</url>
|
||||
<connection>scm:git:https://github.com/AuthMe-Team/AuthMeReloaded.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:AuthMe-Team/AuthMeReloaded.git</developerConnection>
|
||||
<url>https://github.com/AuthMe-Team/AuthMeReloaded</url>
|
||||
</scm>
|
||||
|
||||
<ciManagement>
|
||||
@ -49,22 +49,24 @@
|
||||
</prerequisites>
|
||||
|
||||
<properties>
|
||||
<!-- 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>
|
||||
<!-- Project properties -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.jdkVersion>1.7</project.jdkVersion>
|
||||
|
||||
<!-- Output properties -->
|
||||
<pluginName>AuthMe</pluginName>
|
||||
<jarName>${pluginName}-${project.version}</jarName>
|
||||
<mainClass>${project.groupId}.${project.artifactId}.${pluginName}</mainClass>
|
||||
<pluginAuthors>Xephi, sgdc3, DNx5, timvisee, games647, ljacqu</pluginAuthors>
|
||||
<buildNumber>Unknown</buildNumber>
|
||||
<project.outputName>AuthMe</project.outputName>
|
||||
<project.buildNumber>CUSTOM</project.buildNumber>
|
||||
<project.skipExtendedHashTests>false</project.skipExtendedHashTests>
|
||||
<project.versionCode>${project.version}-b${project.buildNumber}</project.versionCode>
|
||||
<project.finalName>${project.outputName}-${project.version}</project.finalName>
|
||||
|
||||
<!-- BukkitPlugin properties -->
|
||||
<bukkitplugin.name>${project.outputName}</bukkitplugin.name>
|
||||
<bukkitplugin.main>${project.groupId}.${project.artifactId}.${bukkitplugin.name}</bukkitplugin.main>
|
||||
<bukkitplugin.authors>Xephi, sgdc3, DNx5, timvisee, games647, ljacqu</bukkitplugin.authors>
|
||||
|
||||
<!-- Change Bukkit Version HERE! -->
|
||||
<bukkitVersion>1.9.2-R0.1-SNAPSHOT</bukkitVersion>
|
||||
<bukkit.version>1.10-R0.1-SNAPSHOT</bukkit.version>
|
||||
</properties>
|
||||
|
||||
<!-- Jenkins profile (add the real buildNumber to the version string) -->
|
||||
@ -77,47 +79,44 @@
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<buildNumber>${env.BUILD_NUMBER}</buildNumber>
|
||||
<project.buildNumber>${env.BUILD_NUMBER}</project.buildNumber>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>skipLongHashTests</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>skipLongHashTests</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.skipExtendedHashTests>true</project.skipExtendedHashTests>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<finalName>${jarName}-noshade</finalName>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||
<!-- Name of the NOSHADE jar (no shaded/relocated libraries) -->
|
||||
<finalName>${project.finalName}-noshade</finalName>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>false</filtering>
|
||||
<directory>.</directory>
|
||||
<filtering>false</filtering>
|
||||
<includes>
|
||||
<include>LICENSE</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources/messages/</directory>
|
||||
<targetPath>./messages/</targetPath>
|
||||
<filtering>false</filtering>
|
||||
<directory>src/main/resources/messages/</directory>
|
||||
<includes>
|
||||
<include>*.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
</testResource>
|
||||
</testResources>
|
||||
|
||||
<plugins>
|
||||
<!-- Maven Java Compiler -->
|
||||
@ -126,10 +125,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>${jdkVersion}</source>
|
||||
<target>${jdkVersion}</target>
|
||||
<testSource>${testJreVersion}</testSource>
|
||||
<testTarget>${testJreVersion}</testTarget>
|
||||
<source>${project.jdkVersion}</source>
|
||||
<target>${project.jdkVersion}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Test Plugin -->
|
||||
@ -138,21 +135,30 @@
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.19.1</version>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=${projectEncoding} ${argLine}</argLine>
|
||||
<argLine>-Dfile.encoding=${project.build.sourceEncoding} @{argLine}</argLine>
|
||||
<systemPropertyVariables>
|
||||
<project.skipExtendedHashTests>${project.skipExtendedHashTests}</project.skipExtendedHashTests>
|
||||
</systemPropertyVariables>
|
||||
</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)-->
|
||||
<!--
|
||||
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)
|
||||
-->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<!--
|
||||
Let's try to remove this!
|
||||
<minimizeJar>false</minimizeJar>
|
||||
-->
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- Spigot 1.8+ -->
|
||||
<execution>
|
||||
<id>spigot-shade</id>
|
||||
<phase>package</phase>
|
||||
@ -160,6 +166,7 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Exclude guava (already included into spigot) -->
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>com.google.guava:guava</exclude>
|
||||
@ -187,15 +194,20 @@
|
||||
<pattern>net.ricecode.similarity</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.similarity</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>javax.inject</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.inject</shadedPattern>
|
||||
</relocation>
|
||||
<!-- MCStats.org metrics -->
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>fr.xephi.authme</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<outputFile>target/${jarName}-spigot.jar</outputFile>
|
||||
<outputFile>target/${project.finalName}-spigot.jar</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!-- 1.7.10 and lower -->
|
||||
<execution>
|
||||
<id>legacy-shade</id>
|
||||
<phase>package</phase>
|
||||
@ -225,22 +237,41 @@
|
||||
<pattern>net.ricecode.similarity</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.similarity</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>javax.inject</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.inject</shadedPattern>
|
||||
</relocation>
|
||||
<!-- MCStats.org metrics -->
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>fr.xephi.authme</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<outputFile>target/${jarName}-legacy.jar</outputFile>
|
||||
<outputFile>target/${project.finalName}-legacy.jar</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Exec Tools -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<configuration>
|
||||
<classpathScope>test</classpathScope>
|
||||
<workingDirectory>${project.basedir}/target/test-classes</workingDirectory>
|
||||
<mainClass>tools.ToolsRunner</mainClass>
|
||||
<arguments>
|
||||
<argument>updateDocs</argument>
|
||||
</arguments>
|
||||
<includeProjectDependencies>true</includeProjectDependencies>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Test coverage -->
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.7.6.201602180812</version>
|
||||
<version>0.7.7.201606060606</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-agent</id>
|
||||
@ -254,7 +285,7 @@
|
||||
<plugin>
|
||||
<groupId>org.eluder.coveralls</groupId>
|
||||
<artifactId>coveralls-maven-plugin</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.2.0</version>
|
||||
<configuration>
|
||||
<failOnServiceError>false</failOnServiceError>
|
||||
</configuration>
|
||||
@ -264,11 +295,8 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.3</version>
|
||||
<version>2.10.4</version>
|
||||
<configuration>
|
||||
<charset>UTF-8</charset>
|
||||
<docencoding>UTF-8</docencoding>
|
||||
<docfilessubdirs>true</docfilessubdirs>
|
||||
<show>public</show>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
@ -354,19 +382,6 @@
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- JDBC drivers for datasource integration tests -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.8.11.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.191</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Log4J Logger (required by the console filter) -->
|
||||
<dependency>
|
||||
@ -375,7 +390,6 @@
|
||||
<!-- Can't use newer versions due to api changes! -->
|
||||
<version>2.0-beta9</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Java Email Library -->
|
||||
@ -396,7 +410,7 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Guava (required to provide 1.7.10 and below compatibility) -->
|
||||
<!-- Guava (the version provided by the latest bukkit version) -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
@ -405,6 +419,15 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Inject API -->
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Maxmind GeoIp API -->
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip</groupId>
|
||||
@ -429,21 +452,12 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--Spigot API-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.9.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Bukkit API, http://www.spigotmc.org/ or http://bukkit.org/ -->
|
||||
<!-- Spigot API, http://www.spigotmc.org/ or http://bukkit.org/ -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>${bukkitVersion}</version>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${bukkit.version}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit</artifactId>
|
||||
@ -465,6 +479,10 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<groupId>com.google.guava</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>bungeecord-chat</artifactId>
|
||||
<groupId>net.md-5</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
@ -474,7 +492,6 @@
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>3.6.5-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
@ -591,14 +608,13 @@
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Multi World plugin, http://www.spigotmc.org/resources/multiverse-core.390/ -->
|
||||
<dependency>
|
||||
<groupId>com.onarandombox.multiversecore</groupId>
|
||||
<artifactId>Multiverse-Core</artifactId>
|
||||
<version>2.5</version>
|
||||
<version>2.5.0-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
@ -646,8 +662,15 @@
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jettison</artifactId>
|
||||
<groupId>org.codehaus.jettison</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Essentials plugin -->
|
||||
@ -666,7 +689,6 @@
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Anti-PvPLogging plugin, https://github.com/MinelinkNetwork/CombatTagPlus -->
|
||||
@ -741,7 +763,6 @@
|
||||
<groupId>org.mcstats.bukkit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- XAuth, another authentication plugin, required by the database converter -->
|
||||
@ -784,36 +805,6 @@
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Unit Testing Libraries -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>4.12</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>java-hamcrest</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>2.0.0.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>2.0.5-beta</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- String comparison library. Used for dynamic help system. -->
|
||||
@ -824,5 +815,44 @@
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Unit Testing Libraries -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>java-hamcrest</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>2.0.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>2.0.5-beta</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- JDBC drivers for datasource integration tests -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.8.11.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.192</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
126
samples/website_integration/AuthMeController.php
Normal file
126
samples/website_integration/AuthMeController.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/*****************************************************************************
|
||||
* AuthMe website integration logic *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Allows interaction with the AuthMe database (registration, password *
|
||||
* verification). Don't forget to update the AUTHME_TABLE value and your *
|
||||
* database credentials in getAuthmeMySqli(). *
|
||||
* *
|
||||
* Source: https://github.com/AuthMe-Team/AuthMeReloaded/ *
|
||||
*****************************************************************************/
|
||||
abstract class AuthMeController {
|
||||
|
||||
const AUTHME_TABLE = 'authme';
|
||||
|
||||
/**
|
||||
* Entry point function to check supplied credentials against the AuthMe database.
|
||||
*
|
||||
* @param string $username the username
|
||||
* @param string $password the password
|
||||
* @return bool true iff the data is correct, false otherwise
|
||||
*/
|
||||
function checkPassword($username, $password) {
|
||||
if (is_scalar($username) && is_scalar($password)) {
|
||||
$hash = $this->getHashFromDatabase($username);
|
||||
if ($hash) {
|
||||
return $this->isValidPassword($password, $hash);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user exists in the database or not.
|
||||
*
|
||||
* @param string $username the username to check
|
||||
* @return bool true if the user exists; false otherwise
|
||||
*/
|
||||
function isUserRegistered($username) {
|
||||
$mysqli = $this->getAuthmeMySqli();
|
||||
if ($mysqli !== null) {
|
||||
$stmt = $mysqli->prepare('SELECT 1 FROM ' . self::AUTHME_TABLE . ' WHERE username = ?');
|
||||
$stmt->bind_param('s', $username);
|
||||
$stmt->execute();
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
// Defensive default to true; we actually don't know
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a player with the given username.
|
||||
*
|
||||
* @param string $username the username to register
|
||||
* @param string $password the password to associate to the user
|
||||
* @return bool whether or not the registration was successful
|
||||
*/
|
||||
function register($username, $password) {
|
||||
$mysqli = $this->getAuthmeMySqli();
|
||||
if ($mysqli !== null) {
|
||||
$hash = $this->hash($password);
|
||||
$stmt = $mysqli->prepare('INSERT INTO ' . self::AUTHME_TABLE . ' (username, realname, password, ip) '
|
||||
. 'VALUES (?, ?, ?, ?)');
|
||||
$username_low = strtolower($username);
|
||||
$stmt->bind_param('ssss', $username, $username_low, $hash, $_SERVER['REMOTE_ADDR']);
|
||||
return $stmt->execute();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes the given password.
|
||||
*
|
||||
* @param $password string the clear-text password to hash
|
||||
* @return string the resulting hash
|
||||
*/
|
||||
protected abstract function hash($password);
|
||||
|
||||
/**
|
||||
* Checks whether the given password matches the hash.
|
||||
*
|
||||
* @param $password string the clear-text password
|
||||
* @param $hash string the password hash
|
||||
* @return boolean true if the password matches, false otherwise
|
||||
*/
|
||||
protected abstract function isValidPassword($password, $hash);
|
||||
|
||||
/**
|
||||
* Returns a connection to the database.
|
||||
*
|
||||
* @return mysqli|null the mysqli object or null upon error
|
||||
*/
|
||||
private function getAuthmeMySqli() {
|
||||
// CHANGE YOUR DATABASE DETAILS HERE BELOW: host, user, password, database name
|
||||
$mysqli = new mysqli('localhost', 'root', '', 'authme');
|
||||
if (mysqli_connect_error()) {
|
||||
printf('Could not connect to AuthMe database. Errno: %d, error: "%s"',
|
||||
mysqli_connect_errno(), mysqli_connect_error());
|
||||
return null;
|
||||
}
|
||||
return $mysqli;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hash associated with the given user from the database.
|
||||
*
|
||||
* @param string $username the username whose hash should be retrieved
|
||||
* @return string|null the hash, or null if unavailable (e.g. username doesn't exist)
|
||||
*/
|
||||
private function getHashFromDatabase($username) {
|
||||
// Add here your database host, username, password and database name
|
||||
$mysqli = $this->getAuthmeMySqli();
|
||||
if ($mysqli !== null) {
|
||||
$stmt = $mysqli->prepare('SELECT password FROM ' . self::AUTHME_TABLE . ' WHERE username = ?');
|
||||
$stmt->bind_param('s', $username);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($password);
|
||||
if ($stmt->fetch()) {
|
||||
return $password;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
20
samples/website_integration/Bcrypt.php
Normal file
20
samples/website_integration/Bcrypt.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/***********************************************************
|
||||
* AuthMe website integration logic for BCrypt *
|
||||
* ------------------------------------------------------- *
|
||||
* See AuthMeController for details. *
|
||||
* *
|
||||
* Source: https://github.com/AuthMe-Team/AuthMeReloaded/ *
|
||||
***********************************************************/
|
||||
class Bcrypt extends AuthMeController {
|
||||
|
||||
protected function hash($password) {
|
||||
return password_hash($password, PASSWORD_BCRYPT);
|
||||
}
|
||||
|
||||
protected function isValidPassword($password, $hash) {
|
||||
return password_verify($password, $hash);
|
||||
}
|
||||
|
||||
}
|
48
samples/website_integration/Sha256.php
Normal file
48
samples/website_integration/Sha256.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/***********************************************************
|
||||
* AuthMe website integration logic for SHA256 *
|
||||
* ------------------------------------------------------- *
|
||||
* See AuthMeController for details. *
|
||||
* *
|
||||
* Source: https://github.com/AuthMe-Team/AuthMeReloaded/ *
|
||||
***********************************************************/
|
||||
class Sha256 extends AuthMeController {
|
||||
|
||||
/** @var string[] range of characters for salt generation */
|
||||
private $CHARS;
|
||||
|
||||
const SALT_LENGTH = 16;
|
||||
|
||||
public function __construct() {
|
||||
$this->CHARS = self::initRandomChars();
|
||||
}
|
||||
|
||||
protected function isValidPassword($password, $hash) {
|
||||
// $SHA$salt$hash, where hash := sha256(sha256(password) . salt)
|
||||
$parts = explode('$', $hash);
|
||||
return count($parts) === 4 && $parts[3] === hash('sha256', hash('sha256', $password) . $parts[2]);
|
||||
}
|
||||
|
||||
protected function hash($password) {
|
||||
$salt = $this->generateSalt();
|
||||
return '$SHA$' . $salt . '$' . hash('sha256', hash('sha256', $password) . $salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string randomly generated salt
|
||||
*/
|
||||
private function generateSalt() {
|
||||
$maxCharIndex = count($this->CHARS) - 1;
|
||||
$salt = '';
|
||||
for ($i = 0; $i < self::SALT_LENGTH; ++$i) {
|
||||
$salt .= $this->CHARS[mt_rand(0, $maxCharIndex)];
|
||||
}
|
||||
return $salt;
|
||||
}
|
||||
|
||||
private static function initRandomChars() {
|
||||
return array_merge(range('0', '9'), range('a', 'f'));
|
||||
}
|
||||
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
<?php
|
||||
/*****************************************************************************
|
||||
* AuthMe website integration logic for BCrypt *
|
||||
* -------------------------------- *
|
||||
* Check with authme_check_password() whether the received username and *
|
||||
* password match the AuthMe MySQL database. Don't forget to adjust the *
|
||||
* database info in authme_get_hash(). *
|
||||
* *
|
||||
* Source: https://github.com/AuthMe-Team/AuthMeReloaded/ *
|
||||
*****************************************************************************/
|
||||
|
||||
/** The name of the authme MySQL table. */
|
||||
define('AUTHME_TABLE', 'authme');
|
||||
|
||||
|
||||
/**
|
||||
* Entry point function to check supplied credentials against the AuthMe database.
|
||||
*
|
||||
* @param string $username the username
|
||||
* @param string $password the password
|
||||
* @return bool true iff the data is correct, false otherwise
|
||||
*/
|
||||
function authme_check_password($username, $password) {
|
||||
if (is_scalar($username) && is_scalar($password)) {
|
||||
$hash = authme_get_hash($username);
|
||||
if ($hash) {
|
||||
return password_verify($password, $hash);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a connection to the database.
|
||||
*
|
||||
* @return mysqli|null the mysqli object or null upon error
|
||||
*/
|
||||
function authme_get_mysqli() {
|
||||
$mysqli = new mysqli('localhost', 'root', '', 'authme');
|
||||
if (mysqli_connect_error()) {
|
||||
printf('Could not connect to AuthMe database. Errno: %d, error: "%s"',
|
||||
mysqli_connect_errno(), mysqli_connect_error());
|
||||
return null;
|
||||
}
|
||||
return $mysqli;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hash associated with the given user from the database.
|
||||
*
|
||||
* @param string $username the username whose hash should be retrieved
|
||||
* @return string|null the hash, or null if unavailable (e.g. username doesn't exist)
|
||||
*/
|
||||
function authme_get_hash($username) {
|
||||
// Add here your database host, username, password and database name
|
||||
$mysqli = authme_get_mysqli();
|
||||
if ($mysqli !== null) {
|
||||
$stmt = $mysqli->prepare('SELECT password FROM ' . AUTHME_TABLE . ' WHERE username = ?');
|
||||
$stmt->bind_param('s', $username);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($password);
|
||||
if ($stmt->fetch()) {
|
||||
return $password;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user exists in the database or not.
|
||||
*
|
||||
* @param string $username the username to check
|
||||
* @return bool true if the user exists; false otherwise
|
||||
*/
|
||||
function authme_has_user($username) {
|
||||
$mysqli = authme_get_mysqli();
|
||||
if ($mysqli !== null) {
|
||||
$stmt = $mysqli->prepare('SELECT 1 FROM ' . AUTHME_TABLE . ' WHERE username = ?');
|
||||
$stmt->bind_param('s', $username);
|
||||
$stmt->execute();
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
// Defensive default to true; we actually don't know
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a player with the given username.
|
||||
*
|
||||
* @param string $username the username to register
|
||||
* @param string $password the password to associate to the user
|
||||
* @return bool whether or not the registration was successful
|
||||
*/
|
||||
function authme_register($username, $password) {
|
||||
$mysqli = authme_get_mysqli();
|
||||
if ($mysqli !== null) {
|
||||
$hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
$stmt = $mysqli->prepare('INSERT INTO ' . AUTHME_TABLE . ' (username, realname, password, ip) '
|
||||
. 'VALUES (?, ?, ?, ?)');
|
||||
$username_low = strtolower($username);
|
||||
$stmt->bind_param('ssss', $username, $username_low, $hash, $_SERVER['REMOTE_ADDR']);
|
||||
return $stmt->execute();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!--
|
||||
This is a demo page for AuthMe website integration with BCrypt.
|
||||
See integration.php for the PHP code you need.
|
||||
This is a demo page for AuthMe website integration.
|
||||
See AuthMeController.php and the extending classes for the PHP code you need.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@ -12,17 +12,23 @@
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require 'AuthMeController.php';
|
||||
|
||||
// Change this to the file of the hash encryption you need, e.g. Bcrypt.php or Sha256.php
|
||||
require 'Sha256.php';
|
||||
// The class name must correspond to the file you have in require above! e.g. require 'Sha256.php'; and new Sha256();
|
||||
$authme_controller = new Sha256();
|
||||
|
||||
$action = get_from_post_or_empty('action');
|
||||
$user = get_from_post_or_empty('username');
|
||||
$pass = get_from_post_or_empty('password');
|
||||
|
||||
$was_successful = false;
|
||||
if ($action && $user && $pass) {
|
||||
require_once('integration.php');
|
||||
if ($action === 'Log in') {
|
||||
$was_successful = process_login($user, $pass);
|
||||
$was_successful = process_login($user, $pass, $authme_controller);
|
||||
} else if ($action === 'Register') {
|
||||
$was_successful = process_register($user, $pass);
|
||||
$was_successful = process_register($user, $pass, $authme_controller);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,11 +56,11 @@ function get_from_post_or_empty($index_name) {
|
||||
|
||||
|
||||
// Login logic
|
||||
function process_login($user, $pass) {
|
||||
if (authme_check_password($user, $pass)) {
|
||||
function process_login($user, $pass, AuthMeController $controller) {
|
||||
if ($controller->checkPassword($user, $pass)) {
|
||||
printf('<h1>Hello, %s!</h1>', htmlspecialchars($user));
|
||||
echo 'Successful login. Nice to have you back!'
|
||||
. '<br /><a href="form.php">Back to form</a>';
|
||||
. '<br /><a href="index.php">Back to form</a>';
|
||||
return true;
|
||||
} else {
|
||||
echo '<h1>Error</h1> Invalid username or password.';
|
||||
@ -63,15 +69,15 @@ function process_login($user, $pass) {
|
||||
}
|
||||
|
||||
// Register logic
|
||||
function process_register($user, $pass) {
|
||||
if (authme_has_user($user)) {
|
||||
function process_register($user, $pass, AuthMeController $controller) {
|
||||
if ($controller->isUserRegistered($user)) {
|
||||
echo '<h1>Error</h1> This user already exists.';
|
||||
} else {
|
||||
// Note that we don't validate the password or username at all in this demo...
|
||||
$register_success = authme_register($user, $pass);
|
||||
$register_success = $controller->register($user, $pass);
|
||||
if ($register_success) {
|
||||
printf('<h1>Welcome, %s!</h1>Thanks for registering', htmlspecialchars($user));
|
||||
echo '<br /><a href="form.php">Back to form</a>';
|
||||
echo '<br /><a href="index.php">Back to form</a>';
|
||||
return true;
|
||||
} else {
|
||||
echo '<h1>Error</h1>Unfortunately, there was an error during the registration.';
|
@ -1,52 +0,0 @@
|
||||
<!--
|
||||
This is a demo page for AuthMe website integration with SHA256.
|
||||
See integration.php for the PHP code you need.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>AuthMe Integration Sample</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$user = get_from_post_or_empty('username');
|
||||
$pass = get_from_post_or_empty('password');
|
||||
|
||||
$was_successful = false;
|
||||
if ($user && $pass) {
|
||||
require_once('integration.php');
|
||||
if (authme_check_password($user, $pass)) {
|
||||
printf('<h1>Hello, %s!</h1>', htmlspecialchars($user));
|
||||
echo 'Successful login. Nice to have you back!'
|
||||
. '<br /><a href="form.php">Back to form</a>';
|
||||
$was_successful = true;
|
||||
} else {
|
||||
echo '<h1>Error</h1> Invalid username or password.';
|
||||
}
|
||||
}
|
||||
|
||||
if (!$was_successful) {
|
||||
echo '<h1>Login sample</h1>
|
||||
This is a demo form for AuthMe website integration. Enter your AuthMe login details
|
||||
into the following form to test it.
|
||||
<form method="post">
|
||||
<table>
|
||||
<tr><td>Name</td><td><input type="text" value="' . htmlspecialchars($user) . '" name="username" /></td></tr>
|
||||
<tr><td>Pass</td><td><input type="password" value="' . htmlspecialchars($pass) . '" name="password" /></td></tr>
|
||||
<tr><td colspan="2"><input type="submit" value=" Log in " /></td></tr>
|
||||
</table>
|
||||
</form>';
|
||||
}
|
||||
|
||||
function get_from_post_or_empty($index_name) {
|
||||
return trim(
|
||||
filter_input(INPUT_POST, $index_name, FILTER_UNSAFE_RAW, FILTER_REQUIRE_SCALAR | FILTER_FLAG_STRIP_LOW)
|
||||
?: '');
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
/*****************************************************************************
|
||||
* AuthMe website integration logic for SHA256 *
|
||||
* -------------------------------- *
|
||||
* Check with authme_check_password() whether the received username and *
|
||||
* password match the AuthMe MySQL database. Don't forget to adjust the *
|
||||
* database info in authme_get_hash(). *
|
||||
* *
|
||||
* Source: https://github.com/AuthMe-Team/AuthMeReloaded/ *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Entry point function to check supplied credentials against the AuthMe database.
|
||||
*
|
||||
* @param string $username the username
|
||||
* @param string $password the password
|
||||
* @return bool true iff the data is correct, false otherwise
|
||||
*/
|
||||
function authme_check_password($username, $password) {
|
||||
if (is_scalar($username) && is_scalar($password)) {
|
||||
$hash = authme_get_hash($username);
|
||||
if ($hash) {
|
||||
return authme_check_hash($password, $hash);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hash associated with the given user from the database.
|
||||
*
|
||||
* @param string $username the username whose hash should be retrieved
|
||||
* @return string|null the hash, or null if unavailable (e.g. username doesn't exist)
|
||||
*/
|
||||
function authme_get_hash($username) {
|
||||
// Add here your database host, username, password and database name
|
||||
$mysqli = new mysqli('HOST', 'USER', 'PWD', 'DB');
|
||||
$authme_table = 'authme';
|
||||
|
||||
if (mysqli_connect_error()) {
|
||||
printf('Could not connect to AuthMe database. Errno: %d, error: "%s"',
|
||||
mysqli_connect_errno(), mysqli_connect_error());
|
||||
} else {
|
||||
$stmt = $mysqli->prepare("SELECT password FROM $authme_table WHERE username = ?");
|
||||
$stmt->bind_param('s', $username);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($password);
|
||||
if ($stmt->fetch()) {
|
||||
return $password;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given clear-text password against the hash.
|
||||
*
|
||||
* @param string $password the clear-text password to check
|
||||
* @param string $hash the hash to check the password against
|
||||
* @return bool true iff the password matches the hash, false otherwise
|
||||
*/
|
||||
function authme_check_hash($password, $hash) {
|
||||
// $SHA$salt$hash, where hash := sha256(sha256(password) . salt)
|
||||
$parts = explode('$', $hash);
|
||||
return count($parts) === 4
|
||||
&& $parts[3] === hash('sha256', hash('sha256', $password) . $parts[2]);
|
||||
}
|
@ -9,8 +9,8 @@ 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 javax.inject.Inject;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_MINUTE;
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
|
||||
@ -24,11 +24,13 @@ public class AntiBot {
|
||||
private final Messages messages;
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final BukkitService bukkitService;
|
||||
private final List<String> antibotPlayers = new ArrayList<>();
|
||||
public final CopyOnWriteArrayList<String> antibotKicked = new CopyOnWriteArrayList<String>();
|
||||
private final CopyOnWriteArrayList<String> antibotPlayers = new CopyOnWriteArrayList<String>();
|
||||
private AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED;
|
||||
|
||||
public AntiBot(NewSetting settings, Messages messages, PermissionsManager permissionsManager,
|
||||
BukkitService bukkitService) {
|
||||
@Inject
|
||||
AntiBot(NewSetting settings, Messages messages, PermissionsManager permissionsManager,
|
||||
BukkitService bukkitService) {
|
||||
this.settings = settings;
|
||||
this.messages = messages;
|
||||
this.permissionsManager = permissionsManager;
|
||||
@ -75,6 +77,7 @@ public class AntiBot {
|
||||
if (antiBotStatus == AntiBotStatus.ACTIVE) {
|
||||
antiBotStatus = AntiBotStatus.LISTENING;
|
||||
antibotPlayers.clear();
|
||||
antibotKicked.clear();
|
||||
for (String s : messages.retrieve(MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE)) {
|
||||
bukkitService.broadcastMessage(s.replace("%m", Integer.toString(duration)));
|
||||
}
|
||||
@ -83,7 +86,12 @@ public class AntiBot {
|
||||
}, duration * TICKS_PER_MINUTE);
|
||||
}
|
||||
|
||||
public void checkAntiBot(final Player player) {
|
||||
/**
|
||||
* Handles a player joining the server and checks if AntiBot needs to be activated.
|
||||
*
|
||||
* @param player the player who joined the server
|
||||
*/
|
||||
public void handlePlayerJoin(final Player player) {
|
||||
if (antiBotStatus == AntiBotStatus.ACTIVE || antiBotStatus == AntiBotStatus.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,32 +1,5 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.api.NewAPI;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
@ -34,12 +7,7 @@ import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
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.command.CommandDescription;
|
||||
import fr.xephi.authme.command.CommandHandler;
|
||||
import fr.xephi.authme.command.CommandInitializer;
|
||||
import fr.xephi.authme.command.CommandMapper;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import fr.xephi.authme.datasource.CacheDataSource;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
@ -48,13 +16,15 @@ import fr.xephi.authme.datasource.MySQL;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.hooks.BungeeCordMessage;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.initialization.MetricsStarter;
|
||||
import fr.xephi.authme.listener.AuthMeBlockListener;
|
||||
import fr.xephi.authme.listener.AuthMeEntityListener;
|
||||
import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener16;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener18;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener19;
|
||||
import fr.xephi.authme.listener.AuthMeServerListener;
|
||||
import fr.xephi.authme.listener.AuthMeTabCompletePacketAdapter;
|
||||
import fr.xephi.authme.listener.AuthMeTablistPacketAdapter;
|
||||
@ -64,9 +34,7 @@ import fr.xephi.authme.output.Log4JFilter;
|
||||
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.process.ProcessService;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.SHA256;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
@ -82,6 +50,7 @@ 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.task.PurgeTask;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
@ -89,7 +58,32 @@ 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 fr.xephi.authme.util.ValidationService;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
|
||||
|
||||
/**
|
||||
* The AuthMe main class.
|
||||
@ -105,17 +99,13 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
// Private Instances
|
||||
private static AuthMe plugin;
|
||||
private static Server server;
|
||||
/*
|
||||
* Maps and stuff
|
||||
*/
|
||||
// TODO #601: Integrate CaptchaManager
|
||||
public final ConcurrentHashMap<String, BukkitTask> sessions = new ConcurrentHashMap<>();
|
||||
public final ConcurrentHashMap<String, Integer> captcha = new ConcurrentHashMap<>();
|
||||
public final ConcurrentHashMap<String, String> cap = new ConcurrentHashMap<>();
|
||||
|
||||
/*
|
||||
* Public Instances
|
||||
* Public instances
|
||||
*/
|
||||
public NewAPI api;
|
||||
// TODO #655: Encapsulate mail
|
||||
@ -124,7 +114,6 @@ public class AuthMe extends JavaPlugin {
|
||||
public DataManager dataManager;
|
||||
/*
|
||||
* Private instances
|
||||
* TODO #432: Move instantiation and management of these services
|
||||
*/
|
||||
// TODO #604: Encapsulate ProtocolLib members
|
||||
public AuthMeInventoryPacketAdapter inventoryProtector;
|
||||
@ -140,15 +129,16 @@ public class AuthMe extends JavaPlugin {
|
||||
private DataSource database;
|
||||
private PluginHooks pluginHooks;
|
||||
private SpawnLoader spawnLoader;
|
||||
private AntiBot antiBot;
|
||||
private boolean autoPurging;
|
||||
private BukkitService bukkitService;
|
||||
private AuthMeServiceInitializer initializer;
|
||||
|
||||
/**
|
||||
* Get the plugin's instance.
|
||||
*
|
||||
* @return AuthMe
|
||||
*/
|
||||
@Deprecated
|
||||
public static AuthMe getInstance() {
|
||||
return plugin;
|
||||
}
|
||||
@ -180,24 +170,6 @@ public class AuthMe extends JavaPlugin {
|
||||
return pluginBuildNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Messages instance.
|
||||
*
|
||||
* @return Plugin's messages.
|
||||
*/
|
||||
public Messages getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin's NewSetting instance.
|
||||
*
|
||||
* @return NewSetting.
|
||||
*/
|
||||
public NewSetting getSettings() {
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
// Get version and build number of the plugin
|
||||
private void setPluginInfos() {
|
||||
String versionRaw = this.getDescription().getVersion();
|
||||
@ -217,25 +189,23 @@ public class AuthMe extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Set various instances
|
||||
server = getServer();
|
||||
plugin = this;
|
||||
ConsoleLogger.setLogger(getLogger());
|
||||
|
||||
setPluginInfos();
|
||||
|
||||
// Load settings and custom configurations, if it fails, stop the server due to security reasons.
|
||||
newSettings = createNewSetting();
|
||||
if (newSettings == null) {
|
||||
ConsoleLogger.showError("Could not load configuration. Aborting.");
|
||||
server.shutdown();
|
||||
getLogger().warning("Could not load configuration. Aborting.");
|
||||
getServer().shutdown();
|
||||
return;
|
||||
}
|
||||
ConsoleLogger.setLoggingOptions(newSettings.getProperty(SecuritySettings.USE_LOGGING),
|
||||
new File(getDataFolder(), "authme.log"));
|
||||
ConsoleLogger.setLogFile(new File(getDataFolder(), "authme.log"));
|
||||
ConsoleLogger.setLoggingOptions(newSettings);
|
||||
|
||||
// Old settings manager
|
||||
if (!loadSettings()) {
|
||||
server.shutdown();
|
||||
getServer().shutdown();
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
@ -251,23 +221,43 @@ public class AuthMe extends JavaPlugin {
|
||||
stopOrUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
bukkitService = new BukkitService(this);
|
||||
pluginHooks = new PluginHooks(server.getPluginManager());
|
||||
|
||||
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
|
||||
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager());
|
||||
|
||||
// Initialize spawn loader
|
||||
spawnLoader = new SpawnLoader(getDataFolder(), newSettings, pluginHooks);
|
||||
permsMan = initializePermissionsManager();
|
||||
antiBot = new AntiBot(newSettings, messages, permsMan, bukkitService);
|
||||
ValidationService validationService = new ValidationService(newSettings, database, permsMan);
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings,
|
||||
pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
|
||||
|
||||
initializer = new AuthMeServiceInitializer("fr.xephi.authme");
|
||||
// Register elements of the Bukkit / JavaPlugin environment
|
||||
initializer.register(AuthMe.class, this);
|
||||
initializer.register(Server.class, getServer());
|
||||
initializer.register(PluginManager.class, getServer().getPluginManager());
|
||||
initializer.register(BukkitScheduler.class, getServer().getScheduler());
|
||||
initializer.provide(DataFolder.class, getDataFolder());
|
||||
|
||||
// Register elements we instantiate manually
|
||||
initializer.register(NewSetting.class, newSettings);
|
||||
initializer.register(Messages.class, messages);
|
||||
initializer.register(DataSource.class, database);
|
||||
|
||||
// Some statically injected things
|
||||
initializer.register(PlayerCache.class, PlayerCache.getInstance());
|
||||
|
||||
// Note ljacqu 20160612: Instantiate LimboCache first to make sure it is instantiated
|
||||
// (because sometimes it's used via LimboCache.getInstance())
|
||||
// Once LimboCache#getInstance() no longer exists this can be removed!
|
||||
initializer.get(LimboCache.class);
|
||||
|
||||
permsMan = initializer.get(PermissionsManager.class);
|
||||
bukkitService = initializer.get(BukkitService.class);
|
||||
pluginHooks = initializer.get(PluginHooks.class);
|
||||
passwordSecurity = initializer.get(PasswordSecurity.class);
|
||||
spawnLoader = initializer.get(SpawnLoader.class);
|
||||
commandHandler = initializer.get(CommandHandler.class);
|
||||
api = initializer.get(NewAPI.class);
|
||||
management = initializer.get(Management.class);
|
||||
dataManager = initializer.get(DataManager.class);
|
||||
initializer.get(API.class);
|
||||
|
||||
// Set up Metrics
|
||||
MetricsStarter.setupMetrics(plugin, newSettings);
|
||||
MetricsStarter.setupMetrics(this, newSettings);
|
||||
|
||||
// Set console filter
|
||||
setupConsoleFilter();
|
||||
@ -284,32 +274,21 @@ public class AuthMe extends JavaPlugin {
|
||||
// End of Hooks
|
||||
|
||||
// Do a backup on start
|
||||
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.START);
|
||||
new PerformBackup(this, newSettings).doBackup(PerformBackup.BackupCause.START);
|
||||
|
||||
|
||||
// Setup the inventory backup
|
||||
playerBackup = new JsonCache();
|
||||
|
||||
// Set the DataManager
|
||||
dataManager = new DataManager(this, pluginHooks, bukkitService);
|
||||
|
||||
// Set up the new API
|
||||
setupApi();
|
||||
|
||||
// Set up the management
|
||||
ProcessService processService = new ProcessService(newSettings, messages, this, database,
|
||||
passwordSecurity, pluginHooks, spawnLoader, validationService, bukkitService);
|
||||
management = new Management(this, processService, database, PlayerCache.getInstance());
|
||||
|
||||
// Set up the BungeeCord hook
|
||||
setupBungeeCordHook(newSettings);
|
||||
setupBungeeCordHook(newSettings, initializer);
|
||||
|
||||
// Reload support hook
|
||||
reloadSupportHook();
|
||||
|
||||
// Register event listeners
|
||||
registerEventListeners(
|
||||
messages, database, management, pluginHooks, spawnLoader, antiBot, bukkitService, validationService);
|
||||
registerEventListeners(initializer);
|
||||
// Start Email recall task if needed
|
||||
scheduleRecallEmailTask();
|
||||
|
||||
@ -327,23 +306,6 @@ public class AuthMe extends JavaPlugin {
|
||||
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();
|
||||
spawnLoader.initialize(newSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the mail API, if enabled.
|
||||
*/
|
||||
@ -373,38 +335,27 @@ public class AuthMe extends JavaPlugin {
|
||||
/**
|
||||
* Register all event listeners.
|
||||
*/
|
||||
private void registerEventListeners(Messages messages, DataSource dataSource, Management management,
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
|
||||
BukkitService bukkitService, ValidationService validationService) {
|
||||
private void registerEventListeners(AuthMeServiceInitializer initializer) {
|
||||
// Get the plugin manager instance
|
||||
PluginManager pluginManager = server.getPluginManager();
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
|
||||
// Register event listeners
|
||||
pluginManager.registerEvents(new AuthMePlayerListener(
|
||||
this, newSettings, messages, dataSource, antiBot, management, bukkitService, validationService), this);
|
||||
pluginManager.registerEvents(new AuthMeBlockListener(), this);
|
||||
pluginManager.registerEvents(new AuthMeEntityListener(), this);
|
||||
pluginManager.registerEvents(new AuthMeServerListener(
|
||||
this, messages, newSettings, pluginHooks, spawnLoader, validationService), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMeEntityListener.class), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMeServerListener.class), this);
|
||||
|
||||
// Try to register 1.6 player listeners
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
|
||||
pluginManager.registerEvents(new AuthMePlayerListener16(), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener16.class), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// Try to register 1.8 player listeners
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
|
||||
pluginManager.registerEvents(new AuthMePlayerListener18(), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// Try to register 1.9 player listeners
|
||||
try {
|
||||
Class.forName("org.spigotmc.event.player.PlayerSpawnLocationEvent");
|
||||
pluginManager.registerEvents(new AuthMePlayerListener19(this), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener18.class), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
@ -430,38 +381,14 @@ public class AuthMe extends JavaPlugin {
|
||||
/**
|
||||
* Set up the BungeeCord hook.
|
||||
*/
|
||||
private void setupBungeeCordHook(NewSetting settings) {
|
||||
private void setupBungeeCordHook(NewSetting settings, AuthMeServiceInitializer initializer) {
|
||||
if (settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
Bukkit.getMessenger().registerIncomingPluginChannel(
|
||||
this, "BungeeCord", new BungeeCordMessage(this));
|
||||
this, "BungeeCord", initializer.get(BungeeCordMessage.class));
|
||||
}
|
||||
}
|
||||
|
||||
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
|
||||
PasswordSecurity passwordSecurity, NewSetting settings,
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
|
||||
ValidationService validationService, BukkitService bukkitService) {
|
||||
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
|
||||
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
|
||||
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
|
||||
CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity,
|
||||
permissionsManager, settings, pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
|
||||
return new CommandHandler(commandService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the API. This sets up the new and the old API.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void setupApi() {
|
||||
// Set up the API
|
||||
api = new NewAPI(this);
|
||||
|
||||
// Set up the deprecated API
|
||||
new API(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the plugin's settings.
|
||||
*
|
||||
@ -474,7 +401,7 @@ public class AuthMe extends JavaPlugin {
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.logException("Can't load the configuration file... Something went wrong. "
|
||||
+ "To avoid security issues the server will shut down!", e);
|
||||
server.shutdown();
|
||||
getServer().shutdown();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -492,7 +419,7 @@ public class AuthMe extends JavaPlugin {
|
||||
* Set up the console filter.
|
||||
*/
|
||||
private void setupConsoleFilter() {
|
||||
if (Settings.removePassword) {
|
||||
if (newSettings.getProperty(SecuritySettings.REMOVE_PASSWORD_FROM_CONSOLE)) {
|
||||
ConsoleFilter filter = new ConsoleFilter();
|
||||
getLogger().setFilter(filter);
|
||||
Bukkit.getLogger().setFilter(filter);
|
||||
@ -510,33 +437,37 @@ public class AuthMe extends JavaPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Save player data
|
||||
if (bukkitService != null) {
|
||||
BukkitService bukkitService = initializer.getIfAvailable(BukkitService.class);
|
||||
LimboCache limboCache = initializer.getIfAvailable(LimboCache.class);
|
||||
|
||||
if (bukkitService != null && limboCache != null) {
|
||||
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
|
||||
for (Player player : players) {
|
||||
savePlayer(player);
|
||||
savePlayer(player, limboCache);
|
||||
}
|
||||
}
|
||||
|
||||
// Do backup on stop if enabled
|
||||
if (newSettings != null) {
|
||||
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.STOP);
|
||||
new PerformBackup(this, newSettings).doBackup(PerformBackup.BackupCause.STOP);
|
||||
}
|
||||
final AuthMe pluginInstance = this;
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Integer> pendingTasks = new ArrayList<>();
|
||||
for (BukkitTask pendingTask : getServer().getScheduler().getPendingTasks()) {
|
||||
if (pendingTask.getOwner().equals(plugin) && !pendingTask.isSync()) {
|
||||
if (pendingTask.getOwner().equals(pluginInstance) && !pendingTask.isSync()) {
|
||||
pendingTasks.add(pendingTask.getTaskId());
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("Waiting for " + pendingTasks.size() + " tasks to finish");
|
||||
getLogger().info("Waiting for " + pendingTasks.size() + " tasks to finish");
|
||||
int progress = 0;
|
||||
for (int taskId : pendingTasks) {
|
||||
int maxTries = 5;
|
||||
while (getServer().getScheduler().isCurrentlyRunning(taskId)) {
|
||||
if (maxTries <= 0) {
|
||||
ConsoleLogger.info("Async task " + taskId + " times out after to many tries");
|
||||
getLogger().info("Async task " + taskId + " times out after to many tries");
|
||||
break;
|
||||
}
|
||||
try {
|
||||
@ -547,7 +478,7 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
progress++;
|
||||
ConsoleLogger.info("Progress: " + progress + " / " + pendingTasks.size());
|
||||
getLogger().info("Progress: " + progress + " / " + pendingTasks.size());
|
||||
}
|
||||
if (database != null) {
|
||||
database.close();
|
||||
@ -555,19 +486,18 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
}, "AuthMe-DataSource#close").start();
|
||||
|
||||
// Close the database
|
||||
|
||||
// Disabled correctly
|
||||
ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!");
|
||||
ConsoleLogger.close();
|
||||
}
|
||||
|
||||
// Stop/unload the server/plugin as defined in the configuration
|
||||
public void stopOrUnload() {
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("THE SERVER IS GOING TO SHUT DOWN AS DEFINED IN THE CONFIGURATION!");
|
||||
server.shutdown();
|
||||
getServer().shutdown();
|
||||
} else {
|
||||
server.getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
@ -610,7 +540,7 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
database = dataSource;
|
||||
if (DataSourceType.SQLITE == dataSourceType) {
|
||||
server.getScheduler().runTaskAsynchronously(this, new Runnable() {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int accounts = database.getAccountsRegistered();
|
||||
@ -623,15 +553,6 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the permissions manager.
|
||||
*/
|
||||
private PermissionsManager initializePermissionsManager() {
|
||||
PermissionsManager manager = new PermissionsManager(Bukkit.getServer(), getLogger());
|
||||
manager.setup();
|
||||
return manager;
|
||||
}
|
||||
|
||||
// Set the console filter to remove the passwords
|
||||
private void setLog4JFilter() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
@ -648,7 +569,7 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
// Check the presence of the ProtocolLib plugin
|
||||
public void checkProtocolLib() {
|
||||
if (!server.getPluginManager().isPluginEnabled("ProtocolLib")) {
|
||||
if (!getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
|
||||
if (newSettings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||
ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
|
||||
Settings.protectInventoryBeforeLogInEnabled = false;
|
||||
@ -682,8 +603,8 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
// Save Player Data
|
||||
private void savePlayer(Player player) {
|
||||
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
|
||||
private void savePlayer(Player player, LimboCache limboCache) {
|
||||
if (safeIsNpc(player) || Utils.isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
String name = player.getName().toLowerCase();
|
||||
@ -694,8 +615,8 @@ public class AuthMe extends JavaPlugin {
|
||||
.location(player.getLocation()).build();
|
||||
database.updateQuitLoc(auth);
|
||||
}
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (limboCache.hasLimboPlayer(name)) {
|
||||
LimboPlayer limbo = limboCache.getLimboPlayer(name);
|
||||
if (!Settings.noTeleport) {
|
||||
player.teleport(limbo.getLoc());
|
||||
}
|
||||
@ -703,7 +624,7 @@ public class AuthMe extends JavaPlugin {
|
||||
Utils.addNormal(player, limbo.getGroup());
|
||||
player.setOp(limbo.isOperator());
|
||||
limbo.getTimeoutTask().cancel();
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
limboCache.deleteLimboPlayer(name);
|
||||
if (this.playerBackup.doesCacheExist(player)) {
|
||||
this.playerBackup.removeCache(player);
|
||||
}
|
||||
@ -711,14 +632,8 @@ public class AuthMe extends JavaPlugin {
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
}
|
||||
|
||||
// Select the player to kick when a vip player joins the server when full
|
||||
public Player generateKickPlayer(Collection<? extends Player> collection) {
|
||||
for (Player player : collection) {
|
||||
if (!getPermissionsManager().hasPermission(player, PlayerStatePermission.IS_VIP)) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
private boolean safeIsNpc(Player player) {
|
||||
return pluginHooks != null && pluginHooks.isNpc(player) || player.hasMetadata("NPC");
|
||||
}
|
||||
|
||||
// Purge inactive players from the database, as defined in the configuration
|
||||
@ -726,33 +641,22 @@ public class AuthMe extends JavaPlugin {
|
||||
if (!newSettings.getProperty(PurgeSettings.USE_AUTO_PURGE) || autoPurging) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
||||
ConsoleLogger.info("AutoPurging the Database...");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DATE, -newSettings.getProperty(PurgeSettings.DAYS_BEFORE_REMOVE_PLAYER));
|
||||
long until = calendar.getTimeInMillis();
|
||||
Set<String> cleared = database.autoPurgeDatabase(until);
|
||||
if (CollectionUtils.isEmpty(cleared)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConsoleLogger.info("AutoPurging the Database: " + cleared.size() + " accounts removed!");
|
||||
ConsoleLogger.info("Purging user accounts...");
|
||||
new PurgeTask(plugin, Bukkit.getConsoleSender(), cleared, true, Bukkit.getOfflinePlayers())
|
||||
.runTaskTimer(plugin, 0, 1);
|
||||
}
|
||||
|
||||
// Return the spawn location of a player
|
||||
@ -784,6 +688,7 @@ public class AuthMe extends JavaPlugin {
|
||||
public String replaceAllInfo(String message, Player player) {
|
||||
String playersOnline = Integer.toString(bukkitService.getOnlinePlayers().size());
|
||||
String ipAddress = Utils.getPlayerIp(player);
|
||||
Server server = getServer();
|
||||
return message
|
||||
.replace("&", "\u00a7")
|
||||
.replace("{PLAYER}", player.getName())
|
||||
@ -797,17 +702,7 @@ public class AuthMe extends JavaPlugin {
|
||||
.replace("{COUNTRY}", GeoLiteAPI.getCountryName(ipAddress));
|
||||
}
|
||||
|
||||
public boolean isLoggedIp(String name, String ip) {
|
||||
int count = 0;
|
||||
for (Player player : bukkitService.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(Utils.getPlayerIp(player))
|
||||
&& database.isLogged(player.getName().toLowerCase())
|
||||
&& !player.getName().equalsIgnoreCase(name)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count >= Settings.getMaxLoginPerIp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle Bukkit commands.
|
||||
@ -832,34 +727,66 @@ public class AuthMe extends JavaPlugin {
|
||||
return commandHandler.processCommand(sender, commandLabel, args);
|
||||
}
|
||||
|
||||
public void notifyAutoPurgeEnd() {
|
||||
this.autoPurging = false;
|
||||
}
|
||||
|
||||
|
||||
// -------------
|
||||
// Service getters (deprecated)
|
||||
// Use @Inject fields instead
|
||||
// -------------
|
||||
/**
|
||||
* Get the permissions manager instance.
|
||||
*
|
||||
* @return Permissions Manager instance.
|
||||
* @return NewSetting
|
||||
* @deprecated should be used in API classes only (temporarily)
|
||||
*/
|
||||
@Deprecated
|
||||
public NewSetting getSettings() {
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return permission manager
|
||||
* @deprecated should be used in API classes only (temporarily)
|
||||
*/
|
||||
@Deprecated
|
||||
public PermissionsManager getPermissionsManager() {
|
||||
return this.permsMan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the management instance.
|
||||
*
|
||||
* @return management The Management
|
||||
* @return process manager
|
||||
* @deprecated should be used in API classes only (temporarily)
|
||||
*/
|
||||
@Deprecated
|
||||
public Management getManagement() {
|
||||
return management;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the datasource
|
||||
* @deprecated should be used in API classes only (temporarily)
|
||||
*/
|
||||
@Deprecated
|
||||
public DataSource getDataSource() {
|
||||
return database;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return password manager
|
||||
* @deprecated should be used in API classes only (temporarily)
|
||||
*/
|
||||
@Deprecated
|
||||
public PasswordSecurity getPasswordSecurity() {
|
||||
return passwordSecurity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return plugin hooks
|
||||
* @deprecated should be used in API classes only (temporarily)
|
||||
*/
|
||||
@Deprecated
|
||||
public PluginHooks getPluginHooks() {
|
||||
return pluginHooks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@ -20,22 +22,38 @@ public final class ConsoleLogger {
|
||||
private static final String NEW_LINE = System.getProperty("line.separator");
|
||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("[MM-dd HH:mm:ss]");
|
||||
private static Logger logger;
|
||||
private static boolean enableDebug = false;
|
||||
private static boolean useLogging = false;
|
||||
private static File logFile;
|
||||
private static FileWriter fileWriter;
|
||||
|
||||
private ConsoleLogger() {
|
||||
// Service class
|
||||
}
|
||||
|
||||
public static void setLogger(Logger logger) {
|
||||
ConsoleLogger.logger = logger;
|
||||
}
|
||||
|
||||
public static void setLoggingOptions(boolean useLogging, File logFile) {
|
||||
ConsoleLogger.useLogging = useLogging;
|
||||
public static void setLogFile(File logFile) {
|
||||
ConsoleLogger.logFile = logFile;
|
||||
}
|
||||
|
||||
public static void setLoggingOptions(NewSetting settings) {
|
||||
ConsoleLogger.useLogging = settings.getProperty(SecuritySettings.USE_LOGGING);
|
||||
ConsoleLogger.enableDebug = !settings.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE);
|
||||
if (useLogging) {
|
||||
if (fileWriter == null) {
|
||||
try {
|
||||
fileWriter = new FileWriter(logFile, true);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Failed to create the log file:", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an info message.
|
||||
*
|
||||
@ -46,6 +64,20 @@ public final class ConsoleLogger {
|
||||
if (useLogging) {
|
||||
writeLog(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void debug(String message) {
|
||||
if (enableDebug) {
|
||||
//creating and filling an exception is a expensive call
|
||||
//TODO #419 20160601: ->so it should be removed as soon #419 is fixed
|
||||
//logger.isLoggable does not work because the plugin logger is always ALL
|
||||
logger.log(Level.FINE, message + ' ' + Thread.currentThread().getName(), new Exception());
|
||||
|
||||
if (useLogging) {
|
||||
writeLog("Debug: " + Thread.currentThread().getName() + ':' + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,9 +103,11 @@ public final class ConsoleLogger {
|
||||
dateTime = DATE_FORMAT.format(new Date());
|
||||
}
|
||||
try {
|
||||
Files.write(logFile.toPath(), (dateTime + ": " + message + NEW_LINE).getBytes(),
|
||||
StandardOpenOption.APPEND,
|
||||
StandardOpenOption.CREATE);
|
||||
fileWriter.write(dateTime);
|
||||
fileWriter.write(": ");
|
||||
fileWriter.write(message);
|
||||
fileWriter.write(NEW_LINE);
|
||||
fileWriter.flush();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
@ -93,10 +127,21 @@ public final class ConsoleLogger {
|
||||
* Logs a Throwable with the provided message and saves the stack trace to the log file.
|
||||
*
|
||||
* @param message The message to accompany the exception
|
||||
* @param th The Throwable to log
|
||||
* @param th The Throwable to log
|
||||
*/
|
||||
public static void logException(String message, Throwable th) {
|
||||
showError(message + " " + StringUtils.formatException(th));
|
||||
writeStackTrace(th);
|
||||
}
|
||||
|
||||
public static void close() {
|
||||
if (fileWriter != null) {
|
||||
try {
|
||||
fileWriter.flush();
|
||||
fileWriter.close();
|
||||
fileWriter = null;
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,52 +2,44 @@ package fr.xephi.authme;
|
||||
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.PurgeSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class DataManager {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final BukkitService bukkitService;
|
||||
@Inject
|
||||
private Server server;
|
||||
@Inject
|
||||
private PluginHooks pluginHooks;
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
@Inject
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public DataManager(AuthMe plugin, PluginHooks pluginHooks, BukkitService bukkitService) {
|
||||
this.plugin = plugin;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
DataManager() { }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void purgeAntiXray(List<String> cleared) {
|
||||
public void purgeAntiXray(Set<String> cleared) {
|
||||
int i = 0;
|
||||
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);
|
||||
@ -56,10 +48,11 @@ public class DataManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " AntiXRayData Files");
|
||||
}
|
||||
|
||||
public synchronized void purgeLimitedCreative(List<String> cleared) {
|
||||
public synchronized void purgeLimitedCreative(Set<String> cleared) {
|
||||
int i = 0;
|
||||
File dataFolder = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative"
|
||||
+ File.separator + "inventories");
|
||||
@ -96,18 +89,18 @@ public class DataManager {
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " LimitedCreative Survival, Creative and Adventure files");
|
||||
}
|
||||
|
||||
public synchronized void purgeDat(List<String> cleared) {
|
||||
public synchronized void purgeDat(Set<OfflinePlayer> 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");
|
||||
File dataFolder = new File(server.getWorldContainer()
|
||||
, makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players"));
|
||||
|
||||
for (OfflinePlayer offlinePlayer : cleared) {
|
||||
File playerFile = new File(dataFolder, Utils.getUUIDorName(offlinePlayer) + ".dat");
|
||||
if (playerFile.delete()) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleLogger.info("AutoPurge: Removed " + i + " .dat Files");
|
||||
}
|
||||
|
||||
@ -116,7 +109,7 @@ public class DataManager {
|
||||
*
|
||||
* @param cleared List of String
|
||||
*/
|
||||
public void purgeEssentials(List<String> cleared) {
|
||||
public void purgeEssentials(Set<OfflinePlayer> cleared) {
|
||||
int i = 0;
|
||||
File essentialsDataFolder = pluginHooks.getEssentialsDataFolder();
|
||||
if (essentialsDataFolder == null) {
|
||||
@ -128,9 +121,9 @@ public class DataManager {
|
||||
if (!userDataFolder.exists() || !userDataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
|
||||
for (OfflinePlayer player : offlinePlayers) {
|
||||
File playerFile = new File(userDataFolder, Utils.getUUIDorName(player) + ".yml");
|
||||
|
||||
for (OfflinePlayer offlinePlayer : cleared) {
|
||||
File playerFile = new File(userDataFolder, Utils.getUUIDorName(offlinePlayer) + ".yml");
|
||||
if (playerFile.exists() && playerFile.delete()) {
|
||||
i++;
|
||||
}
|
||||
@ -141,16 +134,12 @@ public class DataManager {
|
||||
|
||||
// TODO: What is this method for? Is it correct?
|
||||
// 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 = plugin.getPermissionsManager();
|
||||
if (permsMan == null) {
|
||||
ConsoleLogger.showError("Unable to access permissions manager instance!");
|
||||
return;
|
||||
}
|
||||
for (String name : cleared) {
|
||||
permsMan.removeAllGroups(bukkitService.getPlayerExact(name));
|
||||
public synchronized void purgePermissions(Set<OfflinePlayer> cleared) {
|
||||
for (OfflinePlayer offlinePlayer : cleared) {
|
||||
String name = offlinePlayer.getName();
|
||||
permissionsManager.removeAllGroups(bukkitService.getPlayerExact(name));
|
||||
}
|
||||
|
||||
ConsoleLogger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s).");
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package fr.xephi.authme.api;
|
||||
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.process.Management;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
@ -12,6 +14,8 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Deprecated API of AuthMe. Please use {@link NewAPI} instead.
|
||||
*/
|
||||
@ -20,7 +24,9 @@ public class API {
|
||||
|
||||
public static final String newline = System.getProperty("line.separator");
|
||||
public static AuthMe instance;
|
||||
private static DataSource dataSource;
|
||||
private static PasswordSecurity passwordSecurity;
|
||||
private static Management management;
|
||||
|
||||
/**
|
||||
* Constructor for the deprecated API.
|
||||
@ -28,9 +34,12 @@ public class API {
|
||||
* @param instance AuthMe
|
||||
*/
|
||||
@Deprecated
|
||||
public API(AuthMe instance) {
|
||||
@Inject
|
||||
API(AuthMe instance, DataSource dataSource, PasswordSecurity passwordSecurity, Management management) {
|
||||
API.instance = instance;
|
||||
passwordSecurity = instance.getPasswordSecurity();
|
||||
API.dataSource = dataSource;
|
||||
API.passwordSecurity = passwordSecurity;
|
||||
API.management = management;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +118,7 @@ public class API {
|
||||
@Deprecated
|
||||
public static boolean isRegistered(String playerName) {
|
||||
String player = playerName.toLowerCase();
|
||||
return instance.getDataSource().isAuthAvailable(player);
|
||||
return dataSource.isAuthAvailable(player);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +153,7 @@ public class API {
|
||||
.lastLogin(0)
|
||||
.realName(playerName)
|
||||
.build();
|
||||
return instance.getDataSource().saveAuth(auth);
|
||||
return dataSource.saveAuth(auth);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +163,7 @@ public class API {
|
||||
*/
|
||||
@Deprecated
|
||||
public static void forceLogin(Player player) {
|
||||
instance.getManagement().performLogin(player, "dontneed", true);
|
||||
management.performLogin(player, "dontneed", true);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ -170,7 +179,7 @@ public class API {
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isNPC(Player player) {
|
||||
return Utils.isNPC(player);
|
||||
return instance.getPluginHooks().isNpc(player);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package fr.xephi.authme.api;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* The current API of AuthMe. Recommended method of retrieving the API object:
|
||||
@ -28,19 +28,11 @@ public class NewAPI {
|
||||
*
|
||||
* @param plugin The AuthMe plugin instance
|
||||
*/
|
||||
@Inject
|
||||
public NewAPI(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for NewAPI.
|
||||
*
|
||||
* @param server The server instance
|
||||
*/
|
||||
public NewAPI(Server server) {
|
||||
this.plugin = (AuthMe) server.getPluginManager().getPlugin("AuthMe");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API object for AuthMe.
|
||||
*
|
||||
@ -96,7 +88,7 @@ public class NewAPI {
|
||||
* @return true if the player is an npc
|
||||
*/
|
||||
public boolean isNPC(Player player) {
|
||||
return Utils.isNPC(player);
|
||||
return plugin.getPluginHooks().isNpc(player);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,10 +140,11 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a player with the given password.
|
||||
* Register an OFFLINE/ONLINE 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) {
|
||||
@ -187,13 +180,24 @@ public class NewAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a player with the given password.
|
||||
* Force an ONLINE player to register.
|
||||
*
|
||||
* @param player The player to register
|
||||
* @param password The password to use
|
||||
* @param autoLogin Should the player be authenticated automatically after the registration?
|
||||
*/
|
||||
public void forceRegister(Player player, String password, boolean autoLogin) {
|
||||
plugin.getManagement().performRegister(player, password, null, autoLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an ONLINE player with the given password.
|
||||
*
|
||||
* @param player The player to register
|
||||
* @param password The password to use
|
||||
*/
|
||||
public void forceRegister(Player player, String password) {
|
||||
plugin.getManagement().performRegister(player, password, null);
|
||||
forceRegister(player, password, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,81 +1,132 @@
|
||||
package fr.xephi.authme.cache;
|
||||
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Manager for the handling of captchas.
|
||||
*/
|
||||
public class CaptchaManager {
|
||||
public class CaptchaManager implements SettingsDependent {
|
||||
|
||||
private final int threshold;
|
||||
private final int captchaLength;
|
||||
private final ConcurrentHashMap<String, Integer> playerCounts;
|
||||
private final ConcurrentHashMap<String, String> captchaCodes;
|
||||
|
||||
public CaptchaManager(NewSetting settings) {
|
||||
private boolean isEnabled;
|
||||
private int threshold;
|
||||
private int captchaLength;
|
||||
|
||||
@Inject
|
||||
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);
|
||||
loadSettings(settings);
|
||||
}
|
||||
|
||||
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);
|
||||
/**
|
||||
* Increases the failure count for the given player.
|
||||
*
|
||||
* @param name the player's name
|
||||
*/
|
||||
public void increaseCount(String name) {
|
||||
if (isEnabled) {
|
||||
String playerLower = name.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.
|
||||
* Returns 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
|
||||
* @param name the name of 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;
|
||||
public boolean isCaptchaRequired(String name) {
|
||||
if (isEnabled) {
|
||||
Integer count = playerCounts.get(name.toLowerCase());
|
||||
return count != null && count >= threshold;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the captcha code for the player. Creates one if none present, so call only after
|
||||
* checking with {@link #isCaptchaRequired}.
|
||||
* Returns the stored captcha code for the player.
|
||||
*
|
||||
* @param player The player
|
||||
* @return The code required for the player
|
||||
* @param name the player's name
|
||||
* @return the code the player is required to enter, or null if none registered
|
||||
*/
|
||||
public String getCaptchaCode(String player) {
|
||||
String code = captchaCodes.get(player.toLowerCase());
|
||||
if (code == null) {
|
||||
code = RandomString.generate(captchaLength);
|
||||
captchaCodes.put(player.toLowerCase(), code);
|
||||
}
|
||||
public String getCaptchaCode(String name) {
|
||||
return captchaCodes.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored captcha for the player or generates and saves a new one.
|
||||
*
|
||||
* @param name the player's name
|
||||
* @return the code the player is required to enter
|
||||
*/
|
||||
public String getCaptchaCodeOrGenerateNew(String name) {
|
||||
String code = getCaptchaCode(name);
|
||||
return code == null ? generateCode(name) : code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a code for the player and returns it.
|
||||
*
|
||||
* @param name the name of the player to generate a code for
|
||||
* @return the generated code
|
||||
*/
|
||||
public String generateCode(String name) {
|
||||
String code = RandomString.generate(captchaLength);
|
||||
captchaCodes.put(name.toLowerCase(), code);
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the supplied code is correct for the given player.
|
||||
* Checks the given code against the existing one and resets the player's auth failure count upon success.
|
||||
*
|
||||
* @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
|
||||
* @param name the name of 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());
|
||||
public boolean checkCode(String name, String code) {
|
||||
String savedCode = captchaCodes.get(name.toLowerCase());
|
||||
if (savedCode == null) {
|
||||
return true;
|
||||
} else if (savedCode.equalsIgnoreCase(code)) {
|
||||
captchaCodes.remove(player.toLowerCase());
|
||||
captchaCodes.remove(name.toLowerCase());
|
||||
playerCounts.remove(name.toLowerCase());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the login count of the given player to 0.
|
||||
*
|
||||
* @param name the player's name
|
||||
*/
|
||||
public void resetCounts(String name) {
|
||||
if (isEnabled) {
|
||||
captchaCodes.remove(name.toLowerCase());
|
||||
playerCounts.remove(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings(NewSetting settings) {
|
||||
this.isEnabled = settings.getProperty(SecuritySettings.USE_CAPTCHA);
|
||||
this.threshold = settings.getProperty(SecuritySettings.MAX_LOGIN_TRIES_BEFORE_CAPTCHA);
|
||||
this.captchaLength = settings.getProperty(SecuritySettings.CAPTCHA_LENGTH);
|
||||
}
|
||||
|
||||
}
|
||||
|
116
src/main/java/fr/xephi/authme/cache/TempbanManager.java
vendored
Normal file
116
src/main/java/fr/xephi/authme/cache/TempbanManager.java
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package fr.xephi.authme.cache;
|
||||
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Manager for handling tempbans
|
||||
*/
|
||||
// TODO Gnat008 20160613: Figure out the best way to remove entries based on time
|
||||
public class TempbanManager implements SettingsDependent {
|
||||
|
||||
private static final long MINUTE_IN_MILLISECONDS = 60000;
|
||||
|
||||
private final ConcurrentHashMap<String, Integer> ipLoginFailureCounts;
|
||||
private final BukkitService bukkitService;
|
||||
private final Messages messages;
|
||||
|
||||
private boolean isEnabled;
|
||||
private int threshold;
|
||||
private int length;
|
||||
|
||||
@Inject
|
||||
TempbanManager(BukkitService bukkitService, Messages messages, NewSetting settings) {
|
||||
this.ipLoginFailureCounts = new ConcurrentHashMap<>();
|
||||
this.bukkitService = bukkitService;
|
||||
this.messages = messages;
|
||||
loadSettings(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the failure count for the given IP address.
|
||||
*
|
||||
* @param address The player's IP address
|
||||
*/
|
||||
public void increaseCount(String address) {
|
||||
if (isEnabled) {
|
||||
Integer count = ipLoginFailureCounts.get(address);
|
||||
|
||||
if (count == null) {
|
||||
ipLoginFailureCounts.put(address, 1);
|
||||
} else {
|
||||
ipLoginFailureCounts.put(address, count + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the failure count for a given IP address to 0.
|
||||
*
|
||||
* @param address The IP address
|
||||
*/
|
||||
public void resetCount(String address) {
|
||||
if (isEnabled) {
|
||||
ipLoginFailureCounts.remove(address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the IP address should be tempbanned.
|
||||
*
|
||||
* @param address The player's IP address
|
||||
* @return True if the IP should be tempbanned
|
||||
*/
|
||||
public boolean shouldTempban(String address) {
|
||||
if (isEnabled) {
|
||||
Integer count = ipLoginFailureCounts.get(address);
|
||||
return count != null && count >= threshold;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tempban a player's IP address for failing to log in too many times.
|
||||
* This calculates the expire time based on the time the method was called.
|
||||
*
|
||||
* @param player The player to tempban
|
||||
*/
|
||||
public void tempbanPlayer(final Player player) {
|
||||
if (isEnabled) {
|
||||
final String ip = Utils.getPlayerIp(player);
|
||||
final String reason = messages.retrieveSingle(MessageKey.TEMPBAN_MAX_LOGINS);
|
||||
|
||||
final Date expires = new Date();
|
||||
long newTime = expires.getTime() + (length * MINUTE_IN_MILLISECONDS);
|
||||
expires.setTime(newTime);
|
||||
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
bukkitService.banIp(ip, reason, expires, "AuthMe");
|
||||
player.kickPlayer(reason);
|
||||
}
|
||||
});
|
||||
|
||||
resetCount(ip);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings(NewSetting settings) {
|
||||
this.isEnabled = settings.getProperty(SecuritySettings.TEMPBAN_ON_MAX_LOGINS);
|
||||
this.threshold = settings.getProperty(SecuritySettings.MAX_LOGIN_TEMPBAN);
|
||||
this.length = settings.getProperty(SecuritySettings.TEMPBAN_LENGTH);
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package fr.xephi.authme.cache.auth;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -22,6 +24,7 @@ public class PlayerCache {
|
||||
if (singleton == null) {
|
||||
singleton = new PlayerCache();
|
||||
}
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@ -31,6 +34,7 @@ public class PlayerCache {
|
||||
* @param auth PlayerAuth
|
||||
*/
|
||||
public void addPlayer(PlayerAuth auth) {
|
||||
ConsoleLogger.debug("ADDED PLAYER TO CACHE " + auth.getNickname());
|
||||
cache.put(auth.getNickname().toLowerCase(), auth);
|
||||
}
|
||||
|
||||
@ -40,6 +44,7 @@ public class PlayerCache {
|
||||
* @param auth PlayerAuth
|
||||
*/
|
||||
public void updatePlayer(PlayerAuth auth) {
|
||||
ConsoleLogger.debug("UPDATE PLAYER " + auth.getNickname());
|
||||
cache.put(auth.getNickname(), auth);
|
||||
}
|
||||
|
||||
@ -49,6 +54,7 @@ public class PlayerCache {
|
||||
* @param user String
|
||||
*/
|
||||
public void removePlayer(String user) {
|
||||
ConsoleLogger.debug("REMOVE PLAYER " + user);
|
||||
cache.remove(user.toLowerCase());
|
||||
}
|
||||
|
||||
|
@ -1,46 +1,34 @@
|
||||
package fr.xephi.authme.cache.limbo;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.backup.JsonCache;
|
||||
import fr.xephi.authme.cache.backup.PlayerData;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Manages all {@link LimboPlayer} instances.
|
||||
*/
|
||||
public class LimboCache {
|
||||
|
||||
private volatile static LimboCache singleton;
|
||||
private final ConcurrentHashMap<String, LimboPlayer> cache;
|
||||
private final AuthMe plugin;
|
||||
private final JsonCache jsonCache;
|
||||
private final ConcurrentHashMap<String, LimboPlayer> cache = new ConcurrentHashMap<>();
|
||||
private final JsonCache jsonCache = new JsonCache();
|
||||
|
||||
/**
|
||||
* Constructor for LimboCache.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
*/
|
||||
private LimboCache(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.cache = new ConcurrentHashMap<>();
|
||||
this.jsonCache = new JsonCache();
|
||||
}
|
||||
@Inject
|
||||
private PermissionsManager permissionsManager;
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
|
||||
/**
|
||||
* Method getInstance.
|
||||
*
|
||||
* @return LimboCache
|
||||
*/
|
||||
public static LimboCache getInstance() {
|
||||
if (singleton == null) {
|
||||
singleton = new LimboCache(AuthMe.getInstance());
|
||||
}
|
||||
return singleton;
|
||||
@Inject
|
||||
LimboCache(PermissionsManager permissionsManager, SpawnLoader spawnLoader) {
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.spawnLoader = spawnLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,13 +38,12 @@ public class LimboCache {
|
||||
*/
|
||||
public void addLimboPlayer(Player player) {
|
||||
String name = player.getName().toLowerCase();
|
||||
Location loc = player.getLocation();
|
||||
Location location = player.isDead() ? spawnLoader.getSpawnLocation(player) : player.getLocation();
|
||||
boolean operator = player.isOp();
|
||||
boolean flyEnabled = player.getAllowFlight();
|
||||
String playerGroup = "";
|
||||
PermissionsManager permsMan = plugin.getPermissionsManager();
|
||||
if (permsMan.hasGroupSupport()) {
|
||||
playerGroup = permsMan.getPrimaryGroup(player);
|
||||
if (permissionsManager.hasGroupSupport()) {
|
||||
playerGroup = permissionsManager.getPrimaryGroup(player);
|
||||
}
|
||||
|
||||
if (jsonCache.doesCacheExist(player)) {
|
||||
@ -68,11 +55,8 @@ public class LimboCache {
|
||||
}
|
||||
}
|
||||
|
||||
if (player.isDead()) {
|
||||
loc = plugin.getSpawnLocation(player);
|
||||
}
|
||||
|
||||
cache.put(name, new LimboPlayer(name, loc, operator, playerGroup, flyEnabled));
|
||||
cache.put(name, new LimboPlayer(name, location, operator, playerGroup, flyEnabled));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,9 +67,9 @@ public class LimboCache {
|
||||
public void deleteLimboPlayer(String name) {
|
||||
checkNotNull(name);
|
||||
name = name.toLowerCase();
|
||||
if (cache.containsKey(name)) {
|
||||
cache.get(name).clearTasks();
|
||||
cache.remove(name);
|
||||
LimboPlayer cachedPlayer = cache.remove(name);
|
||||
if (cachedPlayer != null) {
|
||||
cachedPlayer.clearTasks();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import fr.xephi.authme.permission.DefaultPermission;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
@ -14,7 +13,7 @@ import static java.util.Arrays.asList;
|
||||
/**
|
||||
* Command description – defines which labels ("names") will lead to a command and points to the
|
||||
* {@link ExecutableCommand} implementation that executes the logic of the command.
|
||||
*
|
||||
* <p>
|
||||
* CommandDescription instances are built hierarchically: they have one parent, or {@code null} for base commands
|
||||
* (main commands such as {@code /authme}), and may have multiple children extending the mapping of the parent: e.g. if
|
||||
* {@code /authme} has a child whose label is {@code "register"}, then {@code /authme register} is the command that
|
||||
@ -36,9 +35,9 @@ public class CommandDescription {
|
||||
*/
|
||||
private String detailedDescription;
|
||||
/**
|
||||
* The executable command instance described by this object.
|
||||
* The class implementing the command described by this object.
|
||||
*/
|
||||
private ExecutableCommand executableCommand;
|
||||
private Class<? extends ExecutableCommand> executableCommand;
|
||||
/**
|
||||
* The parent command.
|
||||
*/
|
||||
@ -52,13 +51,13 @@ public class CommandDescription {
|
||||
*/
|
||||
private List<CommandArgumentDescription> arguments;
|
||||
/**
|
||||
* Command permissions required to execute this command.
|
||||
* Permission node required to execute this command.
|
||||
*/
|
||||
private CommandPermissions permissions;
|
||||
private PermissionNode permission;
|
||||
|
||||
/**
|
||||
* Private constructor. Use {@link CommandDescription#builder()} to create instances of this class.
|
||||
* <p />
|
||||
* <p>
|
||||
* Note for developers: Instances should be created with {@link CommandDescription#createInstance} to be properly
|
||||
* registered in the command tree.
|
||||
*/
|
||||
@ -68,21 +67,20 @@ public class CommandDescription {
|
||||
/**
|
||||
* Create an instance.
|
||||
*
|
||||
* @param labels List of command labels.
|
||||
* @param description Command description.
|
||||
* @param detailedDescription Detailed comment description.
|
||||
* @param executableCommand The executable command, or null.
|
||||
* @param parent Parent command.
|
||||
* @param arguments Command arguments.
|
||||
* @param permissions The permissions required to execute this command.
|
||||
* @param labels command labels
|
||||
* @param description description of the command
|
||||
* @param detailedDescription detailed command description
|
||||
* @param executableCommand class of the command implementation
|
||||
* @param parent parent command
|
||||
* @param arguments command arguments
|
||||
* @param permission permission node required to execute this command
|
||||
*
|
||||
* @return The created instance
|
||||
* @return the created instance
|
||||
* @see CommandDescription#builder()
|
||||
*/
|
||||
private static CommandDescription createInstance(List<String> labels, String description,
|
||||
String detailedDescription, ExecutableCommand executableCommand,
|
||||
CommandDescription parent, List<CommandArgumentDescription> arguments,
|
||||
CommandPermissions permissions) {
|
||||
String detailedDescription, Class<? extends ExecutableCommand> executableCommand, CommandDescription parent,
|
||||
List<CommandArgumentDescription> arguments, PermissionNode permission) {
|
||||
CommandDescription instance = new CommandDescription();
|
||||
instance.labels = labels;
|
||||
instance.description = description;
|
||||
@ -90,7 +88,7 @@ public class CommandDescription {
|
||||
instance.executableCommand = executableCommand;
|
||||
instance.parent = parent;
|
||||
instance.arguments = arguments;
|
||||
instance.permissions = permissions;
|
||||
instance.permission = permission;
|
||||
|
||||
if (parent != null) {
|
||||
parent.addChild(instance);
|
||||
@ -114,7 +112,7 @@ public class CommandDescription {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this command description has a specific command.
|
||||
* Check whether this command description has the given label.
|
||||
*
|
||||
* @param commandLabel The label to check for.
|
||||
*
|
||||
@ -130,18 +128,18 @@ public class CommandDescription {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link ExecutableCommand} instance defined by the command description.
|
||||
* Return the {@link ExecutableCommand} class implementing this command.
|
||||
*
|
||||
* @return The executable command object.
|
||||
* @return The executable command class
|
||||
*/
|
||||
public ExecutableCommand getExecutableCommand() {
|
||||
public Class<? extends ExecutableCommand> getExecutableCommand() {
|
||||
return executableCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parent.
|
||||
*
|
||||
* @return The parent command, or null for base commands.
|
||||
* @return The parent command, or null for base commands
|
||||
*/
|
||||
public CommandDescription getParent() {
|
||||
return parent;
|
||||
@ -196,12 +194,12 @@ public class CommandDescription {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the permissions required to execute the command.
|
||||
* Return the permission node required to execute the command.
|
||||
*
|
||||
* @return The command permissions, or null if none are required to execute the command.
|
||||
* @return The permission node, or null if none are required to execute the command.
|
||||
*/
|
||||
public CommandPermissions getCommandPermissions() {
|
||||
return permissions;
|
||||
public PermissionNode getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,10 +218,10 @@ public class CommandDescription {
|
||||
private List<String> labels;
|
||||
private String description;
|
||||
private String detailedDescription;
|
||||
private ExecutableCommand executableCommand;
|
||||
private Class<? extends ExecutableCommand> executableCommand;
|
||||
private CommandDescription parent;
|
||||
private List<CommandArgumentDescription> arguments = new ArrayList<>();
|
||||
private CommandPermissions permissions;
|
||||
private PermissionNode permission;
|
||||
|
||||
/**
|
||||
* Build a CommandDescription from the builder or throw an exception if a mandatory
|
||||
@ -239,7 +237,7 @@ public class CommandDescription {
|
||||
// parents and permissions may be null; arguments may be empty
|
||||
|
||||
return createInstance(labels, description, detailedDescription, executableCommand,
|
||||
parent, arguments, permissions);
|
||||
parent, arguments, permission);
|
||||
}
|
||||
|
||||
public CommandBuilder labels(List<String> labels) {
|
||||
@ -261,7 +259,7 @@ public class CommandDescription {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandBuilder executableCommand(ExecutableCommand executableCommand) {
|
||||
public CommandBuilder executableCommand(Class<? extends ExecutableCommand> executableCommand) {
|
||||
this.executableCommand = executableCommand;
|
||||
return this;
|
||||
}
|
||||
@ -286,9 +284,14 @@ public class CommandDescription {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandBuilder permissions(DefaultPermission defaultPermission,
|
||||
PermissionNode... permissionNodes) {
|
||||
this.permissions = new CommandPermissions(asList(permissionNodes), defaultPermission);
|
||||
/**
|
||||
* Add a permission node that a user must have to execute the command.
|
||||
*
|
||||
* @param permission The PermissionNode to add
|
||||
* @return The builder
|
||||
*/
|
||||
public CommandBuilder permission(PermissionNode permission) {
|
||||
this.permission = permission;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,23 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription}
|
||||
* or to display help messages for unknown invocations.
|
||||
* The AuthMe command handler, responsible for invoking the correct {@link ExecutableCommand} based on incoming
|
||||
* command labels or for displaying a help message for unknown command labels.
|
||||
*/
|
||||
public class CommandHandler {
|
||||
|
||||
@ -22,15 +27,22 @@ public class CommandHandler {
|
||||
*/
|
||||
private static final double SUGGEST_COMMAND_THRESHOLD = 0.75;
|
||||
|
||||
private final CommandService commandService;
|
||||
private final CommandMapper commandMapper;
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final HelpProvider helpProvider;
|
||||
|
||||
/**
|
||||
* Create a command handler.
|
||||
*
|
||||
* @param commandService The CommandService instance
|
||||
* Map with ExecutableCommand children. The key is the type of the value.
|
||||
*/
|
||||
public CommandHandler(CommandService commandService) {
|
||||
this.commandService = commandService;
|
||||
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> commands = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public CommandHandler(AuthMeServiceInitializer initializer, CommandMapper commandMapper,
|
||||
PermissionsManager permissionsManager, HelpProvider helpProvider) {
|
||||
this.commandMapper = commandMapper;
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.helpProvider = helpProvider;
|
||||
initializeCommands(initializer, commandMapper.getCommandClasses());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,7 +60,7 @@ public class CommandHandler {
|
||||
List<String> parts = skipEmptyArguments(bukkitArgs);
|
||||
parts.add(0, bukkitCommandLabel);
|
||||
|
||||
FoundCommandResult result = commandService.mapPartsToCommand(sender, parts);
|
||||
FoundCommandResult result = commandMapper.mapPartsToCommand(sender, parts);
|
||||
handleCommandResult(sender, result);
|
||||
return !FoundResultStatus.MISSING_BASE_COMMAND.equals(result.getResultStatus());
|
||||
}
|
||||
@ -75,6 +87,18 @@ public class CommandHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all required ExecutableCommand objects.
|
||||
*
|
||||
* @param commandClasses the classes to instantiate
|
||||
*/
|
||||
private void initializeCommands(AuthMeServiceInitializer initializer,
|
||||
Set<Class<? extends ExecutableCommand>> commandClasses) {
|
||||
for (Class<? extends ExecutableCommand> clazz : commandClasses) {
|
||||
commands.put(clazz, initializer.newInstance(clazz));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command for the given command sender.
|
||||
*
|
||||
@ -82,9 +106,9 @@ public class CommandHandler {
|
||||
* @param result The mapped result
|
||||
*/
|
||||
private void executeCommand(CommandSender sender, FoundCommandResult result) {
|
||||
ExecutableCommand executableCommand = result.getCommandDescription().getExecutableCommand();
|
||||
ExecutableCommand executableCommand = commands.get(result.getCommandDescription().getExecutableCommand());
|
||||
List<String> arguments = result.getArguments();
|
||||
executableCommand.executeCommand(sender, arguments, commandService);
|
||||
executableCommand.executeCommand(sender, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,14 +149,14 @@ public class CommandHandler {
|
||||
|
||||
private void sendImproperArgumentsMessage(CommandSender sender, FoundCommandResult result) {
|
||||
CommandDescription command = result.getCommandDescription();
|
||||
if (!commandService.getPermissionsManager().hasPermission(sender, command)) {
|
||||
if (!permissionsManager.hasPermission(sender, command.getPermission())) {
|
||||
sendPermissionDeniedError(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the command argument help
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
|
||||
commandService.outputHelp(sender, result, HelpProvider.SHOW_ARGUMENTS);
|
||||
helpProvider.outputHelp(sender, result, HelpProvider.SHOW_ARGUMENTS);
|
||||
|
||||
List<String> labels = result.getLabels();
|
||||
String childLabel = labels.size() >= 2 ? labels.get(1) : "";
|
||||
|
@ -41,25 +41,33 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static fr.xephi.authme.permission.DefaultPermission.ALLOWED;
|
||||
import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
|
||||
|
||||
/**
|
||||
* Initializes all available AuthMe commands.
|
||||
*/
|
||||
public final class CommandInitializer {
|
||||
public class CommandInitializer {
|
||||
|
||||
private CommandInitializer() {
|
||||
// Helper class
|
||||
private Set<CommandDescription> commands;
|
||||
|
||||
public CommandInitializer() {
|
||||
buildCommands();
|
||||
}
|
||||
|
||||
public static Set<CommandDescription> buildCommands() {
|
||||
/**
|
||||
* Returns the description of all AuthMe commands.
|
||||
*
|
||||
* @return the command descriptions
|
||||
*/
|
||||
public Set<CommandDescription> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
private void buildCommands() {
|
||||
// Register the base AuthMe Reloaded command
|
||||
final CommandDescription AUTHME_BASE = CommandDescription.builder()
|
||||
.labels("authme")
|
||||
.description("Main command")
|
||||
.detailedDescription("The main AuthMeReloaded command. The root for all admin commands.")
|
||||
.executableCommand(new AuthMeCommand())
|
||||
.executableCommand(AuthMeCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the register command
|
||||
@ -70,8 +78,8 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Register the specified player with the specified password.")
|
||||
.withArgument("player", "Player name", false)
|
||||
.withArgument("password", "Password", false)
|
||||
.permissions(OP_ONLY, AdminPermission.REGISTER)
|
||||
.executableCommand(new RegisterAdminCommand())
|
||||
.permission(AdminPermission.REGISTER)
|
||||
.executableCommand(RegisterAdminCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the unregister command
|
||||
@ -81,8 +89,8 @@ public final class CommandInitializer {
|
||||
.description("Unregister a player")
|
||||
.detailedDescription("Unregister the specified player.")
|
||||
.withArgument("player", "Player name", false)
|
||||
.permissions(OP_ONLY, AdminPermission.UNREGISTER)
|
||||
.executableCommand(new UnregisterAdminCommand())
|
||||
.permission(AdminPermission.UNREGISTER)
|
||||
.executableCommand(UnregisterAdminCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the forcelogin command
|
||||
@ -92,8 +100,8 @@ public final class CommandInitializer {
|
||||
.description("Enforce login player")
|
||||
.detailedDescription("Enforce the specified player to login.")
|
||||
.withArgument("player", "Online player name", true)
|
||||
.permissions(OP_ONLY, AdminPermission.FORCE_LOGIN)
|
||||
.executableCommand(new ForceLoginCommand())
|
||||
.permission(AdminPermission.FORCE_LOGIN)
|
||||
.executableCommand(ForceLoginCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the changepassword command
|
||||
@ -104,8 +112,8 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Change the password of a player.")
|
||||
.withArgument("player", "Player name", false)
|
||||
.withArgument("pwd", "New password", false)
|
||||
.permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD)
|
||||
.executableCommand(new ChangePasswordAdminCommand())
|
||||
.permission(AdminPermission.CHANGE_PASSWORD)
|
||||
.executableCommand(ChangePasswordAdminCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the last login command
|
||||
@ -115,8 +123,8 @@ public final class CommandInitializer {
|
||||
.description("Player's last login")
|
||||
.detailedDescription("View the date of the specified players last login.")
|
||||
.withArgument("player", "Player name", true)
|
||||
.permissions(OP_ONLY, AdminPermission.LAST_LOGIN)
|
||||
.executableCommand(new LastLoginCommand())
|
||||
.permission(AdminPermission.LAST_LOGIN)
|
||||
.executableCommand(LastLoginCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the accounts command
|
||||
@ -126,8 +134,8 @@ public final class CommandInitializer {
|
||||
.description("Display player accounts")
|
||||
.detailedDescription("Display all accounts of a player by his player name or IP.")
|
||||
.withArgument("player", "Player name or IP", true)
|
||||
.permissions(OP_ONLY, AdminPermission.ACCOUNTS)
|
||||
.executableCommand(new AccountsCommand())
|
||||
.permission(AdminPermission.ACCOUNTS)
|
||||
.executableCommand(AccountsCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the getemail command
|
||||
@ -137,8 +145,8 @@ public final class CommandInitializer {
|
||||
.description("Display player's email")
|
||||
.detailedDescription("Display the email address of the specified player if set.")
|
||||
.withArgument("player", "Player name", true)
|
||||
.permissions(OP_ONLY, AdminPermission.GET_EMAIL)
|
||||
.executableCommand(new GetEmailCommand())
|
||||
.permission(AdminPermission.GET_EMAIL)
|
||||
.executableCommand(GetEmailCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the setemail command
|
||||
@ -149,8 +157,8 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Change the email address of the specified player.")
|
||||
.withArgument("player", "Player name", false)
|
||||
.withArgument("email", "Player email", false)
|
||||
.permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL)
|
||||
.executableCommand(new SetEmailCommand())
|
||||
.permission(AdminPermission.CHANGE_EMAIL)
|
||||
.executableCommand(SetEmailCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the getip command
|
||||
@ -160,8 +168,8 @@ public final class CommandInitializer {
|
||||
.description("Get player's IP")
|
||||
.detailedDescription("Get the IP address of the specified online player.")
|
||||
.withArgument("player", "Player name", false)
|
||||
.permissions(OP_ONLY, AdminPermission.GET_IP)
|
||||
.executableCommand(new GetIpCommand())
|
||||
.permission(AdminPermission.GET_IP)
|
||||
.executableCommand(GetIpCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the spawn command
|
||||
@ -170,8 +178,8 @@ public final class CommandInitializer {
|
||||
.labels("spawn", "home")
|
||||
.description("Teleport to spawn")
|
||||
.detailedDescription("Teleport to the spawn.")
|
||||
.permissions(OP_ONLY, AdminPermission.SPAWN)
|
||||
.executableCommand(new SpawnCommand())
|
||||
.permission(AdminPermission.SPAWN)
|
||||
.executableCommand(SpawnCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the setspawn command
|
||||
@ -180,8 +188,8 @@ public final class CommandInitializer {
|
||||
.labels("setspawn", "chgspawn")
|
||||
.description("Change the spawn")
|
||||
.detailedDescription("Change the player's spawn to your current position.")
|
||||
.permissions(OP_ONLY, AdminPermission.SET_SPAWN)
|
||||
.executableCommand(new SetSpawnCommand())
|
||||
.permission(AdminPermission.SET_SPAWN)
|
||||
.executableCommand(SetSpawnCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the firstspawn command
|
||||
@ -190,8 +198,8 @@ public final class CommandInitializer {
|
||||
.labels("firstspawn", "firsthome")
|
||||
.description("Teleport to first spawn")
|
||||
.detailedDescription("Teleport to the first spawn.")
|
||||
.permissions(OP_ONLY, AdminPermission.FIRST_SPAWN)
|
||||
.executableCommand(new FirstSpawnCommand())
|
||||
.permission(AdminPermission.FIRST_SPAWN)
|
||||
.executableCommand(FirstSpawnCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the setfirstspawn command
|
||||
@ -200,8 +208,8 @@ public final class CommandInitializer {
|
||||
.labels("setfirstspawn", "chgfirstspawn")
|
||||
.description("Change the first spawn")
|
||||
.detailedDescription("Change the first player's spawn to your current position.")
|
||||
.permissions(OP_ONLY, AdminPermission.SET_FIRST_SPAWN)
|
||||
.executableCommand(new SetFirstSpawnCommand())
|
||||
.permission(AdminPermission.SET_FIRST_SPAWN)
|
||||
.executableCommand(SetFirstSpawnCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the purge command
|
||||
@ -211,8 +219,8 @@ public final class CommandInitializer {
|
||||
.description("Purge old data")
|
||||
.detailedDescription("Purge old AuthMeReloaded data longer than the specified amount of days ago.")
|
||||
.withArgument("days", "Number of days", false)
|
||||
.permissions(OP_ONLY, AdminPermission.PURGE)
|
||||
.executableCommand(new PurgeCommand())
|
||||
.permission(AdminPermission.PURGE)
|
||||
.executableCommand(PurgeCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the purgelastposition command
|
||||
@ -223,8 +231,8 @@ public final class CommandInitializer {
|
||||
.description("Purge player's last position")
|
||||
.detailedDescription("Purge the last know position of the specified player or all of them.")
|
||||
.withArgument("player/*", "Player name or * for all players", false)
|
||||
.permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION)
|
||||
.executableCommand(new PurgeLastPositionCommand())
|
||||
.permission(AdminPermission.PURGE_LAST_POSITION)
|
||||
.executableCommand(PurgeLastPositionCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the purgebannedplayers command
|
||||
@ -233,8 +241,8 @@ public final class CommandInitializer {
|
||||
.labels("purgebannedplayers", "purgebannedplayer", "deletebannedplayers", "deletebannedplayer")
|
||||
.description("Purge banned players data")
|
||||
.detailedDescription("Purge all AuthMeReloaded data for banned players.")
|
||||
.permissions(OP_ONLY, AdminPermission.PURGE_BANNED_PLAYERS)
|
||||
.executableCommand(new PurgeBannedPlayersCommand())
|
||||
.permission(AdminPermission.PURGE_BANNED_PLAYERS)
|
||||
.executableCommand(PurgeBannedPlayersCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the switchantibot command
|
||||
@ -244,8 +252,8 @@ public final class CommandInitializer {
|
||||
.description("Switch AntiBot mode")
|
||||
.detailedDescription("Switch or toggle the AntiBot mode to the specified state.")
|
||||
.withArgument("mode", "ON / OFF", true)
|
||||
.permissions(OP_ONLY, AdminPermission.SWITCH_ANTIBOT)
|
||||
.executableCommand(new SwitchAntiBotCommand())
|
||||
.permission(AdminPermission.SWITCH_ANTIBOT)
|
||||
.executableCommand(SwitchAntiBotCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the reload command
|
||||
@ -254,8 +262,8 @@ public final class CommandInitializer {
|
||||
.labels("reload", "rld")
|
||||
.description("Reload plugin")
|
||||
.detailedDescription("Reload the AuthMeReloaded plugin.")
|
||||
.permissions(OP_ONLY, AdminPermission.RELOAD)
|
||||
.executableCommand(new ReloadCommand())
|
||||
.permission(AdminPermission.RELOAD)
|
||||
.executableCommand(ReloadCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the version command
|
||||
@ -265,7 +273,7 @@ public final class CommandInitializer {
|
||||
.description("Version info")
|
||||
.detailedDescription("Show detailed information about the installed AuthMeReloaded version, the "
|
||||
+ "developers, contributors, and license.")
|
||||
.executableCommand(new VersionCommand())
|
||||
.executableCommand(VersionCommand.class)
|
||||
.build();
|
||||
|
||||
CommandDescription.builder()
|
||||
@ -275,19 +283,19 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Converter command for AuthMeReloaded.")
|
||||
.withArgument("job", "Conversion job: xauth / crazylogin / rakamak / " +
|
||||
"royalauth / vauth / sqlitetosql", false)
|
||||
.permissions(OP_ONLY, AdminPermission.CONVERTER)
|
||||
.executableCommand(new ConverterCommand())
|
||||
.permission(AdminPermission.CONVERTER)
|
||||
.executableCommand(ConverterCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base login command
|
||||
final CommandDescription LOGIN_BASE = CommandDescription.builder()
|
||||
.parent(null)
|
||||
.labels("login", "l")
|
||||
.labels("login", "l", "log")
|
||||
.description("Login command")
|
||||
.detailedDescription("Command to log in using AuthMeReloaded.")
|
||||
.withArgument("password", "Login password", false)
|
||||
.permissions(ALLOWED, PlayerPermission.LOGIN)
|
||||
.executableCommand(new LoginCommand())
|
||||
.permission(PlayerPermission.LOGIN)
|
||||
.executableCommand(LoginCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base logout command
|
||||
@ -296,8 +304,8 @@ public final class CommandInitializer {
|
||||
.labels("logout")
|
||||
.description("Logout command")
|
||||
.detailedDescription("Command to logout using AuthMeReloaded.")
|
||||
.permissions(ALLOWED, PlayerPermission.LOGOUT)
|
||||
.executableCommand(new LogoutCommand())
|
||||
.permission(PlayerPermission.LOGOUT)
|
||||
.executableCommand(LogoutCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base register command
|
||||
@ -308,19 +316,19 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Command to register using AuthMeReloaded.")
|
||||
.withArgument("password", "Password", true)
|
||||
.withArgument("verifyPassword", "Verify password", true)
|
||||
.permissions(ALLOWED, PlayerPermission.REGISTER)
|
||||
.executableCommand(new RegisterCommand())
|
||||
.permission(PlayerPermission.REGISTER)
|
||||
.executableCommand(RegisterCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base unregister command
|
||||
CommandDescription UNREGISTER_BASE = CommandDescription.builder()
|
||||
.parent(null)
|
||||
.labels("unreg", "unregister")
|
||||
.labels("unregister", "unreg")
|
||||
.description("Unregistration Command")
|
||||
.detailedDescription("Command to unregister using AuthMeReloaded.")
|
||||
.withArgument("password", "Password", false)
|
||||
.permissions(ALLOWED, PlayerPermission.UNREGISTER)
|
||||
.executableCommand(new UnregisterCommand())
|
||||
.permission(PlayerPermission.UNREGISTER)
|
||||
.executableCommand(UnregisterCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base changepassword command
|
||||
@ -331,17 +339,17 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Command to change your password using AuthMeReloaded.")
|
||||
.withArgument("oldPassword", "Old Password", false)
|
||||
.withArgument("newPassword", "New Password.", false)
|
||||
.permissions(ALLOWED, PlayerPermission.CHANGE_PASSWORD)
|
||||
.executableCommand(new ChangePasswordCommand())
|
||||
.permission(PlayerPermission.CHANGE_PASSWORD)
|
||||
.executableCommand(ChangePasswordCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base Email command
|
||||
CommandDescription EMAIL_BASE = CommandDescription.builder()
|
||||
.parent(null)
|
||||
.labels("email", "mail")
|
||||
.labels("email")
|
||||
.description("Email command")
|
||||
.detailedDescription("The AuthMeReloaded Email command base.")
|
||||
.executableCommand(new EmailBaseCommand())
|
||||
.executableCommand(EmailBaseCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the add command
|
||||
@ -352,8 +360,8 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Add a new email address to your account.")
|
||||
.withArgument("email", "Email address", false)
|
||||
.withArgument("verifyEmail", "Email address verification", false)
|
||||
.permissions(ALLOWED, PlayerPermission.ADD_EMAIL)
|
||||
.executableCommand(new AddEmailCommand())
|
||||
.permission(PlayerPermission.ADD_EMAIL)
|
||||
.executableCommand(AddEmailCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the change command
|
||||
@ -364,8 +372,8 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Change an email address of your account.")
|
||||
.withArgument("oldEmail", "Old email address", false)
|
||||
.withArgument("newEmail", "New email address", false)
|
||||
.permissions(ALLOWED, PlayerPermission.CHANGE_EMAIL)
|
||||
.executableCommand(new ChangeEmailCommand())
|
||||
.permission(PlayerPermission.CHANGE_EMAIL)
|
||||
.executableCommand(ChangeEmailCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the recover command
|
||||
@ -376,19 +384,19 @@ public final class CommandInitializer {
|
||||
.detailedDescription("Recover your account using an Email address by sending a mail containing " +
|
||||
"a new password.")
|
||||
.withArgument("email", "Email address", false)
|
||||
.permissions(ALLOWED, PlayerPermission.RECOVER_EMAIL)
|
||||
.executableCommand(new RecoverEmailCommand())
|
||||
.permission(PlayerPermission.RECOVER_EMAIL)
|
||||
.executableCommand(RecoverEmailCommand.class)
|
||||
.build();
|
||||
|
||||
// Register the base captcha command
|
||||
CommandDescription CAPTCHA_BASE = CommandDescription.builder()
|
||||
.parent(null)
|
||||
.labels("captcha", "capt")
|
||||
.labels("captcha")
|
||||
.description("Captcha Command")
|
||||
.detailedDescription("Captcha command for AuthMeReloaded.")
|
||||
.withArgument("captcha", "The Captcha", false)
|
||||
.permissions(ALLOWED, PlayerPermission.CAPTCHA)
|
||||
.executableCommand(new CaptchaCommand())
|
||||
.permission(PlayerPermission.CAPTCHA)
|
||||
.executableCommand(CaptchaCommand.class)
|
||||
.build();
|
||||
|
||||
Set<CommandDescription> baseCommands = ImmutableSet.of(
|
||||
@ -402,16 +410,15 @@ public final class CommandInitializer {
|
||||
CAPTCHA_BASE);
|
||||
|
||||
setHelpOnAllBases(baseCommands);
|
||||
return baseCommands;
|
||||
commands = baseCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the help command on all base commands, e.g. to register /authme help or /register help.
|
||||
* Sets the help command on all base commands, e.g. to register /authme help or /register help.
|
||||
*
|
||||
* @param commands The list of base commands to register a help child command on
|
||||
* @param commands the list of base commands to register a help child command on
|
||||
*/
|
||||
private static void setHelpOnAllBases(Collection<CommandDescription> commands) {
|
||||
final HelpCommand helpCommandExecutable = new HelpCommand();
|
||||
private void setHelpOnAllBases(Collection<CommandDescription> commands) {
|
||||
final List<String> helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?");
|
||||
|
||||
for (CommandDescription base : commands) {
|
||||
@ -421,7 +428,7 @@ public final class CommandInitializer {
|
||||
.description("View help")
|
||||
.detailedDescription("View detailed help for /" + base.getLabels().get(0) + " commands.")
|
||||
.withArgument("query", "The command or query to view help for.", true)
|
||||
.executableCommand(helpCommandExecutable)
|
||||
.executableCommand(HelpCommand.class)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@ -15,8 +17,7 @@ import static fr.xephi.authme.command.FoundResultStatus.MISSING_BASE_COMMAND;
|
||||
import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL;
|
||||
|
||||
/**
|
||||
* The AuthMe command handler, responsible for mapping incoming
|
||||
* command parts to the correct {@link CommandDescription}.
|
||||
* Maps incoming command parts to the correct {@link CommandDescription}.
|
||||
*/
|
||||
public class CommandMapper {
|
||||
|
||||
@ -28,8 +29,9 @@ public class CommandMapper {
|
||||
private final Set<CommandDescription> baseCommands;
|
||||
private final PermissionsManager permissionsManager;
|
||||
|
||||
public CommandMapper(Set<CommandDescription> baseCommands, PermissionsManager permissionsManager) {
|
||||
this.baseCommands = baseCommands;
|
||||
@Inject
|
||||
public CommandMapper(CommandInitializer commandInitializer, PermissionsManager permissionsManager) {
|
||||
this.baseCommands = commandInitializer.getCommands();
|
||||
this.permissionsManager = permissionsManager;
|
||||
}
|
||||
|
||||
@ -67,6 +69,23 @@ public class CommandMapper {
|
||||
return getCommandWithSmallestDifference(base, parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all {@link ExecutableCommand} classes referenced in {@link CommandDescription} objects.
|
||||
*
|
||||
* @return all classes
|
||||
* @see CommandInitializer#getCommands
|
||||
*/
|
||||
public Set<Class<? extends ExecutableCommand>> getCommandClasses() {
|
||||
Set<Class<? extends ExecutableCommand>> classes = new HashSet<>(50);
|
||||
for (CommandDescription command : baseCommands) {
|
||||
classes.add(command.getExecutableCommand());
|
||||
for (CommandDescription child : command.getChildren()) {
|
||||
classes.add(child.getExecutableCommand());
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
private FoundCommandResult getCommandWithSmallestDifference(CommandDescription base, List<String> parts) {
|
||||
// Return the base command with incorrect arg count error if we only have one part
|
||||
if (parts.size() <= 1) {
|
||||
@ -139,7 +158,7 @@ public class CommandMapper {
|
||||
|
||||
private static FoundCommandResult transformResultForHelp(FoundCommandResult result) {
|
||||
if (result.getCommandDescription() != null
|
||||
&& HELP_COMMAND_CLASS.isAssignableFrom(result.getCommandDescription().getExecutableCommand().getClass())) {
|
||||
&& HELP_COMMAND_CLASS == result.getCommandDescription().getExecutableCommand()) {
|
||||
// For "/authme help register" we have labels = [authme, help] and arguments = [register]
|
||||
// But for the help command we want labels = [authme, help] and arguments = [authme, register],
|
||||
// so we can use the arguments as the labels to the command to show help for
|
||||
@ -152,7 +171,7 @@ public class CommandMapper {
|
||||
}
|
||||
|
||||
private FoundResultStatus getPermissionAwareStatus(CommandSender sender, CommandDescription command) {
|
||||
if (sender != null && !permissionsManager.hasPermission(sender, command)) {
|
||||
if (sender != null && !permissionsManager.hasPermission(sender, command.getPermission())) {
|
||||
return FoundResultStatus.NO_PERMISSION;
|
||||
}
|
||||
return FoundResultStatus.SUCCESS;
|
||||
|
@ -1,52 +0,0 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import fr.xephi.authme.permission.DefaultPermission;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class CommandPermissions {
|
||||
|
||||
/**
|
||||
* Defines the permission nodes required to have permission to execute this command.
|
||||
*/
|
||||
private List<PermissionNode> permissionNodes;
|
||||
/**
|
||||
* Defines the default permission if the permission nodes couldn't be used.
|
||||
*/
|
||||
private DefaultPermission defaultPermission;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param permissionNodes The permission nodes required to execute a command.
|
||||
* @param defaultPermission The default permission if the permission nodes couldn't be used.
|
||||
*/
|
||||
public CommandPermissions(List<PermissionNode> permissionNodes, DefaultPermission defaultPermission) {
|
||||
this.permissionNodes = permissionNodes;
|
||||
this.defaultPermission = defaultPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permission nodes required to execute this command.
|
||||
*
|
||||
* @return The permission nodes required to execute this command.
|
||||
*/
|
||||
public List<PermissionNode> getPermissionNodes() {
|
||||
return this.permissionNodes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the default permission if the permission nodes couldn't be used.
|
||||
*
|
||||
* @return The default permission.
|
||||
*/
|
||||
public DefaultPermission getDefaultPermission() {
|
||||
return this.defaultPermission;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,26 +1,13 @@
|
||||
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.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 fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Service for implementations of {@link ExecutableCommand} to execute some common tasks.
|
||||
@ -28,39 +15,12 @@ import java.util.List;
|
||||
*/
|
||||
public class CommandService {
|
||||
|
||||
private final AuthMe authMe;
|
||||
private final Messages messages;
|
||||
private final HelpProvider helpProvider;
|
||||
private final CommandMapper commandMapper;
|
||||
private final PasswordSecurity passwordSecurity;
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final NewSetting settings;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
private final AntiBot antiBot;
|
||||
private final ValidationService validationService;
|
||||
private final BukkitService bukkitService;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages,
|
||||
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings,
|
||||
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
|
||||
ValidationService validationService, BukkitService bukkitService) {
|
||||
this.authMe = authMe;
|
||||
this.messages = messages;
|
||||
this.helpProvider = helpProvider;
|
||||
this.commandMapper = commandMapper;
|
||||
this.passwordSecurity = passwordSecurity;
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.settings = settings;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
this.antiBot = antiBot;
|
||||
this.validationService = validationService;
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
@Inject
|
||||
private Messages messages;
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
/**
|
||||
* Send a message to a player.
|
||||
@ -83,86 +43,6 @@ public class CommandService {
|
||||
messages.send(sender, messageKey, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map command parts to a command description.
|
||||
*
|
||||
* @param sender The command sender issuing the request (for permission check), or null to skip permissions
|
||||
* @param commandParts The received command parts to map to a command
|
||||
* @return The computed mapping result
|
||||
*/
|
||||
public FoundCommandResult mapPartsToCommand(CommandSender sender, List<String> commandParts) {
|
||||
return commandMapper.mapPartsToCommand(sender, commandParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given task asynchronously with the Bukkit scheduler.
|
||||
*
|
||||
* @param task The task to run
|
||||
*/
|
||||
public void runTaskAsynchronously(Runnable task) {
|
||||
authMe.getServer().getScheduler().runTaskAsynchronously(authMe, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe data source.
|
||||
*
|
||||
* @return The used data source
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return authMe.getDataSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe instance for further manipulation. Use only if other methods from
|
||||
* the command service cannot be used.
|
||||
*
|
||||
* @return The AuthMe instance
|
||||
*/
|
||||
public AuthMe getAuthMe() {
|
||||
return authMe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PasswordSecurity instance.
|
||||
*
|
||||
* @return The password security instance
|
||||
*/
|
||||
public PasswordSecurity getPasswordSecurity() {
|
||||
return passwordSecurity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the help for a given command.
|
||||
*
|
||||
* @param sender The sender to output the help to
|
||||
* @param result The result to output information about
|
||||
* @param options Output options, see {@link HelpProvider}
|
||||
*/
|
||||
public void outputHelp(CommandSender sender, FoundCommandResult result, int options) {
|
||||
List<String> lines = helpProvider.printHelp(sender, result, options);
|
||||
for (String line : lines) {
|
||||
sender.sendMessage(line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the management instance of the plugin.
|
||||
*
|
||||
* @return The Management instance linked to the AuthMe instance
|
||||
*/
|
||||
public Management getManagement() {
|
||||
return authMe.getManagement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the permissions manager.
|
||||
*
|
||||
* @return the permissions manager
|
||||
*/
|
||||
public PermissionsManager getPermissionsManager() {
|
||||
return permissionsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a message by its message key.
|
||||
*
|
||||
@ -193,33 +73,6 @@ public class CommandService {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public PlayerCache getPlayerCache() {
|
||||
return PlayerCache.getInstance();
|
||||
}
|
||||
|
||||
public PluginHooks getPluginHooks() {
|
||||
return pluginHooks;
|
||||
}
|
||||
|
||||
public SpawnLoader getSpawnLoader() {
|
||||
return spawnLoader;
|
||||
}
|
||||
|
||||
public AntiBot getAntiBot() {
|
||||
return antiBot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether a password is valid according to the plugin settings.
|
||||
*
|
||||
* @param password the password to verify
|
||||
* @param username the username the password is associated with
|
||||
* @return message key with the password error, or {@code null} if password is valid
|
||||
*/
|
||||
public MessageKey validatePassword(String password, String username) {
|
||||
return validationService.validatePassword(password, username);
|
||||
}
|
||||
|
||||
public boolean validateEmail(String email) {
|
||||
return validationService.validateEmail(email);
|
||||
}
|
||||
@ -228,16 +81,4 @@ public class CommandService {
|
||||
return validationService.isEmailFreeForRegistration(email, sender);
|
||||
}
|
||||
|
||||
public Player getPlayer(String name) {
|
||||
return bukkitService.getPlayerExact(name);
|
||||
}
|
||||
|
||||
public Collection<? extends Player> getOnlinePlayers() {
|
||||
return bukkitService.getOnlinePlayers();
|
||||
}
|
||||
|
||||
public BukkitService getBukkitService() {
|
||||
return bukkitService;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,12 +10,11 @@ import java.util.List;
|
||||
public interface ExecutableCommand {
|
||||
|
||||
/**
|
||||
* Execute the command with the given arguments.
|
||||
* Executes the command with the given arguments.
|
||||
*
|
||||
* @param sender The command sender.
|
||||
* @param arguments The arguments.
|
||||
* @param commandService The command service.
|
||||
* @param sender the command sender (initiator of the command)
|
||||
* @param arguments the arguments
|
||||
*/
|
||||
void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService);
|
||||
void executeCommand(CommandSender sender, List<String> arguments);
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Common base type for player-only commands, handling the verification that the command sender is indeed a player.
|
||||
*/
|
||||
public abstract class PlayerCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
if (sender instanceof Player) {
|
||||
runCommand((Player) sender, arguments, commandService);
|
||||
runCommand((Player) sender, arguments);
|
||||
} else {
|
||||
String alternative = getAlternativeCommand();
|
||||
if (alternative != null) {
|
||||
@ -25,19 +25,18 @@ public abstract class PlayerCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the command with the given player and arguments.
|
||||
* Runs the command with the given player and arguments.
|
||||
*
|
||||
* @param player The player who initiated the command
|
||||
* @param arguments The arguments supplied with the command
|
||||
* @param commandService The command service
|
||||
* @param player the player who initiated the command
|
||||
* @param arguments the arguments supplied with the command
|
||||
*/
|
||||
protected abstract void runCommand(Player player, List<String> arguments, CommandService commandService);
|
||||
protected abstract void runCommand(Player player, List<String> arguments);
|
||||
|
||||
/**
|
||||
* Return an alternative command (textual representation) that is not restricted to players only.
|
||||
* Example: {@code "authme register <playerName> <password>"}
|
||||
* Returns an alternative command (textual representation) that is not restricted to players only.
|
||||
* Example: {@code "/authme register <playerName> <password>"}
|
||||
*
|
||||
* @return Alternative command not only for players, or null if not applicable
|
||||
* @return Alternative command not restricted to players, or null if not applicable
|
||||
*/
|
||||
protected String getAlternativeCommand() {
|
||||
return null;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package fr.xephi.authme.command.executable;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.CommandMapper;
|
||||
import fr.xephi.authme.command.CommandUtils;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.command.FoundCommandResult;
|
||||
@ -9,6 +9,7 @@ import fr.xephi.authme.command.help.HelpProvider;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.command.FoundResultStatus.MISSING_BASE_COMMAND;
|
||||
@ -16,11 +17,18 @@ import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL;
|
||||
|
||||
public class HelpCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private CommandMapper commandMapper;
|
||||
|
||||
@Inject
|
||||
private HelpProvider helpProvider;
|
||||
|
||||
|
||||
// Convention: arguments is not the actual invoked arguments but the command that was invoked,
|
||||
// e.g. "/authme help register" would typically be arguments = [register], but here we pass [authme, register]
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
FoundCommandResult result = commandService.mapPartsToCommand(sender, arguments);
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
FoundCommandResult result = commandMapper.mapPartsToCommand(sender, arguments);
|
||||
|
||||
FoundResultStatus resultStatus = result.getResultStatus();
|
||||
if (MISSING_BASE_COMMAND.equals(resultStatus)) {
|
||||
@ -38,9 +46,9 @@ public class HelpCommand implements ExecutableCommand {
|
||||
|
||||
int mappedCommandLevel = result.getCommandDescription().getLabelCount();
|
||||
if (mappedCommandLevel == 1) {
|
||||
commandService.outputHelp(sender, result, HelpProvider.SHOW_CHILDREN);
|
||||
helpProvider.outputHelp(sender, result, HelpProvider.SHOW_CHILDREN);
|
||||
} else {
|
||||
commandService.outputHelp(sender, result, HelpProvider.ALL_OPTIONS);
|
||||
helpProvider.outputHelp(sender, result, HelpProvider.ALL_OPTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,13 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -14,25 +17,27 @@ import java.util.List;
|
||||
*/
|
||||
public class AccountsCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments,
|
||||
final CommandService commandService) {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
final String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
// Assumption: a player name cannot contain '.'
|
||||
if (!playerName.contains(".")) {
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
if (playerName.contains(".")) {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName.toLowerCase());
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> accountList = commandService.getDataSource().getAllAuthsByIp(auth.getIp());
|
||||
List<String> accountList = dataSource.getAllAuthsByIp(playerName);
|
||||
if (accountList.isEmpty()) {
|
||||
commandService.send(sender, MessageKey.USER_NOT_REGISTERED);
|
||||
sender.sendMessage("[AuthMe] This IP does not exist in the database.");
|
||||
} else if (accountList.size() == 1) {
|
||||
sender.sendMessage("[AuthMe] " + playerName + " is a single account player");
|
||||
} else {
|
||||
@ -41,12 +46,18 @@ public class AccountsCommand implements ExecutableCommand {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<String> accountList = commandService.getDataSource().getAllAuthsByIp(playerName);
|
||||
PlayerAuth auth = dataSource.getAuth(playerName.toLowerCase());
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> accountList = dataSource.getAllAuthsByIp(auth.getIp());
|
||||
if (accountList.isEmpty()) {
|
||||
sender.sendMessage("[AuthMe] This IP does not exist in the database.");
|
||||
commandService.send(sender, MessageKey.USER_NOT_REGISTERED);
|
||||
} else if (accountList.size() == 1) {
|
||||
sender.sendMessage("[AuthMe] " + playerName + " is a single account player");
|
||||
} else {
|
||||
|
@ -1,7 +1,6 @@
|
||||
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.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -14,7 +13,7 @@ import java.util.List;
|
||||
public class AuthMeCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
sender.sendMessage(ChatColor.GREEN + "This server is running " + AuthMe.getPluginName() + " v"
|
||||
+ AuthMe.getPluginVersion() + " b" + AuthMe.getPluginBuildNumber()+ "! " + ChatColor.RED + "<3");
|
||||
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/authme help" + ChatColor.YELLOW
|
||||
|
@ -2,13 +2,19 @@ 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;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import fr.xephi.authme.util.ValidationService.ValidationResult;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -16,30 +22,46 @@ import java.util.List;
|
||||
*/
|
||||
public class ChangePasswordAdminCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private PasswordSecurity passwordSecurity;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments,
|
||||
final CommandService commandService) {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
// Get the player and password
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerPass = arguments.get(1);
|
||||
|
||||
// Validate the password
|
||||
MessageKey passwordError = commandService.validatePassword(playerPass, playerName);
|
||||
if (passwordError != null) {
|
||||
commandService.send(sender, passwordError);
|
||||
ValidationResult validationResult = validationService.validatePassword(playerPass, playerName);
|
||||
if (validationResult.hasError()) {
|
||||
commandService.send(sender, validationResult.getMessageKey(), validationResult.getArgs());
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the password
|
||||
final String playerNameLowerCase = playerName.toLowerCase();
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
DataSource dataSource = commandService.getDataSource();
|
||||
PlayerAuth auth = null;
|
||||
if (commandService.getPlayerCache().isAuthenticated(playerNameLowerCase)) {
|
||||
auth = commandService.getPlayerCache().getAuth(playerNameLowerCase);
|
||||
if (playerCache.isAuthenticated(playerNameLowerCase)) {
|
||||
auth = playerCache.getAuth(playerNameLowerCase);
|
||||
} else if (dataSource.isAuthAvailable(playerNameLowerCase)) {
|
||||
auth = dataSource.getAuth(playerNameLowerCase);
|
||||
}
|
||||
@ -48,15 +70,14 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
HashedPassword hashedPassword = commandService.getPasswordSecurity()
|
||||
.computeHash(playerPass, playerNameLowerCase);
|
||||
HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase);
|
||||
auth.setPassword(hashedPassword);
|
||||
|
||||
if (!dataSource.updatePassword(auth)) {
|
||||
commandService.send(sender, MessageKey.ERROR);
|
||||
} else {
|
||||
if (dataSource.updatePassword(auth)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
|
||||
ConsoleLogger.info(playerNameLowerCase + "'s password changed");
|
||||
} else {
|
||||
commandService.send(sender, MessageKey.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.converter.Converter;
|
||||
@ -10,18 +10,30 @@ import fr.xephi.authme.converter.RoyalAuthConverter;
|
||||
import fr.xephi.authme.converter.SqliteToSql;
|
||||
import fr.xephi.authme.converter.vAuthConverter;
|
||||
import fr.xephi.authme.converter.xAuthConverter;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Converter command: launches conversion based on its parameters.
|
||||
*/
|
||||
public class ConverterCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// AuthMe plugin instance
|
||||
final AuthMe plugin = AuthMe.getInstance();
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private AuthMeServiceInitializer initializer;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
// Get the conversion job
|
||||
String job = arguments.get(0);
|
||||
|
||||
@ -33,49 +45,35 @@ public class ConverterCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
// Get the proper converter instance
|
||||
Converter converter = null;
|
||||
switch (jobType) {
|
||||
case XAUTH:
|
||||
converter = new xAuthConverter(plugin, sender);
|
||||
break;
|
||||
case CRAZYLOGIN:
|
||||
converter = new CrazyLoginConverter(plugin, sender);
|
||||
break;
|
||||
case RAKAMAK:
|
||||
converter = new RakamakConverter(plugin, sender);
|
||||
break;
|
||||
case ROYALAUTH:
|
||||
converter = new RoyalAuthConverter(plugin);
|
||||
break;
|
||||
case VAUTH:
|
||||
converter = new vAuthConverter(plugin, sender);
|
||||
break;
|
||||
case SQLITETOSQL:
|
||||
converter = new SqliteToSql(plugin, sender, commandService.getSettings());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
final Converter converter = initializer.newInstance(jobType.getConverterClass());
|
||||
|
||||
// Run the convert job
|
||||
commandService.runTaskAsynchronously(converter);
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
converter.execute(sender);
|
||||
}
|
||||
});
|
||||
|
||||
// Show a status message
|
||||
sender.sendMessage("[AuthMe] Successfully converted from " + jobType.getName());
|
||||
}
|
||||
|
||||
public enum ConvertType {
|
||||
XAUTH("xauth"),
|
||||
CRAZYLOGIN("crazylogin"),
|
||||
RAKAMAK("rakamak"),
|
||||
ROYALAUTH("royalauth"),
|
||||
VAUTH("vauth"),
|
||||
SQLITETOSQL("sqlitetosql");
|
||||
@VisibleForTesting
|
||||
enum ConvertType {
|
||||
XAUTH("xauth", xAuthConverter.class),
|
||||
CRAZYLOGIN("crazylogin", CrazyLoginConverter.class),
|
||||
RAKAMAK("rakamak", RakamakConverter.class),
|
||||
ROYALAUTH("royalauth", RoyalAuthConverter.class),
|
||||
VAUTH("vauth", vAuthConverter.class),
|
||||
SQLITETOSQL("sqlitetosql", SqliteToSql.class);
|
||||
|
||||
final String name;
|
||||
private final String name;
|
||||
private final Class<? extends Converter> converterClass;
|
||||
|
||||
ConvertType(String name) {
|
||||
ConvertType(String name, Class<? extends Converter> converterClass) {
|
||||
this.name = name;
|
||||
this.converterClass = converterClass;
|
||||
}
|
||||
|
||||
public static ConvertType fromName(String name) {
|
||||
@ -87,8 +85,12 @@ public class ConverterCommand implements ExecutableCommand {
|
||||
return null;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Class<? extends Converter> getConverterClass() {
|
||||
return converterClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -11,12 +12,15 @@ import java.util.List;
|
||||
*/
|
||||
public class FirstSpawnCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (commandService.getSpawnLoader().getFirstSpawn() != null) {
|
||||
player.teleport(commandService.getSpawnLoader().getFirstSpawn());
|
||||
} else {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
if (spawnLoader.getFirstSpawn() == null) {
|
||||
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
|
||||
} else {
|
||||
player.teleport(spawnLoader.getFirstSpawn());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.permission.PlayerPermission.CAN_LOGIN_BE_FORCED;
|
||||
@ -14,18 +17,27 @@ import static fr.xephi.authme.permission.PlayerPermission.CAN_LOGIN_BE_FORCED;
|
||||
*/
|
||||
public class ForceLoginCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
// Get the player query
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
Player player = commandService.getPlayer(playerName);
|
||||
Player player = bukkitService.getPlayerExact(playerName);
|
||||
if (player == null || !player.isOnline()) {
|
||||
sender.sendMessage("Player needs to be online!");
|
||||
} else if (!commandService.getPermissionsManager().hasPermission(player, CAN_LOGIN_BE_FORCED)) {
|
||||
} else if (!permissionsManager.hasPermission(player, CAN_LOGIN_BE_FORCED)) {
|
||||
sender.sendMessage("You cannot force login the player " + playerName + "!");
|
||||
} else {
|
||||
commandService.getManagement().performLogin(player, "dontneed", true);
|
||||
management.performLogin(player, "dontneed", true);
|
||||
sender.sendMessage("Force login for " + playerName + " performed!");
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -13,11 +15,17 @@ import java.util.List;
|
||||
*/
|
||||
public class GetEmailCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
|
||||
PlayerAuth auth = dataSource.getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
} else {
|
||||
|
@ -1,20 +1,24 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class GetIpCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
// Get the player query
|
||||
String playerName = arguments.get(0);
|
||||
|
||||
Player player = commandService.getPlayer(playerName);
|
||||
Player player = bukkitService.getPlayerExact(playerName);
|
||||
if (player == null) {
|
||||
sender.sendMessage("The player is not online");
|
||||
return;
|
||||
|
@ -3,9 +3,11 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -14,12 +16,18 @@ import java.util.List;
|
||||
*/
|
||||
public class LastLoginCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
// Get the player
|
||||
String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
|
||||
|
||||
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
|
||||
PlayerAuth auth = dataSource.getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.USER_NOT_REGISTERED);
|
||||
return;
|
||||
|
@ -1,14 +1,18 @@
|
||||
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.properties.PurgeSettings;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.task.PurgeTask;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Command for purging data of banned players. Depending on the settings
|
||||
@ -16,30 +20,30 @@ import java.util.List;
|
||||
*/
|
||||
public class PurgeBannedPlayersCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// AuthMe plugin instance
|
||||
final AuthMe plugin = commandService.getAuthMe();
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private AuthMe plugin;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
// Get the list of banned players
|
||||
List<String> bannedPlayers = new ArrayList<>();
|
||||
for (OfflinePlayer offlinePlayer : plugin.getServer().getBannedPlayers()) {
|
||||
bannedPlayers.add(offlinePlayer.getName().toLowerCase());
|
||||
Set<String> namedBanned = new HashSet<>();
|
||||
Set<OfflinePlayer> bannedPlayers = bukkitService.getBannedPlayers();
|
||||
for (OfflinePlayer offlinePlayer : bannedPlayers) {
|
||||
namedBanned.add(offlinePlayer.getName().toLowerCase());
|
||||
}
|
||||
|
||||
//todo: note this should may run async because it may executes a SQL-Query
|
||||
// Purge the banned players
|
||||
commandService.getDataSource().purgeBanned(bannedPlayers);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)
|
||||
&& commandService.getPluginHooks().isEssentialsAvailable())
|
||||
plugin.dataManager.purgeEssentials(bannedPlayers);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
|
||||
plugin.dataManager.purgeDat(bannedPlayers);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
|
||||
plugin.dataManager.purgeLimitedCreative(bannedPlayers);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
|
||||
plugin.dataManager.purgeAntiXray(bannedPlayers);
|
||||
dataSource.purgeBanned(namedBanned);
|
||||
|
||||
// Show a status message
|
||||
sender.sendMessage("[AuthMe] Database has been purged correctly");
|
||||
sender.sendMessage(ChatColor.GOLD + "Purging user accounts...");
|
||||
new PurgeTask(plugin, sender, namedBanned, bannedPlayers).runTaskTimer(plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
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.properties.PurgeSettings;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.task.PurgeTask;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Command for purging the data of players which have not been since for a given number
|
||||
@ -18,8 +20,14 @@ public class PurgeCommand implements ExecutableCommand {
|
||||
|
||||
private static final int MINIMUM_LAST_SEEN_DAYS = 30;
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private AuthMe plugin;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
// Get the days parameter
|
||||
String daysStr = arguments.get(0);
|
||||
|
||||
@ -44,25 +52,13 @@ public class PurgeCommand implements ExecutableCommand {
|
||||
calendar.add(Calendar.DATE, -days);
|
||||
long until = calendar.getTimeInMillis();
|
||||
|
||||
//todo: note this should may run async because it may executes a SQL-Query
|
||||
// Purge the data, get the purged values
|
||||
List<String> purged = commandService.getDataSource().autoPurgeDatabase(until);
|
||||
Set<String> purged = dataSource.autoPurgeDatabase(until);
|
||||
|
||||
// Show a status message
|
||||
sender.sendMessage(ChatColor.GOLD + "Deleted " + purged.size() + " user accounts");
|
||||
|
||||
// Purge other data
|
||||
AuthMe plugin = commandService.getAuthMe();
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES) &&
|
||||
commandService.getPluginHooks().isEssentialsAvailable())
|
||||
plugin.dataManager.purgeEssentials(purged);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
|
||||
plugin.dataManager.purgeDat(purged);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
|
||||
plugin.dataManager.purgeLimitedCreative(purged);
|
||||
if (commandService.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
|
||||
plugin.dataManager.purgeAntiXray(purged);
|
||||
|
||||
// Show a status message
|
||||
sender.sendMessage(ChatColor.GREEN + "[AuthMe] Database has been purged correctly");
|
||||
sender.sendMessage(ChatColor.GOLD + "Purging user accounts...");
|
||||
new PurgeTask(plugin, sender, purged).runTaskTimer(plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -13,26 +15,32 @@ import java.util.List;
|
||||
*/
|
||||
public class PurgeLastPositionCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
if ("*".equals(playerName)) {
|
||||
for (PlayerAuth auth : commandService.getDataSource().getAllAuths()) {
|
||||
for (PlayerAuth auth : dataSource.getAllAuths()) {
|
||||
resetLastPosition(auth);
|
||||
commandService.getDataSource().updateQuitLoc(auth);
|
||||
dataSource.updateQuitLoc(auth);
|
||||
}
|
||||
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(playerName);
|
||||
PlayerAuth auth = dataSource.getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
resetLastPosition(auth);
|
||||
commandService.getDataSource().updateQuitLoc(auth);
|
||||
dataSource.updateQuitLoc(auth);
|
||||
sender.sendMessage(playerName + "'s last position location is now reset");
|
||||
}
|
||||
}
|
||||
|
@ -1,68 +1,85 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import fr.xephi.authme.util.ValidationService.ValidationResult;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Admin command to register a user.
|
||||
*/
|
||||
public class RegisterAdminCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private PasswordSecurity passwordSecurity;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments,
|
||||
final CommandService commandService) {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
// Get the player name and password
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerPass = arguments.get(1);
|
||||
final String playerNameLowerCase = playerName.toLowerCase();
|
||||
|
||||
// Command logic
|
||||
MessageKey passwordError = commandService.validatePassword(playerPass, playerName);
|
||||
if (passwordError != null) {
|
||||
commandService.send(sender, passwordError);
|
||||
ValidationResult passwordValidation = validationService.validatePassword(playerPass, playerName);
|
||||
if (passwordValidation.hasError()) {
|
||||
commandService.send(sender, passwordValidation.getMessageKey(), passwordValidation.getArgs());
|
||||
return;
|
||||
}
|
||||
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (commandService.getDataSource().isAuthAvailable(playerNameLowerCase)) {
|
||||
if (dataSource.isAuthAvailable(playerNameLowerCase)) {
|
||||
commandService.send(sender, MessageKey.NAME_ALREADY_REGISTERED);
|
||||
return;
|
||||
}
|
||||
HashedPassword hashedPassword = commandService.getPasswordSecurity()
|
||||
.computeHash(playerPass, playerNameLowerCase);
|
||||
HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(playerNameLowerCase)
|
||||
.realName(playerName)
|
||||
.password(hashedPassword)
|
||||
.build();
|
||||
|
||||
if (!commandService.getDataSource().saveAuth(auth)) {
|
||||
if (!dataSource.saveAuth(auth)) {
|
||||
commandService.send(sender, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
commandService.getDataSource().setUnlogged(playerNameLowerCase);
|
||||
dataSource.setUnlogged(playerNameLowerCase);
|
||||
|
||||
commandService.send(sender, MessageKey.REGISTER_SUCCESS);
|
||||
ConsoleLogger.info(sender.getName() + " registered " + playerName);
|
||||
Player player = commandService.getPlayer(playerName);
|
||||
final Player player = bukkitService.getPlayerExact(playerName);
|
||||
if (player != null) {
|
||||
final Player p = player;
|
||||
p.getServer().getScheduler().scheduleSyncDelayedTask(commandService.getAuthMe(), new Runnable() {
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
p.kickPlayer("An admin just registered you, please log in again");
|
||||
player.kickPlayer("An admin just registered you, please log in again");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -4,9 +4,14 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -14,11 +19,32 @@ import java.util.List;
|
||||
*/
|
||||
public class ReloadCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private AuthMe plugin;
|
||||
|
||||
@Inject
|
||||
private AuthMeServiceInitializer initializer;
|
||||
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
AuthMe plugin = commandService.getAuthMe();
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
try {
|
||||
plugin.reload();
|
||||
settings.reload();
|
||||
ConsoleLogger.setLoggingOptions(settings);
|
||||
// We do not change database type for consistency issues, but we'll output a note in the logs
|
||||
if (!settings.getProperty(DatabaseSettings.BACKEND).equals(dataSource.getType())) {
|
||||
ConsoleLogger.info("Note: cannot change database type during /authme reload");
|
||||
sender.sendMessage("Note: cannot change database type during /authme reload");
|
||||
}
|
||||
initializer.performReloadOnServices();
|
||||
commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage("Error occurred during reload of AuthMe: aborting");
|
||||
|
@ -6,8 +6,10 @@ import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,9 +17,20 @@ import java.util.List;
|
||||
*/
|
||||
public class SetEmailCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments,
|
||||
final CommandService commandService) {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
// Get the player name and email address
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerEmail = arguments.get(1);
|
||||
@ -28,11 +41,10 @@ public class SetEmailCommand implements ExecutableCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
commandService.runTaskAsynchronously(new Runnable() {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Validate the user
|
||||
DataSource dataSource = commandService.getDataSource();
|
||||
PlayerAuth auth = dataSource.getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
@ -50,8 +62,8 @@ public class SetEmailCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
// Update the player cache
|
||||
if (PlayerCache.getInstance().getAuth(playerName) != null) {
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
if (playerCache.getAuth(playerName) != null) {
|
||||
playerCache.updatePlayer(auth);
|
||||
}
|
||||
|
||||
// Show a status message
|
||||
|
@ -1,16 +1,20 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class SetFirstSpawnCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (commandService.getSpawnLoader().setFirstSpawn(player.getLocation())) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
if (spawnLoader.setFirstSpawn(player.getLocation())) {
|
||||
player.sendMessage("[AuthMe] Correctly defined new first spawn point");
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] SetFirstSpawn has failed, please retry");
|
||||
|
@ -1,16 +1,20 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class SetSpawnCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (commandService.getSpawnLoader().setSpawn(player.getLocation())) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
if (spawnLoader.setSpawn(player.getLocation())) {
|
||||
player.sendMessage("[AuthMe] Correctly defined new spawn point");
|
||||
} else {
|
||||
player.sendMessage("[AuthMe] SetSpawn has failed, please retry");
|
||||
|
@ -1,19 +1,23 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class SpawnCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
if (commandService.getSpawnLoader().getSpawn() != null) {
|
||||
player.teleport(commandService.getSpawnLoader().getSpawn());
|
||||
} else {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
if (spawnLoader.getSpawn() == null) {
|
||||
player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
|
||||
} else {
|
||||
player.teleport(spawnLoader.getSpawn());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.AntiBot;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.CommandMapper;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.command.FoundCommandResult;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -16,9 +17,17 @@ import java.util.List;
|
||||
*/
|
||||
public class SwitchAntiBotCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private AntiBot antiBot;
|
||||
|
||||
@Inject
|
||||
private CommandMapper commandMapper;
|
||||
|
||||
@Inject
|
||||
private HelpProvider helpProvider;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
AntiBot antiBot = commandService.getAntiBot();
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
if (arguments.isEmpty()) {
|
||||
sender.sendMessage("[AuthMe] AntiBot status: " + antiBot.getAntiBotStatus().name());
|
||||
return;
|
||||
@ -35,8 +44,8 @@ public class SwitchAntiBotCommand implements ExecutableCommand {
|
||||
sender.sendMessage("[AuthMe] AntiBot Manual Override: disabled!");
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Invalid AntiBot mode!");
|
||||
FoundCommandResult result = commandService.mapPartsToCommand(sender, Arrays.asList("authme", "antibot"));
|
||||
commandService.outputHelp(sender, result, HelpProvider.SHOW_ARGUMENTS);
|
||||
FoundCommandResult result = commandMapper.mapPartsToCommand(sender, Arrays.asList("authme", "antibot"));
|
||||
helpProvider.outputHelp(sender, result, HelpProvider.SHOW_ARGUMENTS);
|
||||
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/authme help antibot");
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,25 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.permission.AuthGroupHandler;
|
||||
import fr.xephi.authme.permission.AuthGroupType;
|
||||
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.task.LimboPlayerTaskManager;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
|
||||
@ -28,31 +29,53 @@ import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
|
||||
*/
|
||||
public class UnregisterAdminCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private LimboCache limboCache;
|
||||
|
||||
@Inject
|
||||
private LimboPlayerTaskManager limboPlayerTaskManager;
|
||||
|
||||
@Inject
|
||||
private AuthGroupHandler authGroupHandler;
|
||||
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
// Get the player name
|
||||
String playerName = arguments.get(0);
|
||||
String playerNameLowerCase = playerName.toLowerCase();
|
||||
|
||||
// Make sure the user is valid
|
||||
if (!commandService.getDataSource().isAuthAvailable(playerNameLowerCase)) {
|
||||
if (!dataSource.isAuthAvailable(playerNameLowerCase)) {
|
||||
commandService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the player
|
||||
if (!commandService.getDataSource().removeAuth(playerNameLowerCase)) {
|
||||
if (!dataSource.removeAuth(playerNameLowerCase)) {
|
||||
commandService.send(sender, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unregister the player
|
||||
Player target = commandService.getPlayer(playerNameLowerCase);
|
||||
PlayerCache.getInstance().removePlayer(playerNameLowerCase);
|
||||
Utils.setGroup(target, Utils.GroupType.UNREGISTERED);
|
||||
Player target = bukkitService.getPlayerExact(playerNameLowerCase);
|
||||
playerCache.removePlayer(playerNameLowerCase);
|
||||
authGroupHandler.setGroup(target, AuthGroupType.UNREGISTERED);
|
||||
if (target != null && target.isOnline()) {
|
||||
if (commandService.getProperty(RegistrationSettings.FORCE)) {
|
||||
applyUnregisteredEffectsAndTasks(target, commandService);
|
||||
applyUnregisteredEffectsAndTasks(target);
|
||||
}
|
||||
commandService.send(target, MessageKey.UNREGISTERED_SUCCESS);
|
||||
}
|
||||
@ -68,27 +91,18 @@ public class UnregisterAdminCommand implements ExecutableCommand {
|
||||
* timeout kick, blindness.
|
||||
*
|
||||
* @param target the player that was unregistered
|
||||
* @param service the command service
|
||||
*/
|
||||
private void applyUnregisteredEffectsAndTasks(Player target, CommandService service) {
|
||||
final AuthMe plugin = service.getAuthMe();
|
||||
final BukkitService bukkitService = service.getBukkitService();
|
||||
final String playerNameLowerCase = target.getName().toLowerCase();
|
||||
|
||||
private void applyUnregisteredEffectsAndTasks(Player target) {
|
||||
// TODO #765: Remove use of Utils method and behave according to settings
|
||||
Utils.teleportToSpawn(target);
|
||||
LimboCache.getInstance().addLimboPlayer(target);
|
||||
int timeOut = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
int interval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
|
||||
if (timeOut != 0) {
|
||||
BukkitTask id = bukkitService.runTaskLater(new TimeoutTask(plugin, playerNameLowerCase, target), timeOut);
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTask(id);
|
||||
}
|
||||
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTask(
|
||||
bukkitService.runTask(new MessageTask(service.getBukkitService(), plugin.getMessages(),
|
||||
playerNameLowerCase, MessageKey.REGISTER_MESSAGE, interval)));
|
||||
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
|
||||
limboCache.addLimboPlayer(target);
|
||||
limboPlayerTaskManager.registerTimeoutTask(target);
|
||||
limboPlayerTaskManager.registerMessageTask(target.getName(), false);
|
||||
|
||||
final int timeout = commandService.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
if (commandService.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,12 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@ -14,15 +16,21 @@ import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
|
||||
public class VersionCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
// Show some version info
|
||||
sender.sendMessage(ChatColor.GOLD + "==========[ " + commandService.getProperty(HELP_HEADER)
|
||||
+ " ABOUT ]==========");
|
||||
sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName()
|
||||
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
|
||||
sender.sendMessage(ChatColor.GOLD + "Developers:");
|
||||
Collection<? extends Player> onlinePlayers = commandService.getOnlinePlayers();
|
||||
Collection<? extends Player> onlinePlayers = bukkitService.getOnlinePlayers();
|
||||
printDeveloper(sender, "Xephi", "xephi59", "Lead Developer", onlinePlayers);
|
||||
printDeveloper(sender, "DNx5", "DNx5", "Developer", onlinePlayers);
|
||||
printDeveloper(sender, "games647", "games647", "Developer", onlinePlayers);
|
||||
|
@ -1,55 +1,47 @@
|
||||
package fr.xephi.authme.command.executable.captcha;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.CaptchaManager;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class CaptchaCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private CaptchaManager captchaManager;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
final String playerNameLowerCase = player.getName().toLowerCase();
|
||||
final String captcha = arguments.get(0);
|
||||
final AuthMe plugin = commandService.getAuthMe();
|
||||
PlayerCache playerCache = PlayerCache.getInstance();
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
final String playerName = player.getName().toLowerCase();
|
||||
|
||||
// Command logic
|
||||
if (playerCache.isAuthenticated(playerNameLowerCase)) {
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!commandService.getProperty(SecuritySettings.USE_CAPTCHA)) {
|
||||
} else if (!captchaManager.isCaptchaRequired(playerName)) {
|
||||
commandService.send(player, MessageKey.USAGE_LOGIN);
|
||||
return;
|
||||
} else {
|
||||
checkCaptcha(player, arguments.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
if (!plugin.cap.containsKey(playerNameLowerCase)) {
|
||||
commandService.send(player, MessageKey.USAGE_LOGIN);
|
||||
return;
|
||||
private void checkCaptcha(Player player, String captchaCode) {
|
||||
final boolean isCorrectCode = captchaManager.checkCode(player.getName(), captchaCode);
|
||||
if (isCorrectCode) {
|
||||
commandService.send(player, MessageKey.CAPTCHA_SUCCESS);
|
||||
commandService.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else {
|
||||
String newCode = captchaManager.generateCode(player.getName());
|
||||
commandService.send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode);
|
||||
}
|
||||
|
||||
if (!captcha.equals(plugin.cap.get(playerNameLowerCase))) {
|
||||
plugin.cap.remove(playerNameLowerCase);
|
||||
int captchaLength = commandService.getProperty(SecuritySettings.CAPTCHA_LENGTH);
|
||||
String randStr = RandomString.generate(captchaLength);
|
||||
plugin.cap.put(playerNameLowerCase, randStr);
|
||||
commandService.send(player, MessageKey.CAPTCHA_WRONG_ERROR, plugin.cap.get(playerNameLowerCase));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.captcha.remove(playerNameLowerCase);
|
||||
plugin.cap.remove(playerNameLowerCase);
|
||||
|
||||
// Show a status message
|
||||
commandService.send(player, MessageKey.CAPTCHA_SUCCESS);
|
||||
commandService.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
package fr.xephi.authme.command.executable.changepassword;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.task.ChangePasswordTask;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import fr.xephi.authme.util.ValidationService.ValidationResult;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,27 +17,37 @@ import java.util.List;
|
||||
*/
|
||||
public class ChangePasswordCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
String oldPassword = arguments.get(0);
|
||||
String newPassword = arguments.get(1);
|
||||
|
||||
String name = player.getName().toLowerCase();
|
||||
final PlayerCache playerCache = commandService.getPlayerCache();
|
||||
if (!playerCache.isAuthenticated(name)) {
|
||||
commandService.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the password is allowed
|
||||
MessageKey passwordError = commandService.validatePassword(newPassword, name);
|
||||
if (passwordError != null) {
|
||||
commandService.send(player, passwordError);
|
||||
ValidationResult passwordValidation = validationService.validatePassword(newPassword, name);
|
||||
if (passwordValidation.hasError()) {
|
||||
commandService.send(player, passwordValidation.getMessageKey(), passwordValidation.getArgs());
|
||||
return;
|
||||
}
|
||||
|
||||
AuthMe plugin = AuthMe.getInstance();
|
||||
// TODO ljacqu 20160117: Call async task via Management
|
||||
commandService.runTaskAsynchronously(new ChangePasswordTask(plugin, player, oldPassword, newPassword));
|
||||
management.performPasswordChange(player, oldPassword, newPassword);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package fr.xephi.authme.command.executable.email;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -12,14 +14,20 @@ import java.util.List;
|
||||
*/
|
||||
public class AddEmailCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
String email = arguments.get(0);
|
||||
String emailConfirmation = arguments.get(1);
|
||||
|
||||
if (email.equals(emailConfirmation)) {
|
||||
// Closer inspection of the mail address handled by the async task
|
||||
commandService.getManagement().performAddEmail(player, email);
|
||||
management.performAddEmail(player, email);
|
||||
} else {
|
||||
commandService.send(player, MessageKey.CONFIRM_EMAIL_MESSAGE);
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package fr.xephi.authme.command.executable.email;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -11,11 +12,14 @@ import java.util.List;
|
||||
*/
|
||||
public class ChangeEmailCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
String playerMailOld = arguments.get(0);
|
||||
String playerMailNew = arguments.get(1);
|
||||
|
||||
commandService.getManagement().performChangeEmail(player, playerMailOld, playerMailNew);
|
||||
management.performChangeEmail(player, playerMailOld, playerMailNew);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
package fr.xephi.authme.command.executable.email;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.CommandMapper;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.command.FoundCommandResult;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@ -14,9 +15,15 @@ import java.util.List;
|
||||
*/
|
||||
public class EmailBaseCommand implements ExecutableCommand {
|
||||
|
||||
@Inject
|
||||
private CommandMapper commandMapper;
|
||||
|
||||
@Inject
|
||||
private HelpProvider helpProvider;
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
FoundCommandResult result = commandService.mapPartsToCommand(sender, Collections.singletonList("email"));
|
||||
commandService.outputHelp(sender, result, HelpProvider.SHOW_CHILDREN);
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
FoundCommandResult result = commandMapper.mapPartsToCommand(sender, Collections.singletonList("email"));
|
||||
helpProvider.outputHelp(sender, result, HelpProvider.SHOW_CHILDREN);
|
||||
}
|
||||
}
|
||||
|
@ -8,28 +8,44 @@ import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class RecoverEmailCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private PasswordSecurity passwordSecurity;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
// TODO #655: Remove injected AuthMe instance once Authme#mail is encapsulated
|
||||
private AuthMe plugin;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
final String playerMail = arguments.get(0);
|
||||
final String playerName = player.getName();
|
||||
final AuthMe plugin = commandService.getAuthMe();
|
||||
|
||||
if (plugin.mail == null) {
|
||||
ConsoleLogger.showError("Mail API is not set");
|
||||
commandService.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
DataSource dataSource = commandService.getDataSource();
|
||||
if (dataSource.isAuthAvailable(playerName)) {
|
||||
if (PlayerCache.getInstance().isAuthenticated(playerName)) {
|
||||
commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
@ -37,10 +53,10 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
}
|
||||
|
||||
String thePass = RandomString.generate(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH));
|
||||
HashedPassword hashNew = commandService.getPasswordSecurity().computeHash(thePass, playerName);
|
||||
HashedPassword hashNew = passwordSecurity.computeHash(thePass, playerName);
|
||||
PlayerAuth auth;
|
||||
if (PlayerCache.getInstance().isAuthenticated(playerName)) {
|
||||
auth = PlayerCache.getInstance().getAuth(playerName);
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
auth = playerCache.getAuth(playerName);
|
||||
} else if (dataSource.isAuthAvailable(playerName)) {
|
||||
auth = dataSource.getAuth(playerName);
|
||||
} else {
|
||||
|
@ -1,9 +1,10 @@
|
||||
package fr.xephi.authme.command.executable.login;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -11,9 +12,12 @@ import java.util.List;
|
||||
*/
|
||||
public class LoginCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
final String password = arguments.get(0);
|
||||
commandService.getManagement().performLogin(player, password, false);
|
||||
management.performLogin(player, password, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package fr.xephi.authme.command.executable.logout;
|
||||
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -11,8 +12,11 @@ import java.util.List;
|
||||
*/
|
||||
public class LogoutCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
commandService.getManagement().performLogout(player);
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
management.performLogout(player);
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,14 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH;
|
||||
@ -19,25 +21,31 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ENABLE_PAS
|
||||
|
||||
public class RegisterCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
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, "", "");
|
||||
management.performRegister(player, "", "", true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure that there is 1 argument, or 2 if confirmation is required
|
||||
final boolean useConfirmation = isConfirmationRequired(commandService);
|
||||
final boolean useConfirmation = isConfirmationRequired();
|
||||
if (arguments.isEmpty() || useConfirmation && arguments.size() < 2) {
|
||||
commandService.send(player, MessageKey.USAGE_REGISTER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandService.getProperty(USE_EMAIL_REGISTRATION)) {
|
||||
handleEmailRegistration(player, arguments, commandService);
|
||||
handleEmailRegistration(player, arguments);
|
||||
} else {
|
||||
handlePasswordRegistration(player, arguments, commandService);
|
||||
handlePasswordRegistration(player, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,15 +54,15 @@ public class RegisterCommand extends PlayerCommand {
|
||||
return "/authme register <playername> <password>";
|
||||
}
|
||||
|
||||
private void handlePasswordRegistration(Player player, List<String> arguments, CommandService commandService) {
|
||||
private void handlePasswordRegistration(Player player, List<String> arguments) {
|
||||
if (commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION) && !arguments.get(0).equals(arguments.get(1))) {
|
||||
commandService.send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
} else {
|
||||
commandService.getManagement().performRegister(player, arguments.get(0), "");
|
||||
management.performRegister(player, arguments.get(0), "", true);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEmailRegistration(Player player, List<String> arguments, CommandService commandService) {
|
||||
private void handleEmailRegistration(Player player, List<String> arguments) {
|
||||
if (commandService.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
|
||||
player.sendMessage("Cannot register: no email address is set for the server. "
|
||||
+ "Please contact an administrator");
|
||||
@ -70,17 +78,16 @@ public class RegisterCommand extends PlayerCommand {
|
||||
commandService.send(player, MessageKey.USAGE_REGISTER);
|
||||
} else {
|
||||
String thePass = RandomString.generate(commandService.getProperty(RECOVERY_PASSWORD_LENGTH));
|
||||
commandService.getManagement().performRegister(player, thePass, email);
|
||||
management.performRegister(player, thePass, email, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the password or email has to be confirmed.
|
||||
*
|
||||
* @param commandService The command service
|
||||
* @return True if the confirmation is needed, false otherwise
|
||||
*/
|
||||
private boolean isConfirmationRequired(CommandService commandService) {
|
||||
private boolean isConfirmationRequired() {
|
||||
return commandService.getProperty(USE_EMAIL_REGISTRATION)
|
||||
? commandService.getProperty(ENABLE_CONFIRM_EMAIL)
|
||||
: commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION);
|
||||
|
@ -4,24 +4,35 @@ import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class UnregisterCommand extends PlayerCommand {
|
||||
|
||||
@Inject
|
||||
private Management management;
|
||||
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
String playerPass = arguments.get(0);
|
||||
final String playerNameLowerCase = player.getName().toLowerCase();
|
||||
|
||||
// Make sure the player is authenticated
|
||||
if (!PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) {
|
||||
if (!playerCache.isAuthenticated(playerNameLowerCase)) {
|
||||
commandService.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unregister the player
|
||||
commandService.getManagement().performUnregister(player, playerPass, false);
|
||||
management.performUnregister(player, playerPass, false);
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,18 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import fr.xephi.authme.command.CommandArgumentDescription;
|
||||
import fr.xephi.authme.command.CommandDescription;
|
||||
import fr.xephi.authme.command.CommandPermissions;
|
||||
import fr.xephi.authme.command.CommandUtils;
|
||||
import fr.xephi.authme.command.FoundCommandResult;
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.permission.DefaultPermission;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -23,7 +25,7 @@ import static java.util.Collections.singletonList;
|
||||
/**
|
||||
* Help syntax generator for AuthMe commands.
|
||||
*/
|
||||
public class HelpProvider {
|
||||
public class HelpProvider implements SettingsDependent {
|
||||
|
||||
// --- Bit flags ---
|
||||
/** Set to <i>not</i> show the command. */
|
||||
@ -43,14 +45,15 @@ public class HelpProvider {
|
||||
public static final int ALL_OPTIONS = ~HIDE_COMMAND;
|
||||
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final String helpHeader;
|
||||
private String helpHeader;
|
||||
|
||||
public HelpProvider(PermissionsManager permissionsManager, String helpHeader) {
|
||||
@Inject
|
||||
HelpProvider(PermissionsManager permissionsManager, NewSetting settings) {
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.helpHeader = helpHeader;
|
||||
loadSettings(settings);
|
||||
}
|
||||
|
||||
public List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) {
|
||||
private List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) {
|
||||
if (result.getCommandDescription() == null) {
|
||||
return singletonList(ChatColor.DARK_RED + "Failed to retrieve any help information!");
|
||||
}
|
||||
@ -84,6 +87,25 @@ public class HelpProvider {
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the help for a given command.
|
||||
*
|
||||
* @param sender The sender to output the help to
|
||||
* @param result The result to output information about
|
||||
* @param options Output options, see {@link HelpProvider}
|
||||
*/
|
||||
public void outputHelp(CommandSender sender, FoundCommandResult result, int options) {
|
||||
List<String> lines = printHelp(sender, result, options);
|
||||
for (String line : lines) {
|
||||
sender.sendMessage(line);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings(NewSetting settings) {
|
||||
helpHeader = settings.getProperty(PluginSettings.HELP_HEADER);
|
||||
}
|
||||
|
||||
private static void printDetailedDescription(CommandDescription command, List<String> lines) {
|
||||
lines.add(ChatColor.GOLD + "Short description: " + ChatColor.WHITE + command.getDescription());
|
||||
lines.add(ChatColor.GOLD + "Detailed description:");
|
||||
@ -110,7 +132,6 @@ public class HelpProvider {
|
||||
}
|
||||
|
||||
private static void printAlternatives(CommandDescription command, List<String> correctLabels, List<String> lines) {
|
||||
// TODO ljacqu 20151219: Need to show alternatives for base labels too? E.g. /r for /register
|
||||
if (command.getLabels().size() <= 1 || correctLabels.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
@ -130,25 +151,22 @@ public class HelpProvider {
|
||||
|
||||
private static void printPermissions(CommandDescription command, CommandSender sender,
|
||||
PermissionsManager permissionsManager, List<String> lines) {
|
||||
CommandPermissions permissions = command.getCommandPermissions();
|
||||
// TODO ljacqu 20151224: Isn't it possible to have a default permission but no permission nodes?
|
||||
if (permissions == null || CollectionUtils.isEmpty(permissions.getPermissionNodes())) {
|
||||
PermissionNode permission = command.getPermission();
|
||||
if (permission == null) {
|
||||
return;
|
||||
}
|
||||
lines.add(ChatColor.GOLD + "Permissions:");
|
||||
|
||||
for (PermissionNode node : permissions.getPermissionNodes()) {
|
||||
boolean hasPermission = permissionsManager.hasPermission(sender, node);
|
||||
final String nodePermsString = "" + ChatColor.GRAY + ChatColor.ITALIC
|
||||
+ (hasPermission ? " (You have permission)" : " (No permission)");
|
||||
lines.add(" " + ChatColor.YELLOW + ChatColor.ITALIC + node.getNode() + nodePermsString);
|
||||
}
|
||||
boolean hasPermission = permissionsManager.hasPermission(sender, permission);
|
||||
final String nodePermsString = "" + ChatColor.GRAY + ChatColor.ITALIC
|
||||
+ (hasPermission ? " (You have permission)" : " (No permission)");
|
||||
lines.add(" " + ChatColor.YELLOW + ChatColor.ITALIC + permission.getNode() + nodePermsString);
|
||||
|
||||
// Addendum to the line to specify whether the sender has permission or not when default is OP_ONLY
|
||||
final DefaultPermission defaultPermission = permissions.getDefaultPermission();
|
||||
final DefaultPermission defaultPermission = permission.getDefaultPermission();
|
||||
String addendum = "";
|
||||
if (DefaultPermission.OP_ONLY.equals(defaultPermission)) {
|
||||
addendum = PermissionsManager.evaluateDefaultPermission(defaultPermission, sender)
|
||||
addendum = defaultPermission.evaluate(sender)
|
||||
? " (You have permission)"
|
||||
: " (No permission)";
|
||||
}
|
||||
@ -156,7 +174,7 @@ public class HelpProvider {
|
||||
+ defaultPermission.getTitle() + addendum);
|
||||
|
||||
// Evaluate if the sender has permission to the command
|
||||
if (permissionsManager.hasPermission(sender, command)) {
|
||||
if (permissionsManager.hasPermission(sender, command.getPermission())) {
|
||||
lines.add(ChatColor.GOLD + " Result: " + ChatColor.GREEN + ChatColor.ITALIC + "You have permission");
|
||||
} else {
|
||||
lines.add(ChatColor.GOLD + " Result: " + ChatColor.DARK_RED + ChatColor.ITALIC + "No permission");
|
||||
|
@ -1,7 +1,16 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Common supertype for AuthMe converters.
|
||||
* Interface for AuthMe converters.
|
||||
*/
|
||||
public interface Converter extends Runnable {
|
||||
public interface Converter {
|
||||
|
||||
/**
|
||||
* Execute the conversion.
|
||||
*
|
||||
* @param sender the sender who initialized the conversion
|
||||
*/
|
||||
void execute(CommandSender sender);
|
||||
}
|
||||
|
@ -1,47 +1,46 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.ConverterSettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Xephi59
|
||||
* Converter for CrazyLogin to AuthMe.
|
||||
*/
|
||||
public class CrazyLoginConverter implements Converter {
|
||||
|
||||
private final DataSource database;
|
||||
private final CommandSender sender;
|
||||
private final NewSetting settings;
|
||||
private final File dataFolder;
|
||||
|
||||
/**
|
||||
* Constructor for CrazyLoginConverter.
|
||||
*
|
||||
* @param instance AuthMe
|
||||
* @param sender CommandSender
|
||||
*/
|
||||
public CrazyLoginConverter(AuthMe instance, CommandSender sender) {
|
||||
this.database = instance.getDataSource();
|
||||
this.sender = sender;
|
||||
@Inject
|
||||
CrazyLoginConverter(@DataFolder File dataFolder, DataSource dataSource, NewSetting settings) {
|
||||
this.dataFolder = dataFolder;
|
||||
this.database = dataSource;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@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 data, please put " + fileName + " in AuthMe folder!");
|
||||
return;
|
||||
}
|
||||
String line;
|
||||
BufferedReader users = new BufferedReader(new FileReader(source));
|
||||
public void execute(CommandSender sender) {
|
||||
String fileName = settings.getProperty(ConverterSettings.CRAZYLOGIN_FILE_NAME);
|
||||
File source = new File(dataFolder, fileName);
|
||||
if (!source.exists()) {
|
||||
sender.sendMessage("CrazyLogin file not found, please put " + fileName + " in AuthMe folder!");
|
||||
return;
|
||||
}
|
||||
|
||||
String line;
|
||||
try (BufferedReader users = new BufferedReader(new FileReader(source))) {
|
||||
while ((line = users.readLine()) != null) {
|
||||
if (line.contains("|")) {
|
||||
String[] args = line.split("\\|");
|
||||
@ -49,22 +48,21 @@ public class CrazyLoginConverter implements Converter {
|
||||
continue;
|
||||
}
|
||||
String playerName = args[0];
|
||||
String psw = args[1];
|
||||
if (psw != null) {
|
||||
String password = args[1];
|
||||
if (password != null) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(playerName.toLowerCase())
|
||||
.realName(playerName)
|
||||
.password(psw, null)
|
||||
.password(password, null)
|
||||
.build();
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
users.close();
|
||||
ConsoleLogger.info("CrazyLogin database has been imported correctly");
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
ConsoleLogger.showError("Can't open the crazylogin database file! Does it exist?");
|
||||
ConsoleLogger.logException("Encountered", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import java.util.List;
|
||||
/**
|
||||
* Mandatory migration from the deprecated flat file datasource to SQLite.
|
||||
*/
|
||||
public class ForceFlatToSqlite implements Converter {
|
||||
public class ForceFlatToSqlite {
|
||||
|
||||
private final DataSource source;
|
||||
private final DataSource destination;
|
||||
@ -31,7 +31,6 @@ public class ForceFlatToSqlite implements Converter {
|
||||
/**
|
||||
* Perform the conversion.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
List<String> skippedPlayers = new ArrayList<>();
|
||||
for (PlayerAuth auth : source.getAllAuths()) {
|
||||
|
@ -1,14 +1,16 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.ConverterSettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
@ -21,24 +23,26 @@ import java.util.Map.Entry;
|
||||
*/
|
||||
public class RakamakConverter implements Converter {
|
||||
|
||||
private final AuthMe instance;
|
||||
private final DataSource database;
|
||||
private final CommandSender sender;
|
||||
private final NewSetting settings;
|
||||
private final File pluginFolder;
|
||||
private final PasswordSecurity passwordSecurity;
|
||||
|
||||
public RakamakConverter(AuthMe instance, CommandSender sender) {
|
||||
this.instance = instance;
|
||||
this.database = instance.getDataSource();
|
||||
this.sender = sender;
|
||||
pluginFolder = instance.getDataFolder();
|
||||
@Inject
|
||||
RakamakConverter(@DataFolder File dataFolder, DataSource dataSource, NewSetting settings,
|
||||
PasswordSecurity passwordSecurity) {
|
||||
this.database = dataSource;
|
||||
this.settings = settings;
|
||||
this.pluginFolder = dataFolder;
|
||||
this.passwordSecurity = passwordSecurity;
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO ljacqu 20151229: Restructure this into smaller portions
|
||||
public void run() {
|
||||
boolean useIP = Settings.rakamakUseIp;
|
||||
String fileName = Settings.rakamakUsers;
|
||||
String ipFileName = Settings.rakamakUsersIp;
|
||||
public void execute(CommandSender sender) {
|
||||
boolean useIP = settings.getProperty(ConverterSettings.RAKAMAK_USE_IP);
|
||||
String fileName = settings.getProperty(ConverterSettings.RAKAMAK_FILE_NAME);
|
||||
String ipFileName = settings.getProperty(ConverterSettings.RAKAMAK_IP_FILE_NAME);
|
||||
File source = new File(pluginFolder, fileName);
|
||||
File ipfiles = new File(pluginFolder, ipFileName);
|
||||
HashMap<String, String> playerIP = new HashMap<>();
|
||||
@ -60,7 +64,6 @@ public class RakamakConverter implements Converter {
|
||||
ipFile.close();
|
||||
|
||||
users = new BufferedReader(new FileReader(source));
|
||||
PasswordSecurity passwordSecurity = instance.getPasswordSecurity();
|
||||
while ((line = users.readLine()) != null) {
|
||||
if (line.contains("=")) {
|
||||
String[] arguments = line.split("=");
|
||||
|
@ -5,9 +5,11 @@ 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.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
@ -19,13 +21,14 @@ public class RoyalAuthConverter implements Converter {
|
||||
private final AuthMe plugin;
|
||||
private final DataSource dataSource;
|
||||
|
||||
public RoyalAuthConverter(AuthMe plugin) {
|
||||
@Inject
|
||||
RoyalAuthConverter(AuthMe plugin, DataSource dataSource) {
|
||||
this.plugin = plugin;
|
||||
this.dataSource = plugin.getDataSource();
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void execute(CommandSender sender) {
|
||||
for (OfflinePlayer player : plugin.getServer().getOfflinePlayers()) {
|
||||
try {
|
||||
String name = player.getName().toLowerCase();
|
||||
|
@ -1,40 +1,43 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class SqliteToSql implements Converter {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final CommandSender sender;
|
||||
private final NewSetting settings;
|
||||
private final DataSource dataSource;
|
||||
private final Messages messages;
|
||||
|
||||
public SqliteToSql(AuthMe plugin, CommandSender sender, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
this.sender = sender;
|
||||
@Inject
|
||||
SqliteToSql(NewSetting settings, DataSource dataSource, Messages messages) {
|
||||
this.settings = settings;
|
||||
this.dataSource = dataSource;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (plugin.getDataSource().getType() != DataSourceType.MYSQL) {
|
||||
public void execute(CommandSender sender) {
|
||||
if (dataSource.getType() != DataSourceType.MYSQL) {
|
||||
sender.sendMessage("Please configure your mySQL connection and re-run this command");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SQLite data = new SQLite(settings);
|
||||
for (PlayerAuth auth : data.getAllAuths()) {
|
||||
plugin.getDataSource().saveAuth(auth);
|
||||
dataSource.saveAuth(auth);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
plugin.getMessages().send(sender, MessageKey.ERROR);
|
||||
messages.send(sender, MessageKey.ERROR);
|
||||
ConsoleLogger.logException("Problem during SQLite to SQL conversion:", e);
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,19 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class vAuthConverter implements Converter {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final CommandSender sender;
|
||||
|
||||
public vAuthConverter(AuthMe plugin, CommandSender sender) {
|
||||
@Inject
|
||||
vAuthConverter(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void execute(CommandSender sender) {
|
||||
try {
|
||||
new vAuthFileReader(plugin).convert();
|
||||
} catch (Exception e) {
|
||||
|
@ -3,18 +3,19 @@ package fr.xephi.authme.converter;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class xAuthConverter implements Converter {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final CommandSender sender;
|
||||
|
||||
public xAuthConverter(AuthMe plugin, CommandSender sender) {
|
||||
@Inject
|
||||
xAuthConverter(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void execute(CommandSender sender) {
|
||||
try {
|
||||
Class.forName("de.luricos.bukkit.xAuth.xAuth");
|
||||
xAuthToFlat converter = new xAuthToFlat(plugin, sender);
|
||||
|
@ -8,6 +8,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
@ -15,12 +16,11 @@ import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class CacheDataSource implements DataSource {
|
||||
|
||||
private final DataSource source;
|
||||
@ -41,7 +41,8 @@ public class CacheDataSource implements DataSource {
|
||||
.build())
|
||||
);
|
||||
cachedAuths = CacheBuilder.newBuilder()
|
||||
.refreshAfterWrite(8, TimeUnit.MINUTES)
|
||||
.refreshAfterWrite(5, TimeUnit.MINUTES)
|
||||
.expireAfterAccess(15, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<String, Optional<PlayerAuth>>() {
|
||||
@Override
|
||||
public Optional<PlayerAuth> load(String key) {
|
||||
@ -53,6 +54,7 @@ public class CacheDataSource implements DataSource {
|
||||
return executorService.submit(new Callable<Optional<PlayerAuth>>() {
|
||||
@Override
|
||||
public Optional<PlayerAuth> call() {
|
||||
ConsoleLogger.debug("REFRESH " + key);
|
||||
return load(key);
|
||||
}
|
||||
});
|
||||
@ -70,7 +72,7 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
public boolean isAuthAvailable(String user) {
|
||||
return getAuth(user) != null;
|
||||
}
|
||||
|
||||
@ -85,13 +87,13 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
public PlayerAuth getAuth(String user) {
|
||||
user = user.toLowerCase();
|
||||
return cachedAuths.getUnchecked(user).orNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
public boolean saveAuth(PlayerAuth auth) {
|
||||
boolean result = source.saveAuth(auth);
|
||||
if (result) {
|
||||
cachedAuths.refresh(auth.getNickname());
|
||||
@ -100,7 +102,7 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
public boolean updatePassword(PlayerAuth auth) {
|
||||
boolean result = source.updatePassword(auth);
|
||||
if (result) {
|
||||
cachedAuths.refresh(auth.getNickname());
|
||||
@ -137,16 +139,17 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
List<String> cleared = source.autoPurgeDatabase(until);
|
||||
public Set<String> autoPurgeDatabase(long until) {
|
||||
Set<String> cleared = source.autoPurgeDatabase(until);
|
||||
for (String name : cleared) {
|
||||
cachedAuths.invalidate(name);
|
||||
}
|
||||
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String name) {
|
||||
public boolean removeAuth(String name) {
|
||||
name = name.toLowerCase();
|
||||
boolean result = source.removeAuth(name);
|
||||
if (result) {
|
||||
@ -156,7 +159,7 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
public void close() {
|
||||
source.close();
|
||||
cachedAuths.invalidateAll();
|
||||
executorService.shutdown();
|
||||
@ -168,7 +171,7 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateEmail(final PlayerAuth auth) {
|
||||
public boolean updateEmail(final PlayerAuth auth) {
|
||||
boolean result = source.updateEmail(auth);
|
||||
if (result) {
|
||||
cachedAuths.refresh(auth.getNickname());
|
||||
@ -177,17 +180,17 @@ public class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByIp(final String ip) {
|
||||
public List<String> getAllAuthsByIp(final String ip) {
|
||||
return source.getAllAuthsByIp(ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int countAuthsByEmail(final String email) {
|
||||
public int countAuthsByEmail(final String email) {
|
||||
return source.countAuthsByEmail(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void purgeBanned(final List<String> banned) {
|
||||
public void purgeBanned(final Set<String> banned) {
|
||||
source.purgeBanned(banned);
|
||||
cachedAuths.invalidateAll(banned);
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface for manipulating {@link PlayerAuth} objects from a data source.
|
||||
*/
|
||||
public interface DataSource {
|
||||
public interface DataSource extends Reloadable {
|
||||
|
||||
/**
|
||||
* Return whether there is a record for the given username.
|
||||
@ -74,7 +76,7 @@ public interface DataSource {
|
||||
* @param until The minimum last login
|
||||
* @return The account names that have been removed
|
||||
*/
|
||||
List<String> autoPurgeDatabase(long until);
|
||||
Set<String> autoPurgeDatabase(long until);
|
||||
|
||||
/**
|
||||
* Remove a user record from the database.
|
||||
@ -126,7 +128,7 @@ public interface DataSource {
|
||||
*
|
||||
* @param banned the list of players to delete
|
||||
*/
|
||||
void purgeBanned(List<String> banned);
|
||||
void purgeBanned(Set<String> banned);
|
||||
|
||||
/**
|
||||
* Return the data source type.
|
||||
@ -204,6 +206,7 @@ public interface DataSource {
|
||||
/**
|
||||
* Reload the data source.
|
||||
*/
|
||||
@Override
|
||||
void reload();
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Deprecated flat file datasource. The only method guaranteed to work is {@link FlatFile#getAllAuths()}
|
||||
@ -227,11 +229,11 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
public Set<String> autoPurgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
List<String> cleared = new ArrayList<>();
|
||||
Set<String> cleared = new HashSet<>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
@ -256,6 +258,7 @@ public class FlatFile implements DataSource {
|
||||
silentClose(br);
|
||||
silentClose(bw);
|
||||
}
|
||||
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@ -414,7 +417,7 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
public void purgeBanned(Set<String> banned) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
|
@ -3,6 +3,7 @@ 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.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
@ -24,10 +25,10 @@ import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class MySQL implements DataSource {
|
||||
|
||||
private final String host;
|
||||
@ -105,34 +106,36 @@ public class MySQL implements DataSource {
|
||||
ds = hikariDataSource;
|
||||
}
|
||||
|
||||
private synchronized void setConnectionArguments() throws RuntimeException {
|
||||
private void setConnectionArguments() throws RuntimeException {
|
||||
ds = new HikariDataSource();
|
||||
ds.setPoolName("AuthMeMYSQLPool");
|
||||
ds.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
ds.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database);
|
||||
ds.addDataSourceProperty("rewriteBatchedStatements", "true");
|
||||
ds.addDataSourceProperty("jdbcCompliantTruncation", "false");
|
||||
ds.addDataSourceProperty("cachePrepStmts", "true");
|
||||
ds.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||
ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||
|
||||
//set utf-8 as default encoding
|
||||
// Database URL
|
||||
ds.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database);
|
||||
|
||||
// Auth
|
||||
ds.setUsername(this.username);
|
||||
ds.setPassword(this.password);
|
||||
|
||||
// Encoding
|
||||
ds.addDataSourceProperty("characterEncoding", "utf8");
|
||||
ds.addDataSourceProperty("encoding","UTF-8");
|
||||
ds.addDataSourceProperty("useUnicode", "true");
|
||||
|
||||
ds.setUsername(this.username);
|
||||
ds.setPassword(this.password);
|
||||
ds.setInitializationFailFast(true); // Don't start the plugin if the database is unavailable
|
||||
ds.setMaxLifetime(180000); // 3 Min
|
||||
ds.setIdleTimeout(60000); // 1 Min
|
||||
ds.setMinimumIdle(2);
|
||||
ds.setMaximumPoolSize((Runtime.getRuntime().availableProcessors() * 2) + 1);
|
||||
// Random stuff
|
||||
ds.addDataSourceProperty("rewriteBatchedStatements", "true");
|
||||
ds.addDataSourceProperty("jdbcCompliantTruncation", "false");
|
||||
|
||||
// Caching
|
||||
ds.addDataSourceProperty("cachePrepStmts", "true");
|
||||
ds.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||
ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||
|
||||
ConsoleLogger.info("Connection arguments loaded, Hikari ConnectionPool ready!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reload() throws RuntimeException {
|
||||
public void reload() throws RuntimeException {
|
||||
if (ds != null) {
|
||||
ds.close();
|
||||
}
|
||||
@ -140,11 +143,11 @@ public class MySQL implements DataSource {
|
||||
ConsoleLogger.info("Hikari ConnectionPool arguments reloaded!");
|
||||
}
|
||||
|
||||
private synchronized Connection getConnection() throws SQLException {
|
||||
private Connection getConnection() throws SQLException {
|
||||
return ds.getConnection();
|
||||
}
|
||||
|
||||
private synchronized void setupConnection() throws SQLException {
|
||||
private void setupConnection() throws SQLException {
|
||||
try (Connection con = getConnection()) {
|
||||
Statement st = con.createStatement();
|
||||
DatabaseMetaData md = con.getMetaData();
|
||||
@ -257,7 +260,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
public boolean isAuthAvailable(String user) {
|
||||
String sql = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
ResultSet rs = null;
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
@ -293,7 +296,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
public PlayerAuth getAuth(String user) {
|
||||
String sql = "SELECT * FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
PlayerAuth auth;
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
@ -327,7 +330,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
public boolean saveAuth(PlayerAuth auth) {
|
||||
try (Connection con = getConnection()) {
|
||||
PreparedStatement pst;
|
||||
PreparedStatement pst2;
|
||||
@ -424,6 +427,7 @@ public class MySQL implements DataSource {
|
||||
rs.close();
|
||||
pst.close();
|
||||
} else if (hashAlgorithm == HashAlgorithm.WORDPRESS) {
|
||||
// NOTE: Eclipse says pst should be closed HERE, but it's a bug, we already close it above. -sgdc3
|
||||
pst = con.prepareStatement("SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
rs = pst.executeQuery();
|
||||
@ -500,6 +504,7 @@ public class MySQL implements DataSource {
|
||||
rs.close();
|
||||
pst.close();
|
||||
} else if (hashAlgorithm == HashAlgorithm.XFBCRYPT) {
|
||||
// NOTE: Eclipse says pst should be closed HERE, but it's a bug, we already close it above. -sgdc3
|
||||
pst = con.prepareStatement("SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
rs = pst.executeQuery();
|
||||
@ -528,7 +533,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
public boolean updatePassword(PlayerAuth auth) {
|
||||
return updatePassword(auth.getNickname(), auth.getPassword());
|
||||
}
|
||||
|
||||
@ -591,7 +596,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateSession(PlayerAuth auth) {
|
||||
public boolean updateSession(PlayerAuth auth) {
|
||||
String sql = "UPDATE " + tableName + " SET "
|
||||
+ col.IP + "=?, " + col.LAST_LOGIN + "=?, " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
@ -608,8 +613,8 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> autoPurgeDatabase(long until) {
|
||||
List<String> list = new ArrayList<>();
|
||||
public Set<String> autoPurgeDatabase(long until) {
|
||||
Set<String> list = new HashSet<>();
|
||||
String select = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
|
||||
String delete = "DELETE FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
|
||||
try (Connection con = getConnection();
|
||||
@ -626,11 +631,12 @@ public class MySQL implements DataSource {
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
public boolean removeAuth(String user) {
|
||||
user = user.toLowerCase();
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
PreparedStatement xfSelect = null;
|
||||
@ -663,7 +669,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateQuitLoc(PlayerAuth auth) {
|
||||
public boolean updateQuitLoc(PlayerAuth auth) {
|
||||
String sql = "UPDATE " + tableName
|
||||
+ " SET " + col.LASTLOC_X + " =?, " + col.LASTLOC_Y + "=?, " + col.LASTLOC_Z + "=?, " + col.LASTLOC_WORLD + "=?"
|
||||
+ " WHERE " + col.NAME + "=?;";
|
||||
@ -682,7 +688,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateEmail(PlayerAuth auth) {
|
||||
public boolean updateEmail(PlayerAuth auth) {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.EMAIL + " =? WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, auth.getEmail());
|
||||
@ -696,14 +702,14 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
public void close() {
|
||||
if (ds != null && !ds.isClosed()) {
|
||||
ds.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByIp(String ip) {
|
||||
public List<String> getAllAuthsByIp(String ip) {
|
||||
List<String> result = new ArrayList<>();
|
||||
String sql = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.IP + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
@ -720,7 +726,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int countAuthsByEmail(String email) {
|
||||
public int countAuthsByEmail(String email) {
|
||||
String sql = "SELECT COUNT(1) FROM " + tableName + " WHERE UPPER(" + col.EMAIL + ") = UPPER(?)";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, email);
|
||||
@ -736,7 +742,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void purgeBanned(List<String> banned) {
|
||||
public void purgeBanned(Set<String> banned) {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
for (String name : banned) {
|
||||
|
@ -1,14 +1,5 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
@ -16,7 +7,19 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
/**
|
||||
*/
|
||||
@ -61,14 +64,13 @@ public class SQLite implements DataSource {
|
||||
ConsoleLogger.logException("Error while executing SQL statement:", e);
|
||||
}
|
||||
|
||||
private synchronized void connect() throws ClassNotFoundException, SQLException {
|
||||
private void connect() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
ConsoleLogger.info("SQLite driver loaded");
|
||||
this.con = DriverManager.getConnection("jdbc:sqlite:plugins/AuthMe/" + database + ".db");
|
||||
|
||||
}
|
||||
|
||||
private synchronized void setup() throws SQLException {
|
||||
private void setup() throws SQLException {
|
||||
Statement st = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
@ -131,11 +133,17 @@ public class SQLite implements DataSource {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
// TODO 20160309: Implement reloading
|
||||
close(con);
|
||||
try {
|
||||
this.connect();
|
||||
this.setup();
|
||||
} catch (ClassNotFoundException | SQLException ex) {
|
||||
ConsoleLogger.logException("Error during SQLite initialization:", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
public boolean isAuthAvailable(String user) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
@ -173,7 +181,7 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
public PlayerAuth getAuth(String user) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
@ -193,7 +201,7 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
public boolean saveAuth(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
HashedPassword password = auth.getPassword();
|
||||
@ -234,7 +242,7 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
public boolean updatePassword(PlayerAuth auth) {
|
||||
return updatePassword(auth.getNickname(), auth.getPassword());
|
||||
}
|
||||
|
||||
@ -285,8 +293,8 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
List<String> list = new ArrayList<>();
|
||||
public Set<String> autoPurgeDatabase(long until) {
|
||||
Set<String> list = new HashSet<>();
|
||||
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);
|
||||
@ -302,11 +310,12 @@ public class SQLite implements DataSource {
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
public boolean removeAuth(String user) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;");
|
||||
@ -356,7 +365,7 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
public void close() {
|
||||
try {
|
||||
if (con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
@ -376,6 +385,16 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
private void close(Connection con) {
|
||||
if (con != null) {
|
||||
try {
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
@ -425,7 +444,7 @@ public class SQLite implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
public void purgeBanned(Set<String> banned) {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
for (String name : banned) {
|
||||
|
@ -19,25 +19,13 @@ public abstract class AbstractTeleportEvent extends CustomEvent implements Cance
|
||||
*
|
||||
* @param isAsync Whether to fire the event asynchronously or not
|
||||
* @param player The player
|
||||
* @param from The location the player is being teleported away from
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public AbstractTeleportEvent(boolean isAsync, Player player, Location from, Location to) {
|
||||
super(isAsync);
|
||||
this.player = player;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, using the player's current location as "from" location.
|
||||
*
|
||||
* @param isAsync Whether to fire the event asynchronously or not
|
||||
* @param player The player
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public AbstractTeleportEvent(boolean isAsync, Player player, Location to) {
|
||||
this(isAsync, player, player.getLocation(), to);
|
||||
super(isAsync);
|
||||
this.player = player;
|
||||
this.from = player.getLocation();
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,8 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is called when a player uses the /login command with correct credentials.
|
||||
* This event is called when a player uses the login command,
|
||||
* it's fired even when a user does a /login with invalid password.
|
||||
* {@link #setCanLogin(boolean) event.setCanLogin(false)} prevents the player from logging in.
|
||||
*/
|
||||
public class AuthMeAsyncPreLoginEvent extends CustomEvent {
|
||||
|
@ -17,11 +17,10 @@ public class FirstSpawnTeleportEvent extends AbstractTeleportEvent {
|
||||
* Constructor.
|
||||
*
|
||||
* @param player The player
|
||||
* @param from The location the player is being teleported away from
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public FirstSpawnTeleportEvent(Player player, Location from, Location to) {
|
||||
super(true, player, from, to);
|
||||
public FirstSpawnTeleportEvent(Player player, Location to) {
|
||||
super(false, player, to);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,17 @@ public class LoginEvent extends CustomEvent {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures compatibility with plugins like GuiRules.
|
||||
*
|
||||
* @return true
|
||||
* @deprecated this will always return true because this event is only called if it was successful
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isLogin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
|
@ -17,12 +17,11 @@ public class SpawnTeleportEvent extends AbstractTeleportEvent {
|
||||
* Constructor.
|
||||
*
|
||||
* @param player The player
|
||||
* @param from The location the player is being teleported away from
|
||||
* @param to The teleport destination
|
||||
* @param isAuthenticated Whether or not the player is logged in
|
||||
*/
|
||||
public SpawnTeleportEvent(Player player, Location from, Location to, boolean isAuthenticated) {
|
||||
super(false, player, from, to);
|
||||
public SpawnTeleportEvent(Player player, Location to, boolean isAuthenticated) {
|
||||
super(false, player, to);
|
||||
this.isAuthenticated = isAuthenticated;
|
||||
}
|
||||
|
||||
|
@ -2,29 +2,37 @@ package fr.xephi.authme.hooks;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
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.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
|
||||
/**
|
||||
*/
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
||||
public class BungeeCordMessage implements PluginMessageListener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private AuthMe plugin;
|
||||
|
||||
BungeeCordMessage() { }
|
||||
|
||||
/**
|
||||
* Constructor for BungeeCordMessage.
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
*/
|
||||
public BungeeCordMessage(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
|
||||
@ -38,8 +46,7 @@ public class BungeeCordMessage implements PluginMessageListener {
|
||||
final String[] args = str.split(";");
|
||||
final String act = args[0];
|
||||
final String name = args[1];
|
||||
final DataSource dataSource = plugin.getDataSource();
|
||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth auth = dataSource.getAuth(name);
|
||||
@ -47,23 +54,33 @@ public class BungeeCordMessage implements PluginMessageListener {
|
||||
return;
|
||||
}
|
||||
if ("login".equals(act)) {
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
playerCache.updatePlayer(auth);
|
||||
dataSource.setLogged(name);
|
||||
ConsoleLogger.info("Player " + auth.getNickname()
|
||||
+ " has logged in from one of your server!");
|
||||
//START 03062016 sgdc3: should fix #731 but we need to recode this mess
|
||||
if (plugin.sessions.containsKey(name)) {
|
||||
plugin.sessions.get(name).cancel();
|
||||
plugin.sessions.remove(name);
|
||||
}
|
||||
//END
|
||||
|
||||
if (!plugin.getSettings().getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info("Player " + auth.getNickname() + " has logged in from one of your server!");
|
||||
}
|
||||
} else if ("logout".equals(act)) {
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
playerCache.removePlayer(name);
|
||||
dataSource.setUnlogged(name);
|
||||
ConsoleLogger.info("Player " + auth.getNickname()
|
||||
+ " has logged out from one of your server!");
|
||||
if (!plugin.getSettings().getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
ConsoleLogger.info("Player " + auth.getNickname() + " has logged out from one of your server!");
|
||||
}
|
||||
} else if ("register".equals(act)) {
|
||||
ConsoleLogger.info("Player " + auth.getNickname()
|
||||
+ " has registered out from one of your server!");
|
||||
if (!plugin.getSettings().getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
|
||||
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 salt = args.length >= 4 ? args[3] : null;
|
||||
auth.setPassword(new HashedPassword(password, salt));
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
playerCache.updatePlayer(auth);
|
||||
dataSource.updatePassword(auth);
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
package fr.xephi.authme.hooks;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import net.minelink.ctplus.CombatTagPlus;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
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 javax.inject.Inject;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Hooks into third-party plugins and allows to perform actions on them.
|
||||
@ -30,6 +29,7 @@ public class PluginHooks {
|
||||
*
|
||||
* @param pluginManager The server's plugin manager
|
||||
*/
|
||||
@Inject
|
||||
public PluginHooks(PluginManager pluginManager) {
|
||||
this.pluginManager = pluginManager;
|
||||
tryHookToCombatPlus();
|
||||
@ -77,13 +77,23 @@ public class PluginHooks {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the player is an NPC.
|
||||
*
|
||||
* @param player The player to process
|
||||
* @return True if player is NPC, false otherwise
|
||||
*/
|
||||
public boolean isNpc(Player player) {
|
||||
return player.hasMetadata("NPC") || isNpcInCombatTagPlus(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
private boolean isNpcInCombatTagPlus(Player player) {
|
||||
return combatTagPlus != null && combatTagPlus.getNpcPlayerHelper().isNpc(player);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,324 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Provider;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Dependency injector of AuthMe: initializes and injects services and tasks.
|
||||
* <p>
|
||||
* Only constructor and field injection are supported, indicated with the JSR330
|
||||
* {@link javax.inject.Inject @Inject} annotation.
|
||||
* <p>
|
||||
* {@link PostConstruct @PostConstruct} methods are recognized and invoked upon
|
||||
* instantiation. Note that the parent classes are <i>not</i> scanned for such methods.
|
||||
*/
|
||||
public class AuthMeServiceInitializer {
|
||||
|
||||
private final Set<String> ALLOWED_PACKAGES;
|
||||
private final Map<Class<?>, Object> objects;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param allowedPackages list of allowed packages. Only classes whose package
|
||||
* starts with any of the given entries will be instantiated
|
||||
*/
|
||||
public AuthMeServiceInitializer(String... allowedPackages) {
|
||||
ALLOWED_PACKAGES = ImmutableSet.copyOf(allowedPackages);
|
||||
objects = new HashMap<>();
|
||||
objects.put(getClass(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves or instantiates an object of the given type.
|
||||
*
|
||||
* @param clazz the class to retrieve the value for
|
||||
* @param <T> the class' type
|
||||
* @return object of the class' type
|
||||
*/
|
||||
public <T> T get(Class<T> clazz) {
|
||||
return get(clazz, new HashSet<Class<?>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an object with a custom class (supertype). Use this for example to specify a
|
||||
* concrete implementation of an interface or an abstract class.
|
||||
*
|
||||
* @param clazz the class to register the object for
|
||||
* @param object the object
|
||||
* @param <T> the class' type
|
||||
*/
|
||||
public <T> void register(Class<? super T> clazz, T object) {
|
||||
if (objects.containsKey(clazz)) {
|
||||
throw new IllegalStateException("There is already an object present for " + clazz);
|
||||
}
|
||||
Preconditions.checkNotNull(object);
|
||||
objects.put(clazz, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate an annotation with a value.
|
||||
*
|
||||
* @param annotation the annotation
|
||||
* @param value the value
|
||||
*/
|
||||
public void provide(Class<? extends Annotation> annotation, Object value) {
|
||||
if (objects.containsKey(annotation)) {
|
||||
throw new IllegalStateException("Annotation @" + annotation.getClass().getSimpleName()
|
||||
+ " already registered");
|
||||
}
|
||||
Preconditions.checkNotNull(value);
|
||||
objects.put(annotation, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the given class and does <i>not</i> keep track of it afterwards,
|
||||
* unlike {@link #get(Class)} (singleton scope).
|
||||
*
|
||||
* @param clazz the class to instantiate
|
||||
* @param <T> the class' type
|
||||
* @return new instance of class T
|
||||
*/
|
||||
public <T> T newInstance(Class<T> clazz) {
|
||||
return instantiate(clazz, new HashSet<Class<?>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the given class if available. This simply returns the instance if present and
|
||||
* otherwise {@code null}. Calling this method will not instantiate anything.
|
||||
*
|
||||
* @param clazz the class to retrieve the instance for
|
||||
* @param <T> the class' type
|
||||
* @return instance or null if none available
|
||||
*/
|
||||
public <T> T getIfAvailable(Class<T> clazz) {
|
||||
if (Annotation.class.isAssignableFrom(clazz)) {
|
||||
throw new UnsupportedOperationException("Annotations may not be retrieved in this way!");
|
||||
}
|
||||
return clazz.cast(objects.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the given class by retrieving it or by instantiating it if not yet present.
|
||||
*
|
||||
* @param clazz the class to retrieve a value for
|
||||
* @param traversedClasses the list of traversed classes
|
||||
* @param <T> the class' type
|
||||
* @return instance or associated value (for annotations)
|
||||
*/
|
||||
private <T> T get(Class<T> clazz, Set<Class<?>> traversedClasses) {
|
||||
if (Annotation.class.isAssignableFrom(clazz)) {
|
||||
throw new UnsupportedOperationException("Cannot retrieve annotated elements in this way!");
|
||||
} else if (objects.containsKey(clazz)) {
|
||||
return clazz.cast(objects.get(clazz));
|
||||
}
|
||||
|
||||
// First time we come across clazz, need to instantiate it. Validate that we can do so
|
||||
validatePackage(clazz);
|
||||
validateInstantiable(clazz);
|
||||
|
||||
// Add the clazz to the list of traversed classes in a new Set, so each path we take has its own Set.
|
||||
traversedClasses = new HashSet<>(traversedClasses);
|
||||
traversedClasses.add(clazz);
|
||||
T object = instantiate(clazz, traversedClasses);
|
||||
storeObject(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a reload on all applicable instances which are registered.
|
||||
* Requires that the {@link NewSetting settings} instance be registered.
|
||||
* <p>
|
||||
* Note that the order in which these classes are reloaded is not guaranteed.
|
||||
*/
|
||||
public void performReloadOnServices() {
|
||||
NewSetting settings = (NewSetting) objects.get(NewSetting.class);
|
||||
if (settings == null) {
|
||||
throw new IllegalStateException("Settings instance is null");
|
||||
}
|
||||
for (Object object : objects.values()) {
|
||||
if (object instanceof Reloadable) {
|
||||
((Reloadable) object).reload();
|
||||
} else if (object instanceof SettingsDependent) {
|
||||
((SettingsDependent) object).loadSettings(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates the given class by locating its @Inject elements and retrieving
|
||||
* or instantiating the required instances.
|
||||
*
|
||||
* @param clazz the class to instantiate
|
||||
* @param traversedClasses collection of classes already traversed
|
||||
* @param <T> the class' type
|
||||
* @return the instantiated object
|
||||
*/
|
||||
private <T> T instantiate(Class<T> clazz, Set<Class<?>> traversedClasses) {
|
||||
Injection<T> injection = firstNotNull(
|
||||
ConstructorInjection.provide(clazz), FieldInjection.provide(clazz), InstantiationFallback.provide(clazz));
|
||||
if (injection == null) {
|
||||
throw new IllegalStateException("Did not find injection method for " + clazz + ". Make sure you have "
|
||||
+ "a constructor with @Inject or fields with @Inject. Fields with @Inject require "
|
||||
+ "the default constructor");
|
||||
}
|
||||
|
||||
validateInjectionHasNoCircularDependencies(injection.getDependencies(), traversedClasses);
|
||||
Object[] dependencies = resolveDependencies(injection, traversedClasses);
|
||||
T object = injection.instantiateWith(dependencies);
|
||||
executePostConstructMethod(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the dependencies for the given class instantiation, i.e. returns a collection that satisfy
|
||||
* the class' dependencies by retrieving elements or instantiating them where necessary.
|
||||
*
|
||||
* @param injection the injection parameters
|
||||
* @param traversedClasses collection of traversed classes
|
||||
* @return array with the parameters to use in the constructor
|
||||
*/
|
||||
private Object[] resolveDependencies(Injection<?> injection, Set<Class<?>> traversedClasses) {
|
||||
Class<?>[] dependencies = injection.getDependencies();
|
||||
Class<?>[] annotations = injection.getDependencyAnnotations();
|
||||
Object[] values = new Object[dependencies.length];
|
||||
for (int i = 0; i < dependencies.length; ++i) {
|
||||
if (annotations[i] == null) {
|
||||
values[i] = get(dependencies[i], traversedClasses);
|
||||
} else {
|
||||
Object value = objects.get(annotations[i]);
|
||||
if (value == null) {
|
||||
throw new IllegalStateException("Value for field with @" + annotations[i].getSimpleName()
|
||||
+ " must be registered beforehand");
|
||||
}
|
||||
values[i] = value;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given object with its class as key. Throws an exception if the key already has
|
||||
* a value associated to it.
|
||||
*
|
||||
* @param object the object to store
|
||||
*/
|
||||
private void storeObject(Object object) {
|
||||
if (objects.containsKey(object.getClass())) {
|
||||
throw new IllegalStateException("There is already an object present for " + object.getClass());
|
||||
}
|
||||
Preconditions.checkNotNull(object);
|
||||
objects.put(object.getClass(), object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that none of the dependencies' types are present in the given collection
|
||||
* of traversed classes. This prevents circular dependencies.
|
||||
*
|
||||
* @param dependencies the dependencies of the class
|
||||
* @param traversedClasses the collection of traversed classes
|
||||
*/
|
||||
private static void validateInjectionHasNoCircularDependencies(Class<?>[] dependencies,
|
||||
Set<Class<?>> traversedClasses) {
|
||||
for (Class<?> clazz : dependencies) {
|
||||
if (traversedClasses.contains(clazz)) {
|
||||
throw new IllegalStateException("Found cyclic dependency - already traversed '" + clazz
|
||||
+ "' (full traversal list: " + traversedClasses + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the package of a parameter type to ensure that it is part of the allowed packages.
|
||||
* This ensures that we don't try to instantiate things that are beyond our reach in case some
|
||||
* external parameter type has not been registered.
|
||||
*
|
||||
* @param clazz the class to validate
|
||||
*/
|
||||
private void validatePackage(Class<?> clazz) {
|
||||
if (clazz.getPackage() == null) {
|
||||
throw new IllegalStateException("Primitive types must be provided explicitly (or use an annotation).");
|
||||
}
|
||||
String packageName = clazz.getPackage().getName();
|
||||
for (String allowedPackage : ALLOWED_PACKAGES) {
|
||||
if (packageName.startsWith(allowedPackage)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Class " + clazz + " with package " + packageName + " is outside of the "
|
||||
+ "allowed packages. It must be provided explicitly or the package must be passed to the constructor.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an object's method annotated with {@link PostConstruct} if present.
|
||||
* Throws an exception if there are multiple such methods, or if the method is static.
|
||||
*
|
||||
* @param object the object to execute the post construct method for
|
||||
*/
|
||||
private static void executePostConstructMethod(Object object) {
|
||||
Method postConstructMethod = getAndValidatePostConstructMethod(object.getClass());
|
||||
if (postConstructMethod != null) {
|
||||
try {
|
||||
postConstructMethod.setAccessible(true);
|
||||
postConstructMethod.invoke(object);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new UnsupportedOperationException("Error executing @PostConstruct method", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateInstantiable(Class<?> clazz) {
|
||||
if (clazz.isEnum() || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
|
||||
throw new IllegalStateException("Class " + clazz.getSimpleName() + " cannot be instantiated");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and locate the given class' post construct method. Returns {@code null} if none present.
|
||||
*
|
||||
* @param clazz the class to search
|
||||
* @return post construct method, or null
|
||||
*/
|
||||
private static Method getAndValidatePostConstructMethod(Class<?> clazz) {
|
||||
Method postConstructMethod = null;
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
if (method.isAnnotationPresent(PostConstruct.class)) {
|
||||
if (postConstructMethod != null) {
|
||||
throw new IllegalStateException("Multiple methods with @PostConstruct on " + clazz);
|
||||
} else if (method.getParameterTypes().length > 0 || Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalStateException("@PostConstruct method may not be static or have any parameters. "
|
||||
+ "Invalid method in " + clazz);
|
||||
} else if (method.getReturnType() != void.class) {
|
||||
throw new IllegalStateException("@PostConstruct method must have return type void. "
|
||||
+ "Offending class: " + clazz);
|
||||
} else {
|
||||
postConstructMethod = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
return postConstructMethod;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <T> Injection<T> firstNotNull(Provider<? extends Injection<T>>... providers) {
|
||||
for (Provider<? extends Injection<T>> provider : providers) {
|
||||
Injection<T> object = provider.get();
|
||||
if (object != null) {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Functionality for constructor injection.
|
||||
*/
|
||||
public class ConstructorInjection<T> implements Injection<T> {
|
||||
|
||||
private final Constructor<T> constructor;
|
||||
|
||||
private ConstructorInjection(Constructor<T> constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getDependencies() {
|
||||
return constructor.getParameterTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getDependencyAnnotations() {
|
||||
Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
|
||||
Class<?>[] annotations = new Class<?>[parameterAnnotations.length];
|
||||
for (int i = 0; i < parameterAnnotations.length; ++i) {
|
||||
annotations[i] = parameterAnnotations[i].length > 0
|
||||
? parameterAnnotations[i][0].annotationType()
|
||||
: null;
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T instantiateWith(Object... values) {
|
||||
validateNoNullValues(values);
|
||||
try {
|
||||
return constructor.newInstance(values);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Provider<ConstructorInjection<T>> provide(final Class<T> clazz) {
|
||||
return new Provider<ConstructorInjection<T>>() {
|
||||
@Override
|
||||
public ConstructorInjection<T> get() {
|
||||
Constructor<T> constructor = getInjectionConstructor(clazz);
|
||||
return constructor == null ? null : new ConstructorInjection<>(constructor);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the first found constructor annotated with {@link Inject} of the given class
|
||||
* and marks it as accessible.
|
||||
*
|
||||
* @param clazz the class to process
|
||||
* @param <T> the class' type
|
||||
* @return injection constructor for the class, null if not applicable
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> Constructor<T> getInjectionConstructor(Class<T> clazz) {
|
||||
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||
for (Constructor<?> constructor : constructors) {
|
||||
if (constructor.isAnnotationPresent(Inject.class)) {
|
||||
constructor.setAccessible(true);
|
||||
return (Constructor<T>) constructor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void validateNoNullValues(Object[] array) {
|
||||
for (Object entry : array) {
|
||||
Preconditions.checkNotNull(entry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
14
src/main/java/fr/xephi/authme/initialization/DataFolder.java
Normal file
14
src/main/java/fr/xephi/authme/initialization/DataFolder.java
Normal file
@ -0,0 +1,14 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation for specifying the plugin's data folder.
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DataFolder {
|
||||
}
|
128
src/main/java/fr/xephi/authme/initialization/FieldInjection.java
Normal file
128
src/main/java/fr/xephi/authme/initialization/FieldInjection.java
Normal file
@ -0,0 +1,128 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Functionality for field injection.
|
||||
*/
|
||||
public class FieldInjection<T> implements Injection<T> {
|
||||
|
||||
private final Field[] fields;
|
||||
private final Constructor<T> defaultConstructor;
|
||||
|
||||
private FieldInjection(Constructor<T> defaultConstructor, Collection<Field> fields) {
|
||||
this.fields = fields.toArray(new Field[fields.size()]);
|
||||
this.defaultConstructor = defaultConstructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getDependencies() {
|
||||
Class<?>[] types = new Class<?>[fields.length];
|
||||
for (int i = 0; i < fields.length; ++i) {
|
||||
types[i] = fields[i].getType();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getDependencyAnnotations() {
|
||||
Class<?>[] annotations = new Class<?>[fields.length];
|
||||
for (int i = 0; i < fields.length; ++i) {
|
||||
annotations[i] = getFirstNonInjectAnnotation(fields[i]);
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T instantiateWith(Object... values) {
|
||||
Preconditions.checkArgument(values.length == fields.length,
|
||||
"The number of values must be equal to the number of fields");
|
||||
|
||||
T instance;
|
||||
try {
|
||||
instance = defaultConstructor.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
|
||||
for (int i = 0; i < fields.length; ++i) {
|
||||
try {
|
||||
Preconditions.checkNotNull(values[i]);
|
||||
fields[i].set(instance, values[i]);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a provider for a {@code FieldInjection<T>} instance, i.e. a provides an object
|
||||
* with which field injection can be performed on the given class if applicable. The provided
|
||||
* value is {@code null} if field injection cannot be applied to the class.
|
||||
*
|
||||
* @param clazz the class to provide field injection for
|
||||
* @param <T> the class' type
|
||||
* @return field injection provider for the given class, or null if not applicable
|
||||
*/
|
||||
public static <T> Provider<FieldInjection<T>> provide(final Class<T> clazz) {
|
||||
return new Provider<FieldInjection<T>>() {
|
||||
@Override
|
||||
public FieldInjection<T> get() {
|
||||
Constructor<T> constructor = getDefaultConstructor(clazz);
|
||||
if (constructor == null) {
|
||||
return null;
|
||||
}
|
||||
List<Field> fields = getInjectionFields(clazz);
|
||||
return fields.isEmpty() ? null : new FieldInjection<>(constructor, fields);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static List<Field> getInjectionFields(Class<?> clazz) {
|
||||
List<Field> fields = new ArrayList<>();
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(Inject.class)) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException(String.format("Field '%s' in class '%s' is static but "
|
||||
+ "annotated with @Inject", field.getName(), clazz.getSimpleName()));
|
||||
}
|
||||
field.setAccessible(true);
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
private static Class<?> getFirstNonInjectAnnotation(Field field) {
|
||||
for (Annotation annotation : field.getAnnotations()) {
|
||||
if (annotation.annotationType() != Inject.class) {
|
||||
return annotation.annotationType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> Constructor<T> getDefaultConstructor(Class<T> clazz) {
|
||||
try {
|
||||
Constructor<?> defaultConstructor = clazz.getDeclaredConstructor();
|
||||
defaultConstructor.setAccessible(true);
|
||||
return (Constructor<T>) defaultConstructor;
|
||||
} catch (NoSuchMethodException ignore) {
|
||||
// no default constructor available
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
36
src/main/java/fr/xephi/authme/initialization/Injection.java
Normal file
36
src/main/java/fr/xephi/authme/initialization/Injection.java
Normal file
@ -0,0 +1,36 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
/**
|
||||
* Common interface for all injection methods.
|
||||
*
|
||||
* @param <T> the type of the concerned object
|
||||
*/
|
||||
public interface Injection<T> {
|
||||
|
||||
/**
|
||||
* Returns the dependencies that must be provided to instantiate the given item.
|
||||
*
|
||||
* @return list of dependencies
|
||||
* @see #instantiateWith
|
||||
*/
|
||||
Class<?>[] getDependencies();
|
||||
|
||||
/**
|
||||
* Returns the annotation on each dependency if available. The indices of this
|
||||
* array correspond to the ones of {@link #getDependencies()}. If no annotation
|
||||
* is available, {@code null} is stored. If multiple annotations are present, only
|
||||
* one is stored (no guarantee on which one).
|
||||
*
|
||||
* @return annotation for each dependency
|
||||
*/
|
||||
Class<?>[] getDependencyAnnotations();
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given values as dependencies. The given values
|
||||
* must correspond to {@link #getDependencies()} in size, order and type.
|
||||
*
|
||||
* @param values the values to set for the dependencies
|
||||
* @return resulting object
|
||||
*/
|
||||
T instantiateWith(Object... values);
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Fallback instantiation method for classes with an accessible no-args constructor
|
||||
* and no elements whatsoever annotated with {@link Inject} or {@link PostConstruct}.
|
||||
*/
|
||||
public class InstantiationFallback<T> implements Injection<T> {
|
||||
|
||||
private final Constructor<T> constructor;
|
||||
|
||||
private InstantiationFallback(Constructor<T> constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getDependencies() {
|
||||
return new Class<?>[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getDependencyAnnotations() {
|
||||
return new Class<?>[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public T instantiateWith(Object... values) {
|
||||
if (values == null || values.length > 0) {
|
||||
throw new UnsupportedOperationException("Instantiation fallback cannot have parameters");
|
||||
}
|
||||
try {
|
||||
return constructor.newInstance();
|
||||
} catch (InvocationTargetException | IllegalAccessException | InstantiationException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instantiation fallback if the class is applicable.
|
||||
*
|
||||
* @param clazz the class
|
||||
* @param <T> the class' type
|
||||
* @return instantiation fallback provider for the given class, or null if not applicable
|
||||
*/
|
||||
public static <T> Provider<InstantiationFallback<T>> provide(final Class<T> clazz) {
|
||||
return new Provider<InstantiationFallback<T>>() {
|
||||
@Override
|
||||
public InstantiationFallback<T> get() {
|
||||
Constructor<T> noArgsConstructor = getNoArgsConstructor(clazz);
|
||||
// Return fallback only if we have no args constructor and no @Inject annotation anywhere
|
||||
if (noArgsConstructor != null
|
||||
&& !isInjectionAnnotationPresent(clazz.getDeclaredConstructors())
|
||||
&& !isInjectionAnnotationPresent(clazz.getDeclaredFields())
|
||||
&& !isInjectionAnnotationPresent(clazz.getDeclaredMethods())) {
|
||||
return new InstantiationFallback<>(noArgsConstructor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> Constructor<T> getNoArgsConstructor(Class<T> clazz) {
|
||||
try {
|
||||
// Note ljacqu 20160504: getConstructor(), unlike getDeclaredConstructor(), only considers public members
|
||||
return clazz.getConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static <A extends AccessibleObject> boolean isInjectionAnnotationPresent(A[] accessibles) {
|
||||
for (A accessible : accessibles) {
|
||||
if (accessible.isAnnotationPresent(Inject.class) || accessible.isAnnotationPresent(PostConstruct.class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package fr.xephi.authme;
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
13
src/main/java/fr/xephi/authme/initialization/Reloadable.java
Normal file
13
src/main/java/fr/xephi/authme/initialization/Reloadable.java
Normal file
@ -0,0 +1,13 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
/**
|
||||
* Interface for reloadable entities.
|
||||
*/
|
||||
public interface Reloadable {
|
||||
|
||||
/**
|
||||
* Performs the reload action.
|
||||
*/
|
||||
void reload();
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
|
||||
/**
|
||||
* Interface for classes that keep a local copy of certain settings.
|
||||
*/
|
||||
public interface SettingsDependent {
|
||||
|
||||
/**
|
||||
* Loads the needed settings.
|
||||
*
|
||||
* @param settings the settings instance
|
||||
*/
|
||||
void loadSettings(NewSetting settings);
|
||||
}
|
@ -5,18 +5,23 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class AuthMeBlockListener implements Listener {
|
||||
|
||||
@Inject
|
||||
private ListenerService listenerService;
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (ListenerService.shouldCancelEvent(event.getPlayer())) {
|
||||
if (listenerService.shouldCancelEvent(event.getPlayer())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if (ListenerService.shouldCancelEvent(event.getPlayer())) {
|
||||
if (listenerService.shouldCancelEvent(event.getPlayer())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
@ -14,29 +15,32 @@ import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.EntityTargetEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent;
|
||||
|
||||
public class AuthMeEntityListener implements Listener {
|
||||
|
||||
private static Method getShooter;
|
||||
private static boolean shooterIsProjectileSource;
|
||||
private final ListenerService listenerService;
|
||||
private Method getShooter;
|
||||
private boolean shooterIsLivingEntity;
|
||||
|
||||
public AuthMeEntityListener() {
|
||||
@Inject
|
||||
AuthMeEntityListener(ListenerService listenerService) {
|
||||
this.listenerService = listenerService;
|
||||
try {
|
||||
Method m = Projectile.class.getDeclaredMethod("getShooter");
|
||||
shooterIsProjectileSource = m.getReturnType() != LivingEntity.class;
|
||||
} catch (Exception ignored) {
|
||||
getShooter = Projectile.class.getDeclaredMethod("getShooter");
|
||||
shooterIsLivingEntity = getShooter.getReturnType() == LivingEntity.class;
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
ConsoleLogger.logException("Cannot load getShooter() method on Projectile class", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Note #360: npc status can be used to bypass security!!!
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.getEntity().setFireTicks(0);
|
||||
event.setDamage(0);
|
||||
event.setCancelled(true);
|
||||
@ -45,7 +49,7 @@ public class AuthMeEntityListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onEntityTarget(EntityTargetEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setTarget(null);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@ -53,21 +57,21 @@ public class AuthMeEntityListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onDamage(EntityDamageByEntityEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void entityRegainHealthEvent(EntityRegainHealthEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setAmount(0);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@ -75,53 +79,48 @@ public class AuthMeEntityListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onEntityInteract(EntityInteractEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onLowestEntityInteract(EntityInteractEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO #568: Need to check this, player can't throw snowball but the item is taken.
|
||||
// TODO #733: 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) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = null;
|
||||
Projectile projectile = event.getEntity();
|
||||
if (shooterIsProjectileSource) {
|
||||
ProjectileSource shooter = projectile.getShooter();
|
||||
if (shooter == null || !(shooter instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
player = (Player) shooter;
|
||||
} else {
|
||||
// TODO #568 20151220: Invoking getShooter() with null but method isn't static
|
||||
// In the Bukkit API prior to 1.7, getShooter() returns a LivingEntity instead of a ProjectileSource
|
||||
Object shooterRaw = null;
|
||||
if (shooterIsLivingEntity) {
|
||||
try {
|
||||
if (getShooter == null) {
|
||||
getShooter = Projectile.class.getMethod("getShooter");
|
||||
}
|
||||
Object obj = getShooter.invoke(null);
|
||||
player = (Player) obj;
|
||||
} catch (Exception ignored) {
|
||||
shooterRaw = getShooter.invoke(projectile);
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
ConsoleLogger.logException("Error getting shooter", e);
|
||||
}
|
||||
} else {
|
||||
shooterRaw = projectile.getShooter();
|
||||
}
|
||||
|
||||
if (ListenerService.shouldCancelEvent(player)) {
|
||||
if (shooterRaw instanceof Player && listenerService.shouldCancelEvent((Player) shooterRaw)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
public void onShoot(EntityShootBowEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,18 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import fr.xephi.authme.AntiBot;
|
||||
import fr.xephi.authme.AntiBot.AntiBotStatus;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
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.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -54,11 +40,12 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_MOVEMENT_RADIUS;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_ALL_COMMANDS_IF_REGISTRATION_IS_OPTIONAL;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT;
|
||||
|
||||
/**
|
||||
@ -67,107 +54,65 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAU
|
||||
public class AuthMePlayerListener implements Listener {
|
||||
|
||||
public static final ConcurrentHashMap<String, String> joinMessage = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentHashMap<String, Boolean> causeByAuthMe = new ConcurrentHashMap<>();
|
||||
private final AuthMe plugin;
|
||||
private final NewSetting settings;
|
||||
private final Messages m;
|
||||
private final DataSource dataSource;
|
||||
private final AntiBot antiBot;
|
||||
private final Management management;
|
||||
private final BukkitService bukkitService;
|
||||
private final ValidationService validationService;
|
||||
|
||||
public AuthMePlayerListener(AuthMe plugin, NewSetting settings, Messages messages, DataSource dataSource,
|
||||
AntiBot antiBot, Management management, BukkitService bukkitService,
|
||||
ValidationService validationService) {
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
this.m = messages;
|
||||
this.dataSource = dataSource;
|
||||
this.antiBot = antiBot;
|
||||
this.management = management;
|
||||
this.bukkitService = bukkitService;
|
||||
this.validationService = validationService;
|
||||
}
|
||||
|
||||
private void handleChat(AsyncPlayerChatEvent event) {
|
||||
if (settings.getProperty(RestrictionSettings.ALLOW_CHAT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
if (shouldCancelEvent(player)) {
|
||||
event.setCancelled(true);
|
||||
sendLoginOrRegisterMessage(player);
|
||||
} else if (settings.getProperty(RestrictionSettings.HIDE_CHAT)) {
|
||||
for (Player p : bukkitService.getOnlinePlayers()) {
|
||||
if (!PlayerCache.getInstance().isAuthenticated(p.getName())) {
|
||||
event.getRecipients().remove(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendLoginOrRegisterMessage(final Player player) {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (dataSource.isAuthAvailable(player.getName().toLowerCase())) {
|
||||
m.send(player, MessageKey.LOGIN_MESSAGE);
|
||||
} else {
|
||||
if (settings.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)) {
|
||||
m.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
} else {
|
||||
m.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
@Inject
|
||||
private Messages m;
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
@Inject
|
||||
private AntiBot antiBot;
|
||||
@Inject
|
||||
private Management management;
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
@Inject
|
||||
private OnJoinVerifier onJoinVerifier;
|
||||
@Inject
|
||||
private ListenerService listenerService;
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
String cmd = event.getMessage().split(" ")[0].toLowerCase();
|
||||
if (settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD) && "/motd".equals(cmd)) {
|
||||
return;
|
||||
}
|
||||
if (!settings.getProperty(RegistrationSettings.FORCE)
|
||||
&& settings.getProperty(ALLOW_ALL_COMMANDS_IF_REGISTRATION_IS_OPTIONAL)) {
|
||||
if (settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD) && cmd.equals("/motd")) {
|
||||
return;
|
||||
}
|
||||
if (settings.getProperty(RestrictionSettings.ALLOW_COMMANDS).contains(cmd)) {
|
||||
return;
|
||||
}
|
||||
if (Utils.checkAuth(event.getPlayer())) {
|
||||
return;
|
||||
final Player player = event.getPlayer();
|
||||
if (listenerService.shouldCancelEvent(player)) {
|
||||
event.setCancelled(true);
|
||||
m.send(player, MessageKey.DENIED_COMMAND);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
sendLoginOrRegisterMessage(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
public void onPlayerNormalChat(AsyncPlayerChatEvent event) {
|
||||
handleChat(event);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||
public void onPlayerHighChat(AsyncPlayerChatEvent event) {
|
||||
handleChat(event);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onPlayerHighestChat(AsyncPlayerChatEvent event) {
|
||||
handleChat(event);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerEarlyChat(AsyncPlayerChatEvent event) {
|
||||
handleChat(event);
|
||||
}
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
if (settings.getProperty(RestrictionSettings.ALLOW_CHAT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void onPlayerLowChat(AsyncPlayerChatEvent event) {
|
||||
handleChat(event);
|
||||
final Player player = event.getPlayer();
|
||||
if (listenerService.shouldCancelEvent(player)) {
|
||||
event.setCancelled(true);
|
||||
m.send(player, MessageKey.DENIED_CHAT);
|
||||
} else if (settings.getProperty(RestrictionSettings.HIDE_CHAT)) {
|
||||
Set<Player> recipients = event.getRecipients();
|
||||
Iterator<Player> iter = recipients.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Player p = iter.next();
|
||||
if (listenerService.shouldCancelEvent(p)) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
if (recipients.size() == 0) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
@ -176,24 +121,26 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Limit player X and Z movements to 1 block
|
||||
* Deny player Y+ movements (allows falling)
|
||||
*/
|
||||
if (event.getFrom().getBlockX() == event.getTo().getBlockX()
|
||||
&& event.getFrom().getBlockZ() == event.getTo().getBlockZ()
|
||||
&& event.getFrom().getY() - event.getTo().getY() >= 0) {
|
||||
Location from = event.getFrom();
|
||||
Location to = event.getTo();
|
||||
if (from.getBlockX() == to.getBlockX()
|
||||
&& from.getBlockZ() == to.getBlockZ()
|
||||
&& from.getY() - to.getY() >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (Utils.checkAuth(player)) {
|
||||
if (!listenerService.shouldCancelEvent(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!settings.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)) {
|
||||
// "cancel" the event
|
||||
event.setTo(event.getFrom());
|
||||
// sgdc3 TODO: remove this, maybe we should set the effect every x ticks, idk!
|
||||
if (settings.getProperty(RestrictionSettings.REMOVE_SPEED)) {
|
||||
player.setFlySpeed(0.0f);
|
||||
player.setWalkSpeed(0.0f);
|
||||
@ -205,7 +152,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
Location spawn = plugin.getSpawnLocation(player);
|
||||
Location spawn = spawnLoader.getSpawnLocation(player);
|
||||
if (spawn != null && spawn.getWorld() != null) {
|
||||
if (!player.getWorld().equals(spawn.getWorld())) {
|
||||
player.teleport(spawn);
|
||||
@ -245,149 +192,82 @@ public class AuthMePlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
if (player == null) {
|
||||
return;
|
||||
if (player != null) {
|
||||
// Schedule login task so works after the prelogin
|
||||
// (Fix found by Koolaid5000)
|
||||
bukkitService.runTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
management.performJoin(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (settings.getProperty(RestrictionSettings.FORCE_SURVIVAL_MODE)
|
||||
&& !player.hasPermission(PlayerStatePermission.BYPASS_FORCE_SURVIVAL.getNode())) {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
}
|
||||
|
||||
// Shedule login task so works after the prelogin
|
||||
// (Fix found by Koolaid5000)
|
||||
bukkitService.runTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
management.performJoin(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Note ljacqu 20160528: AsyncPlayerPreLoginEvent is not fired by all servers in offline mode
|
||||
// e.g. CraftBukkit does not. So we need to run crucial things in onPlayerLogin, too
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
||||
PlayerAuth auth = dataSource.getAuth(event.getName());
|
||||
if (settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE) && auth != null && auth.getRealName() != null) {
|
||||
String realName = auth.getRealName();
|
||||
if (!realName.isEmpty() && !"Player".equals(realName) && !realName.equals(event.getName())) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.INVALID_NAME_CASE, realName, event.getName()));
|
||||
return;
|
||||
}
|
||||
if (realName.isEmpty() || "Player".equals(realName)) {
|
||||
dataSource.updateRealName(event.getName().toLowerCase(), event.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (auth == null && settings.getProperty(ProtectionSettings.ENABLE_PROTECTION)) {
|
||||
String playerIp = event.getAddress().getHostAddress();
|
||||
if (!validationService.isCountryAdmitted(playerIp)) {
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final String name = event.getName().toLowerCase();
|
||||
final Player player = bukkitService.getPlayerExact(name);
|
||||
// Check if forceSingleSession is set to true, so kick player that has
|
||||
// joined with same nick of online player
|
||||
if (player != null && settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)) {
|
||||
final boolean isAuthAvailable = dataSource.isAuthAvailable(event.getName());
|
||||
|
||||
try {
|
||||
// Potential performance improvement: make checkAntiBot not require `isAuthAvailable` info and use
|
||||
// "checkKickNonRegistered" as last -> no need to query the DB before checking antibot / name
|
||||
onJoinVerifier.checkAntibot(name, isAuthAvailable);
|
||||
onJoinVerifier.checkKickNonRegistered(isAuthAvailable);
|
||||
onJoinVerifier.checkIsValidName(name);
|
||||
// Note #760: Single session must be checked here - checking with PlayerLoginEvent is too late and
|
||||
// the first connection will have been kicked. This means this feature doesn't work on CraftBukkit.
|
||||
onJoinVerifier.checkSingleSession(name);
|
||||
} catch (FailedVerificationException e) {
|
||||
event.setKickMessage(m.retrieveSingle(e.getReason(), e.getArgs()));
|
||||
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR));
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
Utils.addNormal(player, limbo.getGroup());
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
if (player == null || Utils.isUnrestricted(player)) {
|
||||
if (Utils.isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the permissions manager
|
||||
PermissionsManager permsMan = plugin.getPermissionsManager();
|
||||
|
||||
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL) {
|
||||
if (permsMan.hasPermission(player, PlayerStatePermission.IS_VIP)) {
|
||||
int playersOnline = bukkitService.getOnlinePlayers().size();
|
||||
if (playersOnline > plugin.getServer().getMaxPlayers()) {
|
||||
event.allow();
|
||||
} else {
|
||||
Player pl = plugin.generateKickPlayer(bukkitService.getOnlinePlayers());
|
||||
if (pl != null) {
|
||||
pl.kickPlayer(m.retrieveSingle(MessageKey.KICK_FOR_VIP));
|
||||
event.allow();
|
||||
} else {
|
||||
ConsoleLogger.info("The player " + event.getPlayer().getName() + " tried to join, but the server was full");
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||
} else if (onJoinVerifier.refusePlayerForFullServer(event)) {
|
||||
return;
|
||||
} else if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String name = player.getName().toLowerCase();
|
||||
boolean isAuthAvailable = dataSource.isAuthAvailable(name);
|
||||
final PlayerAuth auth = dataSource.getAuth(player.getName());
|
||||
final boolean isAuthAvailable = (auth != null);
|
||||
|
||||
if (antiBot.getAntiBotStatus() == AntiBotStatus.ACTIVE && !isAuthAvailable) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT));
|
||||
try {
|
||||
onJoinVerifier.checkAntibot(name, isAuthAvailable);
|
||||
onJoinVerifier.checkKickNonRegistered(isAuthAvailable);
|
||||
onJoinVerifier.checkIsValidName(name);
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
onJoinVerifier.checkPlayerCountry(isAuthAvailable, event);
|
||||
} catch (FailedVerificationException e) {
|
||||
event.setKickMessage(m.retrieveSingle(e.getReason(), e.getArgs()));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED) && !isAuthAvailable) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.MUST_REGISTER_MESSAGE));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.length() > Settings.getMaxNickLength || name.length() < Settings.getMinNickLength) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.INVALID_NAME_LENGTH));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Settings.nickPattern.matcher(player.getName()).matches() || name.equalsIgnoreCase("Player")) {
|
||||
event.setKickMessage(m.retrieveSingle(MessageKey.INVALID_NAME_CHARACTERS).replace("REG_EX", Settings.getNickRegex));
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
antiBot.checkAntiBot(player);
|
||||
|
||||
if (settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("IP");
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
antiBot.handlePlayerJoin(player);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.getProperty(RegistrationSettings.REMOVE_LEAVE_MESSAGE)) {
|
||||
event.setQuitMessage(null);
|
||||
}
|
||||
|
||||
if (antiBot.antibotKicked.contains(player.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
management.performQuit(player, false);
|
||||
}
|
||||
|
||||
@ -395,42 +275,28 @@ public class AuthMePlayerListener implements Listener {
|
||||
public void onPlayerKick(PlayerKickEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
if (!antiBot.antibotKicked.contains(player.getName())) {
|
||||
management.performQuit(player, true);
|
||||
}
|
||||
|
||||
if (!settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)
|
||||
&& event.getReason().equals(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getManagement().performQuit(player, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
* Note #360: npc status can be used to bypass security!!!
|
||||
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
*/
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerConsumeItem(PlayerItemConsumeEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -439,7 +305,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
|
||||
final Player player = (Player) event.getPlayer();
|
||||
|
||||
if (!ListenerService.shouldCancelEvent(player)) {
|
||||
if (!listenerService.shouldCancelEvent(player)) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
@ -448,7 +314,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
* @note little hack cause InventoryOpenEvent cannot be cancelled for
|
||||
* real, cause no packet is send to server by client for the main inv
|
||||
*/
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.closeInventory();
|
||||
@ -458,41 +324,43 @@ public class AuthMePlayerListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerInventoryClick(InventoryClickEvent event) {
|
||||
if (event.getWhoClicked() == null)
|
||||
if (event.getWhoClicked() == null) {
|
||||
return;
|
||||
if (!(event.getWhoClicked() instanceof Player))
|
||||
}
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
if (Utils.checkAuth((Player) event.getWhoClicked()))
|
||||
return;
|
||||
if (Utils.isNPC((Player) event.getWhoClicked()))
|
||||
}
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
if (!listenerService.shouldCancelEvent(player)) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerHitPlayerEvent(EntityDamageByEntityEvent event) {
|
||||
if (ListenerService.shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -500,21 +368,24 @@ public class AuthMePlayerListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (ListenerService.shouldCancelEvent(player)) {
|
||||
if (listenerService.shouldCancelEvent(player)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check this, why do we need to update the quit loc? -sgdc3
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onPlayerRespawn(PlayerRespawnEvent event) {
|
||||
if (!shouldCancelEvent(event)) {
|
||||
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||
return;
|
||||
}
|
||||
if (!listenerService.shouldCancelEvent(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName().toLowerCase();
|
||||
Location spawn = plugin.getSpawnLocation(player);
|
||||
if (Settings.isSaveQuitLocationEnabled && dataSource.isAuthAvailable(name)) {
|
||||
Location spawn = spawnLoader.getSpawnLocation(player);
|
||||
if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION) && dataSource.isAuthAvailable(name)) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.realName(player.getName())
|
||||
@ -529,15 +400,16 @@ public class AuthMePlayerListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerShear(PlayerShearEntityEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerFish(PlayerFishEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,14 +5,19 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerEditBookEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Listener of player events for events introduced in Minecraft 1.6.
|
||||
*/
|
||||
public class AuthMePlayerListener16 implements Listener {
|
||||
|
||||
@Inject
|
||||
private ListenerService listenerService;
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerEditBook(PlayerEditBookEvent event) {
|
||||
if (ListenerService.shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -5,14 +5,19 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Listener of player events for events introduced in Minecraft 1.8.
|
||||
*/
|
||||
public class AuthMePlayerListener18 implements Listener {
|
||||
|
||||
@Inject
|
||||
private ListenerService listenerService;
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
|
||||
if (ListenerService.shouldCancelEvent(event)) {
|
||||
if (listenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.spigotmc.event.player.PlayerSpawnLocationEvent;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
/**
|
||||
* Listener of player events for events introduced in Minecraft 1.9.
|
||||
*/
|
||||
public class AuthMePlayerListener19 implements Listener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
|
||||
public AuthMePlayerListener19(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerSpawn(PlayerSpawnLocationEvent event) {
|
||||
event.setSpawnLocation(plugin.getSpawnLocation(event.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,7 @@ 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.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
@ -16,26 +17,26 @@ import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.event.server.ServerListPingEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AuthMeServerListener implements Listener {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final Messages messages;
|
||||
private final NewSetting settings;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final SpawnLoader spawnLoader;
|
||||
private final ValidationService validationService;
|
||||
|
||||
public AuthMeServerListener(AuthMe plugin, Messages messages, NewSetting settings, PluginHooks pluginHooks,
|
||||
SpawnLoader spawnLoader, ValidationService validationService) {
|
||||
this.plugin = plugin;
|
||||
this.messages = messages;
|
||||
this.settings = settings;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.spawnLoader = spawnLoader;
|
||||
this.validationService = validationService;
|
||||
}
|
||||
@Inject
|
||||
private AuthMe plugin;
|
||||
@Inject
|
||||
private Messages messages;
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
@Inject
|
||||
private PluginHooks pluginHooks;
|
||||
@Inject
|
||||
private SpawnLoader spawnLoader;
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
@Inject
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onServerPing(ServerListPingEvent event) {
|
||||
@ -54,10 +55,11 @@ public class AuthMeServerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call the onPluginDisable method in the permissions manager
|
||||
plugin.getPermissionsManager().onPluginDisable(event);
|
||||
|
||||
final String pluginName = event.getPlugin().getName();
|
||||
|
||||
// Call the onPluginDisable method in the permissions manager
|
||||
permissionsManager.onPluginDisable(pluginName);
|
||||
|
||||
if ("Essentials".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.unhookEssentials();
|
||||
ConsoleLogger.info("Essentials has been disabled: unhooking");
|
||||
@ -87,10 +89,11 @@ public class AuthMeServerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call the onPluginEnable method in the permissions manager
|
||||
plugin.getPermissionsManager().onPluginEnable(event);
|
||||
|
||||
final String pluginName = event.getPlugin().getName();
|
||||
|
||||
// Call the onPluginEnable method in the permissions manager
|
||||
permissionsManager.onPluginEnable(pluginName);
|
||||
|
||||
if ("Essentials".equalsIgnoreCase(pluginName)) {
|
||||
pluginHooks.tryHookToEssentials();
|
||||
} else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) {
|
||||
|
@ -11,8 +11,11 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class AuthMeTabCompletePacketAdapter extends PacketAdapter {
|
||||
|
||||
@Inject
|
||||
public AuthMeTabCompletePacketAdapter(AuthMe plugin) {
|
||||
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.TAB_COMPLETE);
|
||||
}
|
||||
|
@ -14,14 +14,13 @@ import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
@ -30,6 +29,7 @@ public class AuthMeTablistPacketAdapter extends PacketAdapter {
|
||||
|
||||
private final BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
public AuthMeTablistPacketAdapter(AuthMe plugin, BukkitService bukkitService) {
|
||||
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO);
|
||||
this.bukkitService = bukkitService;
|
||||
|
@ -0,0 +1,33 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Exception thrown when a verification has failed.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class FailedVerificationException extends Exception {
|
||||
|
||||
private final MessageKey reason;
|
||||
private final String[] args;
|
||||
|
||||
public FailedVerificationException(MessageKey reason, String... args) {
|
||||
this.reason = reason;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public MessageKey getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public String[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ": reason=" + (reason == null ? "null" : reason)
|
||||
+ ";args=" + (args == null ? "null" : StringUtils.join(", ", args));
|
||||
}
|
||||
}
|
@ -1,26 +1,48 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityEvent;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
/**
|
||||
* Service class for the AuthMe listeners.
|
||||
*/
|
||||
final class ListenerService {
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
private ListenerService() {
|
||||
/**
|
||||
* Service class for the AuthMe listeners to determine whether an event should be canceled.
|
||||
*/
|
||||
class ListenerService implements SettingsDependent {
|
||||
|
||||
private final DataSource dataSource;
|
||||
private final PluginHooks pluginHooks;
|
||||
private final PlayerCache playerCache;
|
||||
|
||||
private boolean isRegistrationForced;
|
||||
private Set<String> unrestrictedNames;
|
||||
|
||||
@Inject
|
||||
ListenerService(NewSetting settings, DataSource dataSource, PluginHooks pluginHooks, PlayerCache playerCache) {
|
||||
this.dataSource = dataSource;
|
||||
this.pluginHooks = pluginHooks;
|
||||
this.playerCache = playerCache;
|
||||
loadSettings(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether an event should be canceled (for unauthenticated, non-NPC players).
|
||||
* Returns whether an event should be canceled (for unauthenticated, non-NPC players).
|
||||
*
|
||||
* @param event The event to process
|
||||
* @return True if the event should be canceled, false otherwise
|
||||
* @param event the event to process
|
||||
* @return true if the event should be canceled, false otherwise
|
||||
*/
|
||||
public static boolean shouldCancelEvent(EntityEvent event) {
|
||||
public boolean shouldCancelEvent(EntityEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity == null || !(entity instanceof Player)) {
|
||||
return false;
|
||||
@ -31,24 +53,57 @@ final class ListenerService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether an event should be canceled (for unauthenticated, non-NPC players).
|
||||
* Returns whether an event should be canceled (for unauthenticated, non-NPC players).
|
||||
*
|
||||
* @param event The event to process
|
||||
* @return True if the event should be canceled, false otherwise
|
||||
* @param event the event to process
|
||||
* @return true if the event should be canceled, false otherwise
|
||||
*/
|
||||
public static boolean shouldCancelEvent(PlayerEvent event) {
|
||||
public boolean shouldCancelEvent(PlayerEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
return shouldCancelEvent(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return, based on the player associated with the event, whether or not the event should be canceled.
|
||||
* Returns, based on the player associated with the event, whether or not the event should be canceled.
|
||||
*
|
||||
* @param player The player to verify
|
||||
* @return True if the associated event should be canceled, false otherwise
|
||||
* @param player the player to verify
|
||||
* @return true if the associated event should be canceled, false otherwise
|
||||
*/
|
||||
public static boolean shouldCancelEvent(Player player) {
|
||||
return player != null && !Utils.checkAuth(player) && !Utils.isNPC(player);
|
||||
public boolean shouldCancelEvent(Player player) {
|
||||
return player != null && !checkAuth(player.getName()) && !pluginHooks.isNpc(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings(NewSetting settings) {
|
||||
isRegistrationForced = settings.getProperty(RegistrationSettings.FORCE);
|
||||
// Keep unrestricted names as Set for more efficient contains()
|
||||
unrestrictedNames = new HashSet<>(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the player is allowed to perform actions (i.e. whether he is logged in
|
||||
* or if other settings permit playing).
|
||||
*
|
||||
* @param name the name of the player to verify
|
||||
* @return true if the player may play, false otherwise
|
||||
*/
|
||||
private boolean checkAuth(String name) {
|
||||
if (isUnrestricted(name) || playerCache.isAuthenticated(name)) {
|
||||
return true;
|
||||
}
|
||||
if (!isRegistrationForced && !dataSource.isAuthAvailable(name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the name is unrestricted according to the configured settings.
|
||||
*
|
||||
* @param name the name to verify
|
||||
* @return true if unrestricted, false otherwise
|
||||
*/
|
||||
private boolean isUnrestricted(String name) {
|
||||
return unrestrictedNames.contains(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user