mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-22 10:15:18 +01:00
Merge remote-tracking branch 'origin/master' into junit5-migration
# Conflicts: # src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java # src/test/java/fr/xephi/authme/output/Log4JFilterTest.java # src/test/java/fr/xephi/authme/process/register/AsyncRegisterTest.java # src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java # src/test/java/fr/xephi/authme/service/ValidationServiceTest.java # src/test/java/fr/xephi/authme/settings/SettingsWarnerTest.java # src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java # src/test/java/fr/xephi/authme/util/StringUtilsTest.java
This commit is contained in:
commit
d3a55011c9
@ -192,6 +192,12 @@
|
||||
<module name="MissingOverride"/>
|
||||
<module name="EqualsHashCode"/>
|
||||
<module name="EqualsAvoidNull"/>
|
||||
<module name="Regexp">
|
||||
<property name="format" value="\.to(Lower|Upper)Case\(\)"/>
|
||||
<property name="illegalPattern" value="true"/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
<property name="message" value="Use toLowerCase/toUpperCase with Locale"/>
|
||||
</module>
|
||||
</module>
|
||||
<module name="FileTabCharacter"/>
|
||||
</module>
|
||||
|
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@ -9,4 +9,6 @@ updates:
|
||||
- dependency-name: com.google.code.gson:gson
|
||||
- dependency-name: com.google.guava:guava
|
||||
- dependency-name: org.apache.logging.log4j:log4j-core
|
||||
- dependency-name: mysql:mysql-connector-java
|
||||
- dependency-name: com.zaxxer:HikariCP
|
||||
- dependency-name: "org.mockito:mockito-core" # Mockito 5 requires Java 11
|
||||
versions: ">= 5"
|
||||
|
22
.github/workflows/maven.yml
vendored
22
.github/workflows/maven.yml
vendored
@ -1,17 +1,23 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
jdkversion: [11]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 1.8
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ matrix.jdkversion }}
|
||||
cache: 'maven'
|
||||
- name: Build with Maven
|
||||
run: mvn -B clean package --file pom.xml
|
||||
run: mvn -V -B clean package --file pom.xml
|
||||
|
38
.travis.yml
38
.travis.yml
@ -1,13 +1,35 @@
|
||||
sudo: false
|
||||
dist: trusty
|
||||
dist: focal
|
||||
|
||||
language: java
|
||||
jdk:
|
||||
- openjdk16
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- JDK_VERSION=8
|
||||
- env:
|
||||
- JDK_VERSION=11
|
||||
- env:
|
||||
- JDK_VERSION=17
|
||||
|
||||
before_install:
|
||||
- wget https://downloads.apache.org/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz
|
||||
- tar xzvf apache-maven-3.8.4-bin.tar.gz
|
||||
- export PATH=`pwd`/apache-maven-3.8.4/bin:$PATH
|
||||
- "[[ -d $HOME/.sdkman/ ]] && [[ -d $HOME/.sdkman/bin/ ]] || rm -rf $HOME/.sdkman/"
|
||||
- curl -s "https://get.sdkman.io" | bash
|
||||
- mkdir -p "$HOME/.sdkman/etc/"
|
||||
- echo sdkman_auto_answer=true > "$HOME/.sdkman/etc/config"
|
||||
- echo sdkman_auto_selfupdate=true >> "$HOME/.sdkman/etc/config"
|
||||
- source "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
|
||||
install:
|
||||
- sdk install java $(sdk list java | grep -o "$JDK_VERSION\.[0-9]*\.[0-9]*\-open" | head -1)
|
||||
- sdk install maven
|
||||
- export JAVA_HOME="$HOME/.sdkman/candidates/java/current"
|
||||
- export PATH=${JAVA_HOME}/bin:${PATH}
|
||||
- export MAVEN_HOME="$HOME/.sdkman/candidates/maven/current"
|
||||
- export M2_HOME="$MAVEN_HOME"
|
||||
- export PATH=${M2_HOME}/bin:${PATH}
|
||||
- env
|
||||
- mvn -v
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.m2/repository'
|
||||
- $HOME/.m2/repository
|
||||
|
@ -116,16 +116,16 @@ You can also create your own translation file and, if you want, you can share it
|
||||
## Requirements
|
||||
|
||||
##### Compiling requirements:
|
||||
>- JDK 8 (JDK 17 is recommended)
|
||||
>- JDK 11 (JDK 17 is recommended)
|
||||
>- Maven
|
||||
>- Git/Github (Optional)
|
||||
|
||||
##### How to compile the project:
|
||||
>- Clone the project with Git/Github
|
||||
>- Clone the project with Git/GitHub
|
||||
>- Execute command "mvn clean package"
|
||||
|
||||
##### Running requirements:
|
||||
>- Java 8 (Java 11 is recommended)
|
||||
>- Java 8 (Java 17 is recommended)
|
||||
>- Paper or Spigot (1.8.X and up)<br>
|
||||
(In case you use Thermos, Cauldron or similar, you have to update the SpecialSource library to support Java 8 plugins.
|
||||
HowTo: https://github.com/games647/FastLogin/issues/111#issuecomment-272331347)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sat Dec 25 15:40:26 CET 2021. See docs/config/config.tpl.md -->
|
||||
<!-- File auto-generated on Thu Jul 28 18:11:22 CEST 2022. See docs/config/config.tpl.md -->
|
||||
|
||||
## AuthMe Configuration
|
||||
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
|
||||
@ -9,7 +9,7 @@ the generated config.yml file.
|
||||
```yml
|
||||
DataSource:
|
||||
# What type of database do you want to use?
|
||||
# Valid values: SQLITE, MYSQL, POSTGRESQL
|
||||
# Valid values: SQLITE, MARIADB, MYSQL, POSTGRESQL
|
||||
backend: SQLITE
|
||||
# Enable the database caching system, should be disabled on bungeecord environments
|
||||
# or when a website integration is being used.
|
||||
@ -24,15 +24,13 @@ DataSource:
|
||||
# We would not recommend to set this option to false.
|
||||
# Set this option to false at your own risk if and only if you know what you're doing
|
||||
mySQLCheckServerCertificate: true
|
||||
# Authorize client to retrieve RSA server public key.
|
||||
# Advanced option, ignore if you don't know what it means.
|
||||
mySQLAllowPublicKeyRetrieval: true
|
||||
# Username to connect to the MySQL database
|
||||
mySQLUsername: authme
|
||||
# Password to connect to the MySQL database
|
||||
mySQLPassword: '12345'
|
||||
# Driver Name of the MySQL database.
|
||||
# Built-in drivers:
|
||||
# MySQL: 'fr.xephi.authme.libs.com.mysql.cj.jdbc.Driver'
|
||||
# MariaDB: 'fr.xephi.authme.libs.org.mariadb.jdbc.Driver'
|
||||
mySQLDriverClassName: fr.xephi.authme.libs.com.mysql.cj.jdbc.Driver
|
||||
# Database Name, use with converters or as SQLITE database name
|
||||
mySQLDatabase: authme
|
||||
# Table of the database
|
||||
@ -590,4 +588,4 @@ To change settings on a running server, save your changes to config.yml and use
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Dec 25 15:40:26 CET 2021
|
||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Thu Jul 28 18:11:22 CEST 2022
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sun Apr 04 21:31:44 CEST 2021. See docs/translations/translations.tpl.md -->
|
||||
<!-- File auto-generated on Wed Jun 21 12:14:29 CEST 2023. See docs/translations/translations.tpl.md -->
|
||||
|
||||
# AuthMe Translations
|
||||
The following translations are available in AuthMe. Set `messagesLanguage` to the language code
|
||||
@ -22,10 +22,11 @@ Code | Language | Translated |
|
||||
[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||
[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 93% | <img src="https://via.placeholder.com/93x7/77dd44?text=%20" alt="93" />
|
||||
[it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[ja](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ja.yml) | Japanese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||
[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 36% | <img src="https://via.placeholder.com/36x7/aa4400?text=%20" alt="36" />
|
||||
[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||
[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
@ -34,13 +35,13 @@ Code | Language | Translated |
|
||||
[sr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sr.yml) | Serbian | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||
[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 77% | <img src="https://via.placeholder.com/77x7/bb9900?text=%20" alt="77" />
|
||||
[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||
[zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 64% | <img src="https://via.placeholder.com/64x7/bb7700?text=%20" alt="64" />
|
||||
[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 86% | <img src="https://via.placeholder.com/86x7/99bb22?text=%20" alt="86" />
|
||||
[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Apr 04 21:31:44 CEST 2021
|
||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Wed Jun 21 12:14:29 CEST 2023
|
||||
|
176
pom.xml
176
pom.xml
@ -60,11 +60,14 @@
|
||||
<!-- Environment properties -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.minimumVersion>3.6.0</maven.minimumVersion>
|
||||
<java.source>1.8</java.source>
|
||||
<java.target>1.8</java.target>
|
||||
<java.apiVersion>8</java.apiVersion>
|
||||
<java.compiler.minimumVersion>11</java.compiler.minimumVersion>
|
||||
<maven.minimumVersion>3.6.3</maven.minimumVersion>
|
||||
|
||||
<!-- Dependencies versions -->
|
||||
<spigot.version>1.18-rc3-R0.1-SNAPSHOT</spigot.version>
|
||||
<spigot.version>1.19.2-R0.1-SNAPSHOT</spigot.version>
|
||||
|
||||
<!-- Versioning properties -->
|
||||
<project.outputName>AuthMe</project.outputName>
|
||||
@ -76,7 +79,7 @@
|
||||
<pluginDescription.name>${project.outputName}</pluginDescription.name>
|
||||
<pluginDescription.version>${project.versionCode}</pluginDescription.version>
|
||||
<pluginDescription.main>${project.groupId}.${project.artifactId}.${pluginDescription.name}</pluginDescription.main>
|
||||
<pluginDescription.authors>sgdc3, ljacqu, games647, Hex3l, krusic22</pluginDescription.authors>
|
||||
<pluginDescription.authors>sgdc3, games647, Hex3l, krusic22</pluginDescription.authors>
|
||||
</properties>
|
||||
|
||||
<!-- Jenkins profile -->
|
||||
@ -151,7 +154,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<version>3.4.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
@ -161,7 +164,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-environment</id>
|
||||
@ -173,6 +176,9 @@
|
||||
<requireMavenVersion>
|
||||
<version>${maven.minimumVersion}</version>
|
||||
</requireMavenVersion>
|
||||
<requireJavaVersion>
|
||||
<version>[11,)</version>
|
||||
</requireJavaVersion>
|
||||
</rules>
|
||||
<fail>true</fail>
|
||||
</configuration>
|
||||
@ -183,29 +189,30 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.0</version>
|
||||
</plugin>
|
||||
<!-- Include resource files -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</plugin>
|
||||
<!-- Compile and include classes -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<source>${java.source}</source>
|
||||
<target>${java.target}</target>
|
||||
<release>${java.apiVersion}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Generate test coverage reports -->
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.7</version>
|
||||
<version>0.8.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
@ -241,7 +248,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</plugin>
|
||||
<!-- Generate a jar containing the source javadoc -->
|
||||
<plugin>
|
||||
@ -282,7 +289,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>3.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>shaded-jar</id>
|
||||
@ -293,7 +300,13 @@
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<!-- Guava -->
|
||||
<exclude>com.google.guava:guava</exclude>
|
||||
<exclude>com.google.guava:failureaccess</exclude>
|
||||
<exclude>com.google.guava:listenablefuture</exclude>
|
||||
<exclude>com.google.errorprone:error_prone_annotations</exclude>
|
||||
<exclude>com.google.j2objc:j2objc-annotations</exclude>
|
||||
<!-- Gson -->
|
||||
<exclude>com.google.code.gson:gson</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
@ -316,6 +329,14 @@
|
||||
<pattern>com.google.thirdparty</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.com.google.thirdparty</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.j2objc</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.com.google.j2objc</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.errorprone</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.com.google.errorprone</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.gson</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.com.google.gson</shadedPattern>
|
||||
@ -365,6 +386,18 @@
|
||||
<pattern>de.rtner</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.de.rtner</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.picketbox</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.org.picketbox</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.jboss.crypto</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.org.jboss.crypto</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.jboss.security</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.org.jboss.security</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>de.mkammerer</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.de.mkammerer</shadedPattern>
|
||||
@ -398,6 +431,10 @@
|
||||
<pattern>com.mysql</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.com.mysql</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.protobuf</pattern>
|
||||
<shadedPattern>fr.xephi.authme.libs.com.google.protobuf</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
|
||||
<filters>
|
||||
@ -430,19 +467,19 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<version>3.0.1</version>
|
||||
</plugin>
|
||||
<!-- Deploy the jars as artifacts into the remote repository -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
<!-- Handle documentation generation, required by other plugins -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.9.1</version>
|
||||
<version>3.12.1</version>
|
||||
</plugin>
|
||||
<!-- Publish coveralls test coverage reports, not included in the build cycle by default -->
|
||||
<plugin>
|
||||
@ -453,6 +490,13 @@
|
||||
<!-- The secret token is provided with a command-line parameter -->
|
||||
<failOnServiceError>false</failOnServiceError>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
@ -496,8 +540,8 @@
|
||||
|
||||
<!-- EssentialsX Repo -->
|
||||
<repository>
|
||||
<id>enderzone-repo</id>
|
||||
<url>https://ci.ender.zone/plugin/repository/everything/</url>
|
||||
<id>essentialsx-repo</id>
|
||||
<url>https://repo.essentialsx.net/releases/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
@ -605,7 +649,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.5</version>
|
||||
<version>2.8.1</version> <!-- Log4J version bundled in 1.12.2 -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -613,7 +657,7 @@
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>4.0.3</version>
|
||||
<version>4.0.3</version> <!-- Latest java 8 release -->
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -626,7 +670,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.32</version>
|
||||
<version>1.7.36</version> <!-- We can't update to 2.x as long as we use HikariCP for java 8 -->
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@ -640,15 +684,15 @@
|
||||
|
||||
<!-- MySQL connector, shaded into the legacy jar -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.26</version>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.0.33</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>2.7.4</version>
|
||||
<version>3.1.4</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@ -689,18 +733,24 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Keep in sync with spigot 1.18 -->
|
||||
<!-- Keep in sync with spigot 1.19 -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.0.1-jre</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Keep in sync with spigot 1.18 -->
|
||||
<!-- Keep in sync with spigot 1.19 -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.8</version>
|
||||
<version>2.8.9</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@ -710,7 +760,7 @@
|
||||
<dependency>
|
||||
<groupId>ch.jalu</groupId>
|
||||
<artifactId>configme</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.4.0</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -724,7 +774,7 @@
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<version>3.0.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@ -732,7 +782,7 @@
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.7.0</version>
|
||||
<version>4.8.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -743,6 +793,10 @@
|
||||
<artifactId>BukkitExecutors</artifactId>
|
||||
<groupId>com.comphenix.executors</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
@ -750,7 +804,7 @@
|
||||
<dependency>
|
||||
<groupId>net.luckperms</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>5.3</version>
|
||||
<version>5.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -869,9 +923,9 @@
|
||||
|
||||
<!-- EssentialsX plugin -->
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<groupId>net.essentialsx</groupId>
|
||||
<artifactId>EssentialsX</artifactId>
|
||||
<version>2.16.1</version>
|
||||
<version>2.20.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -879,32 +933,40 @@
|
||||
<artifactId>paperlib</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>NMSProvider</artifactId>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>UpdatedMetaProvider</artifactId>
|
||||
<groupId>net.essentialsx</groupId>
|
||||
<artifactId>BaseProviders</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R1Provider</artifactId>
|
||||
<groupId>net.essentialsx</groupId>
|
||||
<artifactId>PaperProvider</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R2Provider</artifactId>
|
||||
<groupId>net.essentialsx</groupId>
|
||||
<artifactId>NMSReflectionProvider</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>LegacyProvider</artifactId>
|
||||
<groupId>net.essentialsx</groupId>
|
||||
<artifactId>1_8Provider</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>ReflectionProvider</artifactId>
|
||||
<groupId>net.essentialsx</groupId>
|
||||
<artifactId>1_12Provider</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>FlattenedProvider</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>configurate-yaml</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
@ -935,8 +997,14 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.3.1</version>
|
||||
<version>42.6.0</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Unit Testing Libraries -->
|
||||
@ -965,7 +1033,7 @@
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>4.1.0</version>
|
||||
<version>4.8.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
@ -984,7 +1052,7 @@
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>3.20.0</version>
|
||||
<version>3.26.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@ -992,13 +1060,13 @@
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.36.0.3</version>
|
||||
<version>3.42.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>2.1.210</version>
|
||||
<version>2.2.220</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@ -217,7 +218,7 @@ public class AuthMeApi {
|
||||
* @return true if player is registered, false otherwise
|
||||
*/
|
||||
public boolean isRegistered(String playerName) {
|
||||
String player = playerName.toLowerCase();
|
||||
String player = playerName.toLowerCase(Locale.ROOT);
|
||||
return dataSource.isAuthAvailable(player);
|
||||
}
|
||||
|
||||
@ -241,7 +242,7 @@ public class AuthMeApi {
|
||||
* @return true if the player was registered successfully
|
||||
*/
|
||||
public boolean registerPlayer(String playerName, String password) {
|
||||
String name = playerName.toLowerCase();
|
||||
String name = playerName.toLowerCase(Locale.ROOT);
|
||||
if (isRegistered(name)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -226,8 +226,8 @@ public class CommandDescription {
|
||||
*/
|
||||
public CommandDescription build() {
|
||||
checkArgument(!Utils.isCollectionEmpty(labels), "Labels may not be empty");
|
||||
checkArgument(!StringUtils.isEmpty(description), "Description may not be empty");
|
||||
checkArgument(!StringUtils.isEmpty(detailedDescription), "Detailed description may not be empty");
|
||||
checkArgument(!StringUtils.isBlank(description), "Description may not be empty");
|
||||
checkArgument(!StringUtils.isBlank(detailedDescription), "Detailed description may not be empty");
|
||||
checkArgument(executableCommand != null, "Executable command must be set");
|
||||
// parents and permissions may be null; arguments may be empty
|
||||
|
||||
|
@ -131,7 +131,7 @@ public class CommandHandler {
|
||||
private static List<String> skipEmptyArguments(String[] args) {
|
||||
List<String> cleanArguments = new ArrayList<>();
|
||||
for (String argument : args) {
|
||||
if (!StringUtils.isEmpty(argument)) {
|
||||
if (!StringUtils.isBlank(argument)) {
|
||||
cleanArguments.add(argument);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static fr.xephi.authme.command.FoundResultStatus.INCORRECT_ARGUMENTS;
|
||||
@ -130,7 +131,7 @@ public class CommandMapper {
|
||||
}
|
||||
|
||||
private CommandDescription getBaseCommand(String label) {
|
||||
String baseLabel = label.toLowerCase();
|
||||
String baseLabel = label.toLowerCase(Locale.ROOT);
|
||||
if (baseLabel.startsWith("authme:")) {
|
||||
baseLabel = baseLabel.substring("authme:".length());
|
||||
}
|
||||
@ -157,7 +158,7 @@ public class CommandMapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String label = parts.get(0).toLowerCase();
|
||||
final String label = parts.get(0).toLowerCase(Locale.ROOT);
|
||||
final int argumentCount = parts.size() - 1;
|
||||
|
||||
for (CommandDescription child : baseCommand.getChildren()) {
|
||||
|
@ -10,6 +10,7 @@ import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Shows all accounts registered by the same IP address for the given player name or IP address.
|
||||
@ -44,7 +45,7 @@ public class AccountsCommand implements ExecutableCommand {
|
||||
});
|
||||
} else {
|
||||
bukkitService.runTaskAsynchronously(() -> {
|
||||
PlayerAuth auth = dataSource.getAuth(playerName.toLowerCase());
|
||||
PlayerAuth auth = dataSource.getAuth(playerName.toLowerCase(Locale.ROOT));
|
||||
if (auth == null) {
|
||||
commonService.send(sender, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
|
@ -22,6 +22,7 @@ import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -71,7 +72,7 @@ public class ConverterCommand implements ExecutableCommand {
|
||||
private static Class<? extends Converter> getConverterClassFromArgs(List<String> arguments) {
|
||||
return arguments.isEmpty()
|
||||
? null
|
||||
: CONVERTERS.get(arguments.get(0).toLowerCase());
|
||||
: CONVERTERS.get(arguments.get(0).toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -29,7 +30,7 @@ public class PurgeBannedPlayersCommand implements ExecutableCommand {
|
||||
Set<OfflinePlayer> bannedPlayers = bukkitService.getBannedPlayers();
|
||||
Set<String> namedBanned = new HashSet<>(bannedPlayers.size());
|
||||
for (OfflinePlayer offlinePlayer : bannedPlayers) {
|
||||
namedBanned.add(offlinePlayer.getName().toLowerCase());
|
||||
namedBanned.add(offlinePlayer.getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
purgeService.purgePlayers(sender, namedBanned, bannedPlayers.toArray(new OfflinePlayer[bannedPlayers.size()]));
|
||||
|
@ -5,8 +5,6 @@ import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -23,18 +21,15 @@ public class PurgeLastPositionCommand implements ExecutableCommand {
|
||||
@Inject
|
||||
private CommonService commonService;
|
||||
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
|
||||
|
||||
if ("*".equals(playerName)) {
|
||||
for (PlayerAuth auth : dataSource.getAllAuths()) {
|
||||
resetLastPosition(auth);
|
||||
dataSource.updateQuitLoc(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_QUITLOC, playerName);
|
||||
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
||||
}
|
||||
sender.sendMessage("All players last position locations are now reset");
|
||||
} else {
|
||||
@ -47,7 +42,7 @@ public class PurgeLastPositionCommand implements ExecutableCommand {
|
||||
|
||||
resetLastPosition(auth);
|
||||
dataSource.updateQuitLoc(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_QUITLOC, playerName);
|
||||
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
||||
sender.sendMessage(playerName + "'s last position location is now reset");
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@ -36,7 +37,7 @@ public class PurgePlayerCommand implements ExecutableCommand {
|
||||
private void executeCommand(CommandSender sender, String name, String option) {
|
||||
if ("force".equals(option) || !dataSource.isAuthAvailable(name)) {
|
||||
OfflinePlayer offlinePlayer = bukkitService.getOfflinePlayer(name);
|
||||
purgeExecutor.executePurge(singletonList(offlinePlayer), singletonList(name.toLowerCase()));
|
||||
purgeExecutor.executePurge(singletonList(offlinePlayer), singletonList(name.toLowerCase(Locale.ROOT)));
|
||||
sender.sendMessage("Purged data for player " + name);
|
||||
} else {
|
||||
sender.sendMessage("This player is still registered! Are you sure you want to proceed? "
|
||||
|
@ -17,6 +17,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Admin command to register a user.
|
||||
@ -45,7 +46,7 @@ public class RegisterAdminCommand implements ExecutableCommand {
|
||||
// Get the player name and password
|
||||
final String playerName = arguments.get(0);
|
||||
final String playerPass = arguments.get(1);
|
||||
final String playerNameLowerCase = playerName.toLowerCase();
|
||||
final String playerNameLowerCase = playerName.toLowerCase(Locale.ROOT);
|
||||
|
||||
// Command logic
|
||||
ValidationResult passwordValidation = validationService.validatePassword(playerPass, playerName);
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
@ -45,7 +46,7 @@ public class DebugCommand implements ExecutableCommand {
|
||||
if (arguments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return getSections().get(arguments.get(0).toLowerCase());
|
||||
return getSections().get(arguments.get(0).toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
private void sendAvailableSections(CommandSender sender) {
|
||||
|
@ -89,7 +89,7 @@ class PlayerAuthViewer implements DebugSection {
|
||||
* or empty string if the string is null or empty
|
||||
*/
|
||||
private static String safeSubstring(String str, int length) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return "";
|
||||
} else if (str.length() < length) {
|
||||
return str.substring(0, str.length() / 2) + "...";
|
||||
|
@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* The command for a player to change his password with.
|
||||
@ -35,7 +36,7 @@ public class ChangePasswordCommand extends PlayerCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
|
||||
if (!playerCache.isAuthenticated(name)) {
|
||||
commonService.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
|
@ -31,7 +31,7 @@ public class UnregisterCommand extends PlayerCommand {
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
String playerPass = arguments.get(0);
|
||||
final String playerName = player.getName();
|
||||
String playerName = player.getName();
|
||||
|
||||
// Make sure the player is authenticated
|
||||
if (!playerCache.isAuthenticated(playerName)) {
|
||||
|
@ -4,6 +4,7 @@ import fr.xephi.authme.initialization.HasCleanup;
|
||||
import fr.xephi.authme.util.expiring.ExpiringSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ProxySessionManager implements HasCleanup {
|
||||
@ -21,7 +22,7 @@ public class ProxySessionManager implements HasCleanup {
|
||||
* @param name the player's name
|
||||
*/
|
||||
private void setActiveSession(String name) {
|
||||
activeProxySessions.add(name.toLowerCase());
|
||||
activeProxySessions.add(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -82,7 +83,7 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||
* @return true if the player has been verified, false otherwise
|
||||
*/
|
||||
private boolean isPlayerVerified(String name) {
|
||||
return verifiedPlayers.contains(name.toLowerCase());
|
||||
return verifiedPlayers.contains(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,7 +93,7 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||
* @return true if the code exists, false otherwise
|
||||
*/
|
||||
public boolean hasCode(String name) {
|
||||
return (verificationCodes.get(name.toLowerCase()) != null);
|
||||
return (verificationCodes.get(name.toLowerCase(Locale.ROOT)) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,7 +136,7 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||
final String email = emailResult.getValue();
|
||||
if (!Utils.isEmailEmpty(email)) {
|
||||
String code = RandomStringUtils.generateNum(6); // 6 digits code
|
||||
verificationCodes.put(name.toLowerCase(), code);
|
||||
verificationCodes.put(name.toLowerCase(Locale.ROOT), code);
|
||||
emailService.sendVerificationMail(name, email, code);
|
||||
}
|
||||
}
|
||||
@ -150,7 +151,7 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||
*/
|
||||
public boolean checkCode(String name, String code) {
|
||||
boolean correct = false;
|
||||
if (code.equals(verificationCodes.get(name.toLowerCase()))) {
|
||||
if (code.equals(verificationCodes.get(name.toLowerCase(Locale.ROOT)))) {
|
||||
verify(name);
|
||||
correct = true;
|
||||
}
|
||||
@ -163,7 +164,7 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||
* @param name the name of the player to generate a code for
|
||||
*/
|
||||
public void verify(String name) {
|
||||
verifiedPlayers.add(name.toLowerCase());
|
||||
verifiedPlayers.add(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,7 +173,7 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||
* @param name the name of the player to generate a code for
|
||||
*/
|
||||
public void unverify(String name){
|
||||
verifiedPlayers.remove(name.toLowerCase());
|
||||
verifiedPlayers.remove(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,6 +3,7 @@ package fr.xephi.authme.data.auth;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -54,7 +55,7 @@ public class PlayerAuth {
|
||||
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname.toLowerCase();
|
||||
this.nickname = nickname.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
@ -239,7 +240,7 @@ public class PlayerAuth {
|
||||
*/
|
||||
public PlayerAuth build() {
|
||||
PlayerAuth auth = new PlayerAuth();
|
||||
auth.nickname = checkNotNull(name).toLowerCase();
|
||||
auth.nickname = checkNotNull(name).toLowerCase(Locale.ROOT);
|
||||
auth.realName = Optional.ofNullable(realName).orElse("Player");
|
||||
auth.password = Optional.ofNullable(password).orElse(new HashedPassword(""));
|
||||
auth.totpKey = totpKey;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.xephi.authme.data.auth;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -20,7 +21,7 @@ public class PlayerCache {
|
||||
* @param auth the player auth object to save
|
||||
*/
|
||||
public void updatePlayer(PlayerAuth auth) {
|
||||
cache.put(auth.getNickname().toLowerCase(), auth);
|
||||
cache.put(auth.getNickname().toLowerCase(Locale.ROOT), auth);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,7 +30,7 @@ public class PlayerCache {
|
||||
* @param user name of the player to remove
|
||||
*/
|
||||
public void removePlayer(String user) {
|
||||
cache.remove(user.toLowerCase());
|
||||
cache.remove(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,7 +41,7 @@ public class PlayerCache {
|
||||
* @return true if player is logged in, false otherwise.
|
||||
*/
|
||||
public boolean isAuthenticated(String user) {
|
||||
return cache.containsKey(user.toLowerCase());
|
||||
return cache.containsKey(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,7 +52,7 @@ public class PlayerCache {
|
||||
* @return the associated auth object, or null if not available
|
||||
*/
|
||||
public PlayerAuth getAuth(String user) {
|
||||
return cache.get(user.toLowerCase());
|
||||
return cache.get(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ package fr.xephi.authme.data.captcha;
|
||||
import fr.xephi.authme.util.RandomStringUtils;
|
||||
import fr.xephi.authme.util.expiring.ExpiringMap;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -51,7 +52,7 @@ public class CaptchaCodeStorage {
|
||||
* @return the code the player is required to enter
|
||||
*/
|
||||
public String getCodeOrGenerateNew(String name) {
|
||||
String code = captchaCodes.get(name.toLowerCase());
|
||||
String code = captchaCodes.get(name.toLowerCase(Locale.ROOT));
|
||||
return code == null ? generateCode(name) : code;
|
||||
}
|
||||
|
||||
@ -63,7 +64,7 @@ public class CaptchaCodeStorage {
|
||||
*/
|
||||
private String generateCode(String name) {
|
||||
String code = RandomStringUtils.generate(captchaLength);
|
||||
captchaCodes.put(name.toLowerCase(), code);
|
||||
captchaCodes.put(name.toLowerCase(Locale.ROOT), code);
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -76,7 +77,7 @@ public class CaptchaCodeStorage {
|
||||
* @return true if the code matches, false otherwise
|
||||
*/
|
||||
public boolean checkCode(String name, String code) {
|
||||
String nameLowerCase = name.toLowerCase();
|
||||
String nameLowerCase = name.toLowerCase(Locale.ROOT);
|
||||
String savedCode = captchaCodes.get(nameLowerCase);
|
||||
if (savedCode != null && savedCode.equalsIgnoreCase(code)) {
|
||||
captchaCodes.remove(nameLowerCase);
|
||||
|
@ -8,6 +8,7 @@ import fr.xephi.authme.util.expiring.TimedCounter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -36,14 +37,14 @@ public class LoginCaptchaManager implements CaptchaManager, SettingsDependent, H
|
||||
*/
|
||||
public void increaseLoginFailureCount(String name) {
|
||||
if (isEnabled) {
|
||||
String playerLower = name.toLowerCase();
|
||||
String playerLower = name.toLowerCase(Locale.ROOT);
|
||||
playerCounts.increment(playerLower);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaptchaRequired(String playerName) {
|
||||
return isEnabled && playerCounts.get(playerName.toLowerCase()) >= threshold;
|
||||
return isEnabled && playerCounts.get(playerName.toLowerCase(Locale.ROOT)) >= threshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -53,7 +54,7 @@ public class LoginCaptchaManager implements CaptchaManager, SettingsDependent, H
|
||||
|
||||
@Override
|
||||
public boolean checkCode(Player player, String code) {
|
||||
String nameLower = player.getName().toLowerCase();
|
||||
String nameLower = player.getName().toLowerCase(Locale.ROOT);
|
||||
boolean isCodeCorrect = captchaCodeStorage.checkCode(nameLower, code);
|
||||
if (isCodeCorrect) {
|
||||
playerCounts.remove(nameLower);
|
||||
@ -68,7 +69,7 @@ public class LoginCaptchaManager implements CaptchaManager, SettingsDependent, H
|
||||
*/
|
||||
public void resetLoginFailureCount(String name) {
|
||||
if (isEnabled) {
|
||||
playerCounts.remove(name.toLowerCase());
|
||||
playerCounts.remove(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import fr.xephi.authme.util.expiring.ExpiringSet;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -31,7 +32,7 @@ public class RegistrationCaptchaManager implements CaptchaManager, SettingsDepen
|
||||
|
||||
@Override
|
||||
public boolean isCaptchaRequired(String name) {
|
||||
return isEnabled && !verifiedNamesForRegistration.contains(name.toLowerCase());
|
||||
return isEnabled && !verifiedNamesForRegistration.contains(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,7 +42,7 @@ public class RegistrationCaptchaManager implements CaptchaManager, SettingsDepen
|
||||
|
||||
@Override
|
||||
public boolean checkCode(Player player, String code) {
|
||||
String nameLower = player.getName().toLowerCase();
|
||||
String nameLower = player.getName().toLowerCase(Locale.ROOT);
|
||||
boolean isCodeCorrect = captchaCodeStorage.checkCode(nameLower, code);
|
||||
if (isCodeCorrect) {
|
||||
verifiedNamesForRegistration.add(nameLower);
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -55,7 +56,7 @@ public class LimboService {
|
||||
* @param isRegistered whether or not the player is registered
|
||||
*/
|
||||
public void createLimboPlayer(Player player, boolean isRegistered) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
final String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
|
||||
LimboPlayer limboFromDisk = persistence.getLimboPlayer(player);
|
||||
if (limboFromDisk != null) {
|
||||
@ -89,7 +90,7 @@ public class LimboService {
|
||||
* @return the associated limbo player, or null if none available
|
||||
*/
|
||||
public LimboPlayer getLimboPlayer(String name) {
|
||||
return entries.get(name.toLowerCase());
|
||||
return entries.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +100,7 @@ public class LimboService {
|
||||
* @return true if present, false otherwise
|
||||
*/
|
||||
public boolean hasLimboPlayer(String name) {
|
||||
return entries.containsKey(name.toLowerCase());
|
||||
return entries.containsKey(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +112,7 @@ public class LimboService {
|
||||
* @param player the player whose data should be restored
|
||||
*/
|
||||
public void restoreData(Player player) {
|
||||
String lowerName = player.getName().toLowerCase();
|
||||
String lowerName = player.getName().toLowerCase(Locale.ROOT);
|
||||
LimboPlayer limbo = entries.remove(lowerName);
|
||||
|
||||
if (limbo == null) {
|
||||
@ -178,7 +179,7 @@ public class LimboService {
|
||||
* @return Optional with the limbo player
|
||||
*/
|
||||
private Optional<LimboPlayer> getLimboOrLogError(Player player, String context) {
|
||||
LimboPlayer limbo = entries.get(player.getName().toLowerCase());
|
||||
LimboPlayer limbo = entries.get(player.getName().toLowerCase(Locale.ROOT));
|
||||
if (limbo == null) {
|
||||
logger.debug("No LimboPlayer found for `{0}`. Action: {1}", player.getName(), context);
|
||||
}
|
||||
|
@ -167,4 +167,6 @@ public abstract class AbstractSqlDataSource implements DataSource {
|
||||
return DataSourceValueImpl.unknownRow();
|
||||
}
|
||||
}
|
||||
|
||||
abstract String getJdbcUrl(String host, String port, String database);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import fr.xephi.authme.util.Utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -86,7 +87,7 @@ public class CacheDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public HashedPassword getPassword(String user) {
|
||||
user = user.toLowerCase();
|
||||
user = user.toLowerCase(Locale.ROOT);
|
||||
Optional<PlayerAuth> pAuthOpt = cachedAuths.getIfPresent(user);
|
||||
if (pAuthOpt != null && pAuthOpt.isPresent()) {
|
||||
return pAuthOpt.get().getPassword();
|
||||
@ -96,7 +97,7 @@ public class CacheDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public PlayerAuth getAuth(String user) {
|
||||
user = user.toLowerCase();
|
||||
user = user.toLowerCase(Locale.ROOT);
|
||||
return cachedAuths.getUnchecked(user).orElse(null);
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ public class CacheDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public boolean updatePassword(String user, HashedPassword password) {
|
||||
user = user.toLowerCase();
|
||||
user = user.toLowerCase(Locale.ROOT);
|
||||
boolean result = source.updatePassword(user, password);
|
||||
if (result) {
|
||||
cachedAuths.refresh(user);
|
||||
@ -153,7 +154,7 @@ public class CacheDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public boolean removeAuth(String name) {
|
||||
name = name.toLowerCase();
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
boolean result = source.removeAuth(name);
|
||||
if (result) {
|
||||
cachedAuths.invalidate(name);
|
||||
@ -210,12 +211,12 @@ public class CacheDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public void setLogged(final String user) {
|
||||
source.setLogged(user.toLowerCase());
|
||||
source.setLogged(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnlogged(final String user) {
|
||||
source.setUnlogged(user.toLowerCase());
|
||||
source.setUnlogged(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,6 +7,8 @@ public enum DataSourceType {
|
||||
|
||||
MYSQL,
|
||||
|
||||
MARIADB,
|
||||
|
||||
POSTGRESQL,
|
||||
|
||||
SQLITE
|
||||
|
27
src/main/java/fr/xephi/authme/datasource/MariaDB.java
Normal file
27
src/main/java/fr/xephi/authme/datasource/MariaDB.java
Normal file
@ -0,0 +1,27 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MariaDB extends MySQL {
|
||||
public MariaDB(Settings settings, MySqlExtensionsFactory extensionsFactory) throws SQLException {
|
||||
super(settings, extensionsFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getJdbcUrl(String host, String port, String database) {
|
||||
return "jdbc:mariadb://" + host + ":" + port + "/" + database;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDriverClassName() {
|
||||
return "org.mariadb.jdbc.Driver";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceType getType() {
|
||||
return DataSourceType.MARIADB;
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -39,11 +40,11 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
|
||||
private boolean useSsl;
|
||||
private boolean serverCertificateVerification;
|
||||
private boolean allowPublicKeyRetrieval;
|
||||
private String host;
|
||||
private String port;
|
||||
private String username;
|
||||
private String password;
|
||||
private String className;
|
||||
private String database;
|
||||
private String tableName;
|
||||
private int poolSize;
|
||||
@ -89,6 +90,15 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
setParameters(settings, extensionsFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path of the Driver class to use when connecting to the database.
|
||||
*
|
||||
* @return the dotted path of the SQL driver class to be used
|
||||
*/
|
||||
protected String getDriverClassName() {
|
||||
return "com.mysql.cj.jdbc.Driver";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves various settings.
|
||||
*
|
||||
@ -100,14 +110,6 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT);
|
||||
this.username = settings.getProperty(DatabaseSettings.MYSQL_USERNAME);
|
||||
this.password = settings.getProperty(DatabaseSettings.MYSQL_PASSWORD);
|
||||
this.className = settings.getProperty(DatabaseSettings.MYSQL_DRIVER_CLASS_NAME);
|
||||
try {
|
||||
Class.forName(this.className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
this.className = DatabaseSettings.MYSQL_DRIVER_CLASS_NAME.getDefaultValue();
|
||||
logger.info("Driver class '" + this.className + "' not found! Falling back to the built-in MySQL driver ("
|
||||
+ this.className + ")");
|
||||
}
|
||||
this.database = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
|
||||
this.tableName = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
|
||||
this.columnOthers = settings.getProperty(HooksSettings.MYSQL_OTHER_USERNAME_COLS);
|
||||
@ -118,6 +120,7 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
this.maxLifetime = settings.getProperty(DatabaseSettings.MYSQL_CONNECTION_MAX_LIFETIME);
|
||||
this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL);
|
||||
this.serverCertificateVerification = settings.getProperty(DatabaseSettings.MYSQL_CHECK_SERVER_CERTIFICATE);
|
||||
this.allowPublicKeyRetrieval = settings.getProperty(DatabaseSettings.MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,14 +135,14 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
ds.setMaxLifetime(maxLifetime * 1000L);
|
||||
|
||||
// Database URL
|
||||
ds.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database);
|
||||
ds.setJdbcUrl(this.getJdbcUrl(this.host, this.port, this.database));
|
||||
|
||||
// Auth
|
||||
ds.setUsername(this.username);
|
||||
ds.setPassword(this.password);
|
||||
|
||||
// Driver
|
||||
ds.setDriverClassName(this.className);
|
||||
ds.setDriverClassName(this.getDriverClassName());
|
||||
|
||||
// Request mysql over SSL
|
||||
ds.addDataSourceProperty("useSSL", String.valueOf(useSsl));
|
||||
@ -147,6 +150,9 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
// Disabling server certificate verification on need
|
||||
if (!serverCertificateVerification) {
|
||||
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
|
||||
} // Disabling server certificate verification on need
|
||||
if (allowPublicKeyRetrieval) {
|
||||
ds.addDataSourceProperty("allowPublicKeyRetrieval", String.valueOf(true));
|
||||
}
|
||||
|
||||
// Encoding
|
||||
@ -294,7 +300,7 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
}
|
||||
|
||||
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {
|
||||
try (ResultSet rs = metaData.getColumns(null, null, tableName, columnName)) {
|
||||
try (ResultSet rs = metaData.getColumns(database, null, tableName, columnName)) {
|
||||
return !rs.next();
|
||||
}
|
||||
}
|
||||
@ -304,7 +310,7 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
String sql = "SELECT * FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
PlayerAuth auth;
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, user.toLowerCase());
|
||||
pst.setString(1, user.toLowerCase(Locale.ROOT));
|
||||
try (ResultSet rs = pst.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
@ -343,6 +349,11 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getJdbcUrl(String host, String port, String database) {
|
||||
return "jdbc:mysql://" + host + ":" + port + "/" + database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRecordsToPurge(long until) {
|
||||
Set<String> list = new HashSet<>();
|
||||
@ -367,11 +378,11 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
|
||||
@Override
|
||||
public boolean removeAuth(String user) {
|
||||
user = user.toLowerCase();
|
||||
user = user.toLowerCase(Locale.ROOT);
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
sqlExtension.removeAuth(user, con);
|
||||
pst.setString(1, user.toLowerCase());
|
||||
pst.setString(1, user.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException ex) {
|
||||
@ -392,7 +403,7 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
for (String name : toPurge) {
|
||||
pst.setString(1, name.toLowerCase());
|
||||
pst.setString(1, name.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -460,7 +471,7 @@ public class MySQL extends AbstractSqlDataSource {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.TOTP_KEY + " = ? WHERE " + col.NAME + " = ?";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, totpKey);
|
||||
pst.setString(2, user.toLowerCase());
|
||||
pst.setString(2, user.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
|
@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
|
||||
@ -119,7 +120,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
|
||||
// Database URL
|
||||
ds.setDriverClassName("org.postgresql.Driver");
|
||||
ds.setJdbcUrl("jdbc:postgresql://" + this.host + ":" + this.port + "/" + this.database);
|
||||
ds.setJdbcUrl(this.getJdbcUrl(this.host, this.port, this.database));
|
||||
|
||||
// Auth
|
||||
ds.setUsername(this.username);
|
||||
@ -257,7 +258,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
}
|
||||
|
||||
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {
|
||||
try (ResultSet rs = metaData.getColumns(null, null, tableName, columnName.toLowerCase())) {
|
||||
try (ResultSet rs = metaData.getColumns(null, null, tableName, columnName.toLowerCase(Locale.ROOT))) {
|
||||
return !rs.next();
|
||||
}
|
||||
}
|
||||
@ -267,7 +268,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
String sql = "SELECT * FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
PlayerAuth auth;
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, user.toLowerCase());
|
||||
pst.setString(1, user.toLowerCase(Locale.ROOT));
|
||||
try (ResultSet rs = pst.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
int id = rs.getInt(col.ID);
|
||||
@ -306,6 +307,11 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getJdbcUrl(String host, String port, String database) {
|
||||
return "jdbc:postgresql://" + host + ":" + port + "/" + database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRecordsToPurge(long until) {
|
||||
Set<String> list = new HashSet<>();
|
||||
@ -330,11 +336,11 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
|
||||
@Override
|
||||
public boolean removeAuth(String user) {
|
||||
user = user.toLowerCase();
|
||||
user = user.toLowerCase(Locale.ROOT);
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
sqlExtension.removeAuth(user, con);
|
||||
pst.setString(1, user.toLowerCase());
|
||||
pst.setString(1, user.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException ex) {
|
||||
@ -355,7 +361,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
for (String name : toPurge) {
|
||||
pst.setString(1, name.toLowerCase());
|
||||
pst.setString(1, name.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -423,7 +429,7 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.TOTP_KEY + " = ? WHERE " + col.NAME + " = ?";
|
||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, totpKey);
|
||||
pst.setString(2, user.toLowerCase());
|
||||
pst.setString(2, user.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
|
||||
@ -88,7 +89,7 @@ public class SQLite extends AbstractSqlDataSource {
|
||||
}
|
||||
|
||||
logger.debug("SQLite driver loaded");
|
||||
this.con = DriverManager.getConnection("jdbc:sqlite:" + this.dataFolder + File.separator + database + ".db");
|
||||
this.con = DriverManager.getConnection(this.getJdbcUrl(this.dataFolder.getAbsolutePath(), "", this.database));
|
||||
this.columnsHandler = AuthMeColumnsHandler.createForSqlite(con, settings);
|
||||
}
|
||||
|
||||
@ -268,7 +269,7 @@ public class SQLite extends AbstractSqlDataSource {
|
||||
String delete = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (PreparedStatement deletePst = con.prepareStatement(delete)) {
|
||||
for (String name : toPurge) {
|
||||
deletePst.setString(1, name.toLowerCase());
|
||||
deletePst.setString(1, name.toLowerCase(Locale.ROOT));
|
||||
deletePst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -280,7 +281,7 @@ public class SQLite extends AbstractSqlDataSource {
|
||||
public boolean removeAuth(String user) {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, user.toLowerCase());
|
||||
pst.setString(1, user.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException ex) {
|
||||
@ -355,7 +356,7 @@ public class SQLite extends AbstractSqlDataSource {
|
||||
String sql = "UPDATE " + tableName + " SET " + col.TOTP_KEY + " = ? WHERE " + col.NAME + " = ?";
|
||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||
pst.setString(1, totpKey);
|
||||
pst.setString(2, user.toLowerCase());
|
||||
pst.setString(2, user.toLowerCase(Locale.ROOT));
|
||||
pst.executeUpdate();
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
@ -405,6 +406,11 @@ public class SQLite extends AbstractSqlDataSource {
|
||||
+ currentTimestamp + ", to all " + updatedRows + " rows");
|
||||
}
|
||||
|
||||
@Override
|
||||
String getJdbcUrl(String dataPath, String ignored, String database) {
|
||||
return "jdbc:sqlite:" + dataPath + File.separator + database + ".db";
|
||||
}
|
||||
|
||||
private static void close(Connection con) {
|
||||
if (con != null) {
|
||||
try {
|
||||
|
@ -14,6 +14,7 @@ import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static ch.jalu.datasourcecolumns.sqlimplementation.SqlColumnsHandlerConfig.forConnectionPool;
|
||||
import static ch.jalu.datasourcecolumns.sqlimplementation.SqlColumnsHandlerConfig.forSingleConnection;
|
||||
@ -78,7 +79,7 @@ public final class AuthMeColumnsHandler {
|
||||
*/
|
||||
public <T> boolean update(String name, DataSourceColumn<T> column, T value) {
|
||||
try {
|
||||
return internalHandler.update(name.toLowerCase(), column, value);
|
||||
return internalHandler.update(name.toLowerCase(Locale.ROOT), column, value);
|
||||
} catch (SQLException e) {
|
||||
logSqlException(e);
|
||||
return false;
|
||||
@ -110,7 +111,7 @@ public final class AuthMeColumnsHandler {
|
||||
*/
|
||||
public boolean update(String name, UpdateValues<ColumnContext> updateValues) {
|
||||
try {
|
||||
return internalHandler.update(name.toLowerCase(), updateValues);
|
||||
return internalHandler.update(name.toLowerCase(Locale.ROOT), updateValues);
|
||||
} catch (SQLException e) {
|
||||
logSqlException(e);
|
||||
return false;
|
||||
@ -145,7 +146,7 @@ public final class AuthMeColumnsHandler {
|
||||
* @throws SQLException .
|
||||
*/
|
||||
public <T> DataSourceValue<T> retrieve(String name, DataSourceColumn<T> column) throws SQLException {
|
||||
return internalHandler.retrieve(name.toLowerCase(), column);
|
||||
return internalHandler.retrieve(name.toLowerCase(Locale.ROOT), column);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,7 +158,7 @@ public final class AuthMeColumnsHandler {
|
||||
* @throws SQLException .
|
||||
*/
|
||||
public DataSourceValues retrieve(String name, DataSourceColumn<?>... columns) throws SQLException {
|
||||
return internalHandler.retrieve(name.toLowerCase(), columns);
|
||||
return internalHandler.retrieve(name.toLowerCase(Locale.ROOT), columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,6 +14,7 @@ import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Converter for CrazyLogin to AuthMe.
|
||||
@ -70,7 +71,7 @@ public class CrazyLoginConverter implements Converter {
|
||||
String password = args[1];
|
||||
if (password != null) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(playerName.toLowerCase())
|
||||
.name(playerName.toLowerCase(Locale.ROOT))
|
||||
.realName(playerName)
|
||||
.password(password, null)
|
||||
.build();
|
||||
|
@ -12,6 +12,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.util.FileUtils.makePath;
|
||||
|
||||
@ -35,7 +36,7 @@ public class RoyalAuthConverter implements Converter {
|
||||
public void execute(CommandSender sender) {
|
||||
for (OfflinePlayer player : plugin.getServer().getOfflinePlayers()) {
|
||||
try {
|
||||
String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
File file = new File(makePath(".", "plugins", "RoyalAuth", "userdata", name + ".yml"));
|
||||
|
||||
if (dataSource.isAuthAvailable(name) || !file.exists()) {
|
||||
|
@ -12,6 +12,7 @@ import org.bukkit.command.CommandSender;
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -48,12 +49,12 @@ public class VAuthConverter implements Converter {
|
||||
continue;
|
||||
}
|
||||
auth = PlayerAuth.builder()
|
||||
.name(pname.toLowerCase())
|
||||
.name(pname.toLowerCase(Locale.ROOT))
|
||||
.realName(pname)
|
||||
.password(password, null).build();
|
||||
} else {
|
||||
auth = PlayerAuth.builder()
|
||||
.name(name.toLowerCase())
|
||||
.name(name.toLowerCase(Locale.ROOT))
|
||||
.realName(name)
|
||||
.password(password, null).build();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.util.FileUtils.makePath;
|
||||
|
||||
@ -66,7 +67,7 @@ public class XAuthConverter implements Converter {
|
||||
String psw = getPassword(id);
|
||||
if (psw != null && !psw.isEmpty() && pl != null) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(pl.toLowerCase())
|
||||
.name(pl.toLowerCase(Locale.ROOT))
|
||||
.realName(pl)
|
||||
.password(psw, null).build();
|
||||
database.saveAuth(auth);
|
||||
@ -89,7 +90,7 @@ public class XAuthConverter implements Converter {
|
||||
if (!rs.next()) {
|
||||
return null;
|
||||
}
|
||||
realPass = rs.getString("playername").toLowerCase();
|
||||
realPass = rs.getString("playername").toLowerCase(Locale.ROOT);
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve name for account: " + id, e);
|
||||
return null;
|
||||
|
@ -5,6 +5,7 @@ import fr.xephi.authme.data.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.CacheDataSource;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.datasource.MariaDB;
|
||||
import fr.xephi.authme.datasource.MySQL;
|
||||
import fr.xephi.authme.datasource.PostgreSqlDataSource;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
@ -66,6 +67,9 @@ public class DataSourceProvider implements Provider<DataSource> {
|
||||
case MYSQL:
|
||||
dataSource = new MySQL(settings, mySqlExtensionsFactory);
|
||||
break;
|
||||
case MARIADB:
|
||||
dataSource = new MariaDB(settings, mySqlExtensionsFactory);
|
||||
break;
|
||||
case POSTGRESQL:
|
||||
dataSource = new PostgreSqlDataSource(settings, mySqlExtensionsFactory);
|
||||
break;
|
||||
|
@ -6,8 +6,6 @@ import fr.xephi.authme.data.limbo.LimboService;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.ValidationService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
@ -16,6 +14,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Saves all players' data when the plugin shuts down.
|
||||
@ -36,8 +35,6 @@ public class OnShutdownPlayerSaver {
|
||||
private PlayerCache playerCache;
|
||||
@Inject
|
||||
private LimboService limboService;
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
OnShutdownPlayerSaver() {
|
||||
}
|
||||
@ -52,7 +49,7 @@ public class OnShutdownPlayerSaver {
|
||||
}
|
||||
|
||||
private void savePlayer(Player player) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
if (PlayerUtils.isNpc(player) || validationService.isUnrestricted(name)) {
|
||||
return;
|
||||
}
|
||||
@ -67,12 +64,12 @@ public class OnShutdownPlayerSaver {
|
||||
private void saveLoggedinPlayer(Player player) {
|
||||
if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||
Location loc = spawnLoader.getPlayerLocationOrSpawn(player);
|
||||
final PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(player.getName().toLowerCase())
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(player.getName().toLowerCase(Locale.ROOT))
|
||||
.realName(player.getName())
|
||||
.location(loc).build();
|
||||
dataSource.updateQuitLoc(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_QUITLOC, player.getName());
|
||||
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@ -159,8 +160,8 @@ public class OnJoinVerifier implements Reloadable {
|
||||
if (auth != null && settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)) {
|
||||
String realName = auth.getRealName(); // might be null or "Player"
|
||||
|
||||
if (StringUtils.isEmpty(realName) || "Player".equals(realName)) {
|
||||
dataSource.updateRealName(connectingName.toLowerCase(), connectingName);
|
||||
if (StringUtils.isBlank(realName) || "Player".equals(realName)) {
|
||||
dataSource.updateRealName(connectingName.toLowerCase(Locale.ROOT), connectingName);
|
||||
} else if (!realName.equals(connectingName)) {
|
||||
throw new FailedVerificationException(MessageKey.INVALID_NAME_CASE, realName, connectingName);
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_MOVEMENT_RADIUS;
|
||||
@ -214,7 +215,7 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
String joinMsg = event.getJoinMessage();
|
||||
|
||||
// Remove the join message while the player isn't logging in
|
||||
@ -292,7 +293,7 @@ public class PlayerListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
String cmd = event.getMessage().split(" ")[0].toLowerCase();
|
||||
String cmd = event.getMessage().split(" ")[0].toLowerCase(Locale.ROOT);
|
||||
if (settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD) && "/motd".equals(cmd)) {
|
||||
return;
|
||||
}
|
||||
@ -482,7 +483,7 @@ public class PlayerListener implements Listener {
|
||||
return false;
|
||||
}
|
||||
Set<String> whitelist = settings.getProperty(RestrictionSettings.UNRESTRICTED_INVENTORIES);
|
||||
return whitelist.contains(ChatColor.stripColor(inventory.getTitle()).toLowerCase());
|
||||
return whitelist.contains(ChatColor.stripColor(inventory.getTitle()).toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
|
@ -51,11 +51,11 @@ public class SendMailSsl {
|
||||
* @throws EmailException if the mail is invalid
|
||||
*/
|
||||
public HtmlEmail initializeMail(String emailAddress) throws EmailException {
|
||||
String senderMail = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_ADDRESS))
|
||||
String senderMail = StringUtils.isBlank(settings.getProperty(EmailSettings.MAIL_ADDRESS))
|
||||
? settings.getProperty(EmailSettings.MAIL_ACCOUNT)
|
||||
: settings.getProperty(EmailSettings.MAIL_ADDRESS);
|
||||
|
||||
String senderName = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_SENDER_NAME))
|
||||
String senderName = StringUtils.isBlank(settings.getProperty(EmailSettings.MAIL_SENDER_NAME))
|
||||
? senderMail
|
||||
: settings.getProperty(EmailSettings.MAIL_SENDER_NAME);
|
||||
String mailPassword = settings.getProperty(EmailSettings.MAIL_PASSWORD);
|
||||
|
@ -5,6 +5,7 @@ import ch.jalu.configme.properties.Property;
|
||||
import ch.jalu.configme.properties.convertresult.PropertyValue;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.message.updater.MessageUpdater.MessageKeyProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -39,15 +40,19 @@ public class MessageKeyConfigurationData extends ConfigurationDataImpl {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Property<String>> getAllMessageProperties() {
|
||||
public List<MessageKeyProperty> getAllMessageProperties() {
|
||||
return (List) getProperties();
|
||||
}
|
||||
|
||||
public String getMessage(MessageKey messageKey) {
|
||||
return getValue(new MessageUpdater.MessageKeyProperty(messageKey));
|
||||
return getValue(new MessageKeyProperty(messageKey));
|
||||
}
|
||||
|
||||
public String getMessage(MessageKeyProperty property) {
|
||||
return (String) getValues().get(property.getPath());
|
||||
}
|
||||
|
||||
public void setMessage(MessageKey messageKey, String message) {
|
||||
setValue(new MessageUpdater.MessageKeyProperty(messageKey), message);
|
||||
setValue(new MessageKeyProperty(messageKey), message);
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ import ch.jalu.configme.exception.ConfigMeException;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -36,8 +36,8 @@ final class MessageMigraterPropertyReader implements PropertyReader {
|
||||
* @param file the file to load
|
||||
* @return the created property reader
|
||||
*/
|
||||
public static MessageMigraterPropertyReader loadFromFile(File file) {
|
||||
try (InputStream is = new FileInputStream(file)) {
|
||||
public static MessageMigraterPropertyReader loadFromFile(Path file) {
|
||||
try (InputStream is = Files.newInputStream(file)) {
|
||||
return loadFromStream(is);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error while reading file '" + file + "'", e);
|
||||
|
@ -2,7 +2,6 @@ package fr.xephi.authme.message.updater;
|
||||
|
||||
import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.configurationdata.PropertyListBuilder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import ch.jalu.configme.properties.StringProperty;
|
||||
import ch.jalu.configme.properties.convertresult.ConvertErrorRecorder;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
@ -10,8 +9,8 @@ import ch.jalu.configme.resource.PropertyResource;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
@ -102,9 +101,9 @@ public class MessageUpdater {
|
||||
|
||||
private boolean addMissingKeys(JarMessageSource jarMessageSource, MessageKeyConfigurationData configurationData) {
|
||||
List<String> addedKeys = new ArrayList<>();
|
||||
for (Property<String> property : configurationData.getAllMessageProperties()) {
|
||||
for (MessageKeyProperty property : configurationData.getAllMessageProperties()) {
|
||||
final String key = property.getPath();
|
||||
if (configurationData.getValue(property) == null) {
|
||||
if (configurationData.getMessage(property) == null) {
|
||||
configurationData.setValue(property, jarMessageSource.getMessageFromJar(property));
|
||||
addedKeys.add(key);
|
||||
}
|
||||
|
@ -2,8 +2,14 @@ package fr.xephi.authme.message.updater;
|
||||
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
import ch.jalu.configme.resource.YamlFileResource;
|
||||
import ch.jalu.configme.resource.yaml.SnakeYamlNodeBuilder;
|
||||
import ch.jalu.configme.resource.yaml.SnakeYamlNodeBuilderImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
import org.yaml.snakeyaml.nodes.ScalarNode;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -12,28 +18,43 @@ import java.io.File;
|
||||
*/
|
||||
public class MigraterYamlFileResource extends YamlFileResource {
|
||||
|
||||
private Yaml singleQuoteYaml;
|
||||
|
||||
public MigraterYamlFileResource(File file) {
|
||||
super(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyReader createReader() {
|
||||
return MessageMigraterPropertyReader.loadFromFile(getFile());
|
||||
return MessageMigraterPropertyReader.loadFromFile(getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Yaml createNewYaml() {
|
||||
if (singleQuoteYaml == null) {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setAllowUnicode(true);
|
||||
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
|
||||
// Overridden setting: don't split lines
|
||||
options.setSplitLines(false);
|
||||
singleQuoteYaml = new Yaml(options);
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setAllowUnicode(true);
|
||||
options.setProcessComments(true);
|
||||
options.setIndent(4);
|
||||
// Overridden setting: don't split lines
|
||||
options.setSplitLines(false);
|
||||
return new Yaml(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull SnakeYamlNodeBuilder createNodeBuilder() {
|
||||
return new MigraterYamlNodeBuilder();
|
||||
}
|
||||
|
||||
/** Extended to represent all strings with single quotes in the YAML. */
|
||||
private static final class MigraterYamlNodeBuilder extends SnakeYamlNodeBuilderImpl {
|
||||
|
||||
@Override
|
||||
protected @NotNull Node createStringNode(@NotNull String value) {
|
||||
return new ScalarNode(Tag.STR, value, null, null, DumperOptions.ScalarStyle.SINGLE_QUOTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Node createKeyNode(@NotNull String key) {
|
||||
return super.createStringNode(key); // no single quotes
|
||||
}
|
||||
return singleQuoteYaml;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import fr.xephi.authme.util.StringUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Service class for the log filters.
|
||||
@ -35,7 +36,7 @@ final class LogFilterHelper {
|
||||
if (message == null) {
|
||||
return false;
|
||||
}
|
||||
String lowerMessage = message.toLowerCase();
|
||||
String lowerMessage = message.toLowerCase(Locale.ROOT);
|
||||
return lowerMessage.contains(ISSUED_COMMAND_TEXT) && StringUtils.containsAny(lowerMessage, COMMANDS_TO_SKIP);
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ public class PermissionsManager implements Reloadable {
|
||||
* False is also returned if this feature isn't supported for the current permissions system.
|
||||
*/
|
||||
public boolean addGroup(OfflinePlayer player, UserGroup groupName) {
|
||||
if (!isEnabled() || StringUtils.isEmpty(groupName.getGroupName())) {
|
||||
if (!isEnabled() || StringUtils.isBlank(groupName.getGroupName())) {
|
||||
return false;
|
||||
}
|
||||
return handler.addToGroup(player, groupName);
|
||||
|
@ -10,12 +10,11 @@ import fr.xephi.authme.process.AsynchronousProcess;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
public class AsyncChangePassword implements AsynchronousProcess {
|
||||
|
||||
@ -33,9 +32,6 @@ public class AsyncChangePassword implements AsynchronousProcess {
|
||||
@Inject
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
AsyncChangePassword() {
|
||||
}
|
||||
|
||||
@ -46,8 +42,8 @@ public class AsyncChangePassword implements AsynchronousProcess {
|
||||
* @param oldPassword the old password used by the player
|
||||
* @param newPassword the new password chosen by the player
|
||||
*/
|
||||
public void changePassword(final Player player, String oldPassword, String newPassword) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
public void changePassword(Player player, String oldPassword, String newPassword) {
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
PlayerAuth auth = playerCache.getAuth(name);
|
||||
if (passwordSecurity.comparePassword(oldPassword, auth.getPassword(), player.getName())) {
|
||||
HashedPassword hashedPassword = passwordSecurity.computeHash(newPassword, name);
|
||||
@ -57,7 +53,8 @@ public class AsyncChangePassword implements AsynchronousProcess {
|
||||
commonService.send(player, MessageKey.ERROR);
|
||||
return;
|
||||
}
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_PASSWORD, name);
|
||||
|
||||
// TODO: send an update when a messaging service will be implemented (PASSWORD_CHANGED)
|
||||
|
||||
playerCache.updatePlayer(auth);
|
||||
commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS);
|
||||
@ -74,8 +71,8 @@ public class AsyncChangePassword implements AsynchronousProcess {
|
||||
* @param playerName the player name
|
||||
* @param newPassword the new password chosen for the player
|
||||
*/
|
||||
public void changePasswordAsAdmin(CommandSender sender, final String playerName, String newPassword) {
|
||||
final String lowerCaseName = playerName.toLowerCase();
|
||||
public void changePasswordAsAdmin(CommandSender sender, String playerName, String newPassword) {
|
||||
String lowerCaseName = playerName.toLowerCase(Locale.ROOT);
|
||||
if (!(playerCache.isAuthenticated(lowerCaseName) || dataSource.isAuthAvailable(lowerCaseName))) {
|
||||
if (sender == null) {
|
||||
logger.warning("Tried to change password for user " + lowerCaseName + " but it doesn't exist!");
|
||||
@ -87,7 +84,8 @@ public class AsyncChangePassword implements AsynchronousProcess {
|
||||
|
||||
HashedPassword hashedPassword = passwordSecurity.computeHash(newPassword, lowerCaseName);
|
||||
if (dataSource.updatePassword(lowerCaseName, hashedPassword)) {
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_PASSWORD, lowerCaseName);
|
||||
// TODO: send an update when a messaging service will be implemented (PASSWORD_CHANGED)
|
||||
|
||||
if (sender != null) {
|
||||
commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
|
||||
logger.info(sender.getName() + " changed password of " + lowerCaseName);
|
||||
|
@ -11,12 +11,11 @@ import fr.xephi.authme.process.AsynchronousProcess;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.ValidationService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Async task to add an email to an account.
|
||||
@ -37,9 +36,6 @@ public class AsyncAddEmail implements AsynchronousProcess {
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@ -53,11 +49,11 @@ public class AsyncAddEmail implements AsynchronousProcess {
|
||||
* @param email the email to add
|
||||
*/
|
||||
public void addEmail(Player player, String email) {
|
||||
String playerName = player.getName().toLowerCase();
|
||||
String playerName = player.getName().toLowerCase(Locale.ROOT);
|
||||
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
PlayerAuth auth = playerCache.getAuth(playerName);
|
||||
final String currentEmail = auth.getEmail();
|
||||
String currentEmail = auth.getEmail();
|
||||
|
||||
if (!Utils.isEmailEmpty(currentEmail)) {
|
||||
service.send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
@ -76,7 +72,7 @@ public class AsyncAddEmail implements AsynchronousProcess {
|
||||
auth.setEmail(email);
|
||||
if (dataSource.updateEmail(auth)) {
|
||||
playerCache.updatePlayer(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_EMAIL, playerName);
|
||||
// TODO: send an update when a messaging service will be implemented (ADD_MAIL)
|
||||
service.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
} else {
|
||||
logger.warning("Could not save email for player '" + player + "'");
|
||||
|
@ -11,11 +11,10 @@ import fr.xephi.authme.process.AsynchronousProcess;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.ValidationService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Async task for changing the email.
|
||||
@ -36,9 +35,6 @@ public class AsyncChangeEmail implements AsynchronousProcess {
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@ -53,10 +49,10 @@ public class AsyncChangeEmail implements AsynchronousProcess {
|
||||
* @param newEmail provided new email
|
||||
*/
|
||||
public void changeEmail(Player player, String oldEmail, String newEmail) {
|
||||
String playerName = player.getName().toLowerCase();
|
||||
String playerName = player.getName().toLowerCase(Locale.ROOT);
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
PlayerAuth auth = playerCache.getAuth(playerName);
|
||||
final String currentEmail = auth.getEmail();
|
||||
String currentEmail = auth.getEmail();
|
||||
|
||||
if (currentEmail == null) {
|
||||
service.send(player, MessageKey.USAGE_ADD_EMAIL);
|
||||
@ -94,7 +90,7 @@ public class AsyncChangeEmail implements AsynchronousProcess {
|
||||
auth.setEmail(newEmail);
|
||||
if (dataSource.updateEmail(auth)) {
|
||||
playerCache.updatePlayer(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_EMAIL, player.getName());
|
||||
// TODO: send an update when a messaging service will be implemented (CHANGE_MAIL)
|
||||
service.send(player, MessageKey.EMAIL_CHANGED_SUCCESS);
|
||||
} else {
|
||||
service.send(player, MessageKey.ERROR);
|
||||
|
@ -32,6 +32,8 @@ import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||
|
||||
@ -89,9 +91,14 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
||||
*
|
||||
* @param player the player to process
|
||||
*/
|
||||
public void processJoin(final Player player) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
final String ip = PlayerUtils.getPlayerIp(player);
|
||||
public void processJoin(Player player) {
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
|
||||
if (!validationService.fulfillsNameRestrictions(player)) {
|
||||
handlePlayerWithUnmetNameRestriction(player, ip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (service.getProperty(RestrictionSettings.UNRESTRICTED_NAMES).contains(name)) {
|
||||
return;
|
||||
@ -107,16 +114,11 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
||||
pluginHookService.setEssentialsSocialSpyStatus(player, false);
|
||||
}
|
||||
|
||||
if (!validationService.fulfillsNameRestrictions(player)) {
|
||||
handlePlayerWithUnmetNameRestriction(player, ip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validatePlayerCountForIp(player, ip)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean isAuthAvailable = database.isAuthAvailable(name);
|
||||
boolean isAuthAvailable = database.isAuthAvailable(name);
|
||||
|
||||
if (isAuthAvailable) {
|
||||
// Protect inventory
|
||||
@ -153,7 +155,13 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
||||
});
|
||||
|
||||
// Skip if registration is optional
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.LOGIN, name);
|
||||
|
||||
if (bungeeSender.isEnabled()) {
|
||||
// As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/
|
||||
// "Keep in mind that you can't send plugin messages directly after a player joins."
|
||||
bukkitService.scheduleSyncDelayedTask(() ->
|
||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -177,7 +185,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
||||
* @param isAuthAvailable true if the player is registered, false otherwise
|
||||
*/
|
||||
private void processJoinSync(Player player, boolean isAuthAvailable) {
|
||||
final int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
|
||||
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
|
||||
limboService.createLimboPlayer(player, isAuthAvailable);
|
||||
@ -204,7 +212,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
||||
*
|
||||
* @return true if the verification is OK (no infraction), false if player has been kicked
|
||||
*/
|
||||
private boolean validatePlayerCountForIp(final Player player, String ip) {
|
||||
private boolean validatePlayerCountForIp(Player player, String ip) {
|
||||
if (service.getProperty(RestrictionSettings.MAX_JOIN_PER_IP) > 0
|
||||
&& !service.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
&& !InternetProtocolUtils.isLoopbackAddress(ip)
|
||||
|
@ -40,6 +40,7 @@ import org.bukkit.entity.Player;
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Asynchronous task for a player login.
|
||||
@ -153,7 +154,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
* (e.g. because he is already logged in)
|
||||
*/
|
||||
private PlayerAuth getPlayerAuth(Player player, boolean quiet) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
if (playerCache.isAuthenticated(name)) {
|
||||
if (!quiet) {
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
@ -179,7 +180,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String ip = PlayerUtils.getPlayerIp(player);
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
if (hasReachedMaxLoggedInPlayersForIp(player, ip)) {
|
||||
if (!quiet) {
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
@ -206,7 +207,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
* false otherwise
|
||||
*/
|
||||
private boolean checkPlayerInfo(Player player, PlayerAuth auth, String password) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
|
||||
// If captcha is required send a message to the player and deny to log in
|
||||
if (loginCaptchaManager.isCaptchaRequired(name)) {
|
||||
@ -214,7 +215,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String ip = PlayerUtils.getPlayerIp(player);
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
|
||||
// Increase the counts here before knowing the result of the login.
|
||||
loginCaptchaManager.increaseLoginFailureCount(name);
|
||||
@ -266,18 +267,19 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
*/
|
||||
public void performLogin(Player player, PlayerAuth auth) {
|
||||
if (player.isOnline()) {
|
||||
final boolean isFirstLogin = (auth.getLastLogin() == null);
|
||||
boolean isFirstLogin = (auth.getLastLogin() == null);
|
||||
|
||||
// Update auth to reflect this new login
|
||||
final String ip = PlayerUtils.getPlayerIp(player);
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
auth.setRealName(player.getName());
|
||||
auth.setLastLogin(System.currentTimeMillis());
|
||||
auth.setLastIp(ip);
|
||||
dataSource.updateSession(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_SESSION, player.getName());
|
||||
|
||||
// TODO: send an update when a messaging service will be implemented (SESSION)
|
||||
|
||||
// Successful login, so reset the captcha & temp ban count
|
||||
final String name = player.getName();
|
||||
String name = player.getName();
|
||||
loginCaptchaManager.resetLoginFailureCount(name);
|
||||
tempbanManager.resetCount(ip, name);
|
||||
player.setNoDamageTicks(0);
|
||||
@ -288,7 +290,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
List<String> auths = dataSource.getAllAuthsByIp(auth.getLastIp());
|
||||
displayOtherAccounts(auths, player);
|
||||
|
||||
final String email = auth.getEmail();
|
||||
String email = auth.getEmail();
|
||||
if (service.getProperty(EmailSettings.RECALL_PLAYERS) && Utils.isEmailEmpty(email)) {
|
||||
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
@ -299,7 +301,13 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
playerCache.updatePlayer(auth);
|
||||
dataSource.setLogged(name);
|
||||
sessionService.grantSession(name);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.LOGIN, name);
|
||||
|
||||
if (bungeeSender.isEnabled()) {
|
||||
// As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/
|
||||
// "Keep in mind that you can't send plugin messages directly after a player joins."
|
||||
bukkitService.scheduleSyncDelayedTask(() ->
|
||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
|
||||
}
|
||||
|
||||
// As the scheduling executes the Task most likely after the current
|
||||
// task, we schedule it in the end
|
||||
@ -368,12 +376,12 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
||||
}
|
||||
|
||||
// Count logged in players with same IP address
|
||||
final String name = player.getName();
|
||||
String name = player.getName();
|
||||
int count = 0;
|
||||
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
|
||||
if (ip.equalsIgnoreCase(PlayerUtils.getPlayerIp(onlinePlayer))
|
||||
&& !onlinePlayer.getName().equals(name)
|
||||
&& dataSource.isLogged(onlinePlayer.getName().toLowerCase())) {
|
||||
&& dataSource.isLogged(onlinePlayer.getName().toLowerCase(Locale.ROOT))) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||
|
||||
@ -76,7 +77,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
||||
* @param authsWithSameIp registered names with the same IP address as the player's
|
||||
*/
|
||||
public void processPlayerLogin(Player player, boolean isFirstLogin, List<String> authsWithSameIp) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
final String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
final LimboPlayer limbo = limboService.getLimboPlayer(name);
|
||||
|
||||
// Limbo contains the State of the Player before /login
|
||||
|
@ -15,6 +15,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Async task when a player wants to log out.
|
||||
@ -51,7 +52,7 @@ public class AsynchronousLogout implements AsynchronousProcess {
|
||||
* @param player the player wanting to log out
|
||||
*/
|
||||
public void logout(Player player) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
if (!playerCache.isAuthenticated(name)) {
|
||||
service.send(player, MessageKey.NOT_LOGGED_IN);
|
||||
return;
|
||||
@ -59,18 +60,18 @@ public class AsynchronousLogout implements AsynchronousProcess {
|
||||
|
||||
PlayerAuth auth = playerCache.getAuth(name);
|
||||
database.updateSession(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_SESSION, name);
|
||||
// TODO: send an update when a messaging service will be implemented (SESSION)
|
||||
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||
auth.setQuitLocation(player.getLocation());
|
||||
database.updateQuitLoc(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_QUITLOC, name);
|
||||
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
||||
}
|
||||
|
||||
playerCache.removePlayer(name);
|
||||
codeManager.unverify(name);
|
||||
database.setUnlogged(name);
|
||||
sessionService.revokeSession(name);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.LOGOUT, name);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT);
|
||||
syncProcessManager.processSyncPlayerLogout(player);
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ import fr.xephi.authme.process.SyncProcessManager;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.SessionService;
|
||||
import fr.xephi.authme.service.ValidationService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import fr.xephi.authme.settings.SpawnLoader;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
@ -20,6 +18,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Async process called when a player quits the server.
|
||||
@ -53,9 +52,6 @@ public class AsynchronousQuit implements AsynchronousProcess {
|
||||
@Inject
|
||||
private SessionService sessionService;
|
||||
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
AsynchronousQuit() {
|
||||
}
|
||||
|
||||
@ -68,8 +64,8 @@ public class AsynchronousQuit implements AsynchronousProcess {
|
||||
if (player == null || validationService.isUnrestricted(player.getName())) {
|
||||
return;
|
||||
}
|
||||
final String name = player.getName().toLowerCase();
|
||||
final boolean wasLoggedIn = playerCache.isAuthenticated(name);
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
boolean wasLoggedIn = playerCache.isAuthenticated(name);
|
||||
|
||||
if (wasLoggedIn) {
|
||||
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||
@ -80,7 +76,7 @@ public class AsynchronousQuit implements AsynchronousProcess {
|
||||
database.updateQuitLoc(auth);
|
||||
}
|
||||
|
||||
final String ip = PlayerUtils.getPlayerIp(player);
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(name)
|
||||
.realName(player.getName())
|
||||
@ -88,7 +84,8 @@ public class AsynchronousQuit implements AsynchronousProcess {
|
||||
.lastLogin(System.currentTimeMillis())
|
||||
.build();
|
||||
database.updateSession(auth);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REFRESH_QUITLOC, name);
|
||||
|
||||
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
||||
}
|
||||
|
||||
//always unauthenticate the player - use session only for auto logins on the same ip
|
||||
|
@ -12,8 +12,6 @@ import fr.xephi.authme.process.register.executors.RegistrationMethod;
|
||||
import fr.xephi.authme.process.register.executors.RegistrationParameters;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.InternetProtocolUtils;
|
||||
@ -22,6 +20,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.permission.PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS;
|
||||
|
||||
@ -40,8 +39,6 @@ public class AsyncRegister implements AsynchronousProcess {
|
||||
private CommonService service;
|
||||
@Inject
|
||||
private SingletonStore<RegistrationExecutor> registrationExecutorFactory;
|
||||
@Inject
|
||||
private BungeeSender bungeeSender;
|
||||
|
||||
AsyncRegister() {
|
||||
}
|
||||
@ -71,7 +68,7 @@ public class AsyncRegister implements AsynchronousProcess {
|
||||
* @return true if the checks are successful and the event hasn't marked the action as denied, false otherwise.
|
||||
*/
|
||||
private boolean preRegisterCheck(RegistrationMethod<?> variant, Player player) {
|
||||
final String name = player.getName().toLowerCase();
|
||||
String name = player.getName().toLowerCase(Locale.ROOT);
|
||||
if (playerCache.isAuthenticated(name)) {
|
||||
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return false;
|
||||
@ -104,7 +101,6 @@ public class AsyncRegister implements AsynchronousProcess {
|
||||
PlayerAuth auth = executor.buildPlayerAuth(parameters);
|
||||
if (database.saveAuth(auth)) {
|
||||
executor.executePostPersistAction(parameters);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.REGISTER, parameters.getPlayerName());
|
||||
} else {
|
||||
service.send(parameters.getPlayer(), MessageKey.ERROR);
|
||||
}
|
||||
@ -118,8 +114,8 @@ public class AsyncRegister implements AsynchronousProcess {
|
||||
* @return true if registration may take place, false otherwise (IP check failed)
|
||||
*/
|
||||
private boolean isPlayerIpAllowedToRegister(Player player) {
|
||||
final int maxRegPerIp = service.getProperty(RestrictionSettings.MAX_REGISTRATION_PER_IP);
|
||||
final String ip = PlayerUtils.getPlayerIp(player);
|
||||
int maxRegPerIp = service.getProperty(RestrictionSettings.MAX_REGISTRATION_PER_IP);
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
if (maxRegPerIp > 0
|
||||
&& !InternetProtocolUtils.isLoopbackAddress(ip)
|
||||
&& !service.hasPermission(player, ALLOW_MULTIPLE_ACCOUNTS)) {
|
||||
|
@ -5,6 +5,8 @@ import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.util.PlayerUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Helper for constructing PlayerAuth objects.
|
||||
*/
|
||||
@ -23,7 +25,7 @@ final class PlayerAuthBuilderHelper {
|
||||
*/
|
||||
static PlayerAuth createPlayerAuth(Player player, HashedPassword hashedPassword, String email) {
|
||||
return PlayerAuth.builder()
|
||||
.name(player.getName().toLowerCase())
|
||||
.name(player.getName().toLowerCase(Locale.ROOT))
|
||||
.realName(player.getName())
|
||||
.password(hashedPassword)
|
||||
.email(email)
|
||||
|
@ -14,11 +14,11 @@ import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.CommonService;
|
||||
import fr.xephi.authme.service.TeleportationService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
@ -70,8 +70,8 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
||||
* @param password the input password to check before unregister
|
||||
*/
|
||||
public void unregister(Player player, String password) {
|
||||
final String name = player.getName();
|
||||
final PlayerAuth cachedAuth = playerCache.getAuth(name);
|
||||
String name = player.getName();
|
||||
PlayerAuth cachedAuth = playerCache.getAuth(name);
|
||||
if (passwordSecurity.comparePassword(password, cachedAuth.getPassword(), name)) {
|
||||
if (dataSource.removeAuth(name)) {
|
||||
performPostUnregisterActions(name, player);
|
||||
@ -117,8 +117,12 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
||||
* @param player the according Player object (nullable)
|
||||
*/
|
||||
private void performPostUnregisterActions(String name, Player player) {
|
||||
if (player != null && playerCache.isAuthenticated(name)) {
|
||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT);
|
||||
}
|
||||
playerCache.removePlayer(name);
|
||||
bungeeSender.sendAuthMeBungeecordMessage(MessageType.UNREGISTER, name);
|
||||
|
||||
// TODO: send an update when a messaging service will be implemented (UNREGISTER)
|
||||
|
||||
if (player == null || !player.isOnline()) {
|
||||
return;
|
||||
@ -137,7 +141,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
||||
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||
}
|
||||
|
||||
private void applyBlindEffect(final Player player) {
|
||||
private void applyBlindEffect(Player player) {
|
||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||
int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
|
||||
|
@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Manager class for password-related operations.
|
||||
@ -54,7 +55,7 @@ public class PasswordSecurity implements Reloadable {
|
||||
* @return The password hash
|
||||
*/
|
||||
public HashedPassword computeHash(String password, String playerName) {
|
||||
String playerLowerCase = playerName.toLowerCase();
|
||||
String playerLowerCase = playerName.toLowerCase(Locale.ROOT);
|
||||
return encryptionMethod.computeHash(password, playerLowerCase);
|
||||
}
|
||||
|
||||
@ -81,7 +82,7 @@ public class PasswordSecurity implements Reloadable {
|
||||
* @return True if the password matches, false otherwise
|
||||
*/
|
||||
public boolean comparePassword(String password, HashedPassword hashedPassword, String playerName) {
|
||||
String playerLowerCase = playerName.toLowerCase();
|
||||
String playerLowerCase = playerName.toLowerCase(Locale.ROOT);
|
||||
return methodMatches(encryptionMethod, password, hashedPassword, playerLowerCase)
|
||||
|| compareWithLegacyHashes(password, hashedPassword, playerLowerCase);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import fr.xephi.authme.security.crypts.description.SaltType;
|
||||
import fr.xephi.authme.security.crypts.description.Usage;
|
||||
import fr.xephi.authme.util.RandomStringUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.security.HashUtils.isEqual;
|
||||
|
||||
/**
|
||||
@ -29,7 +31,7 @@ public class Smf implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String computeHash(String password, String salt, String name) {
|
||||
return HashUtils.sha1(name.toLowerCase() + password);
|
||||
return HashUtils.sha1(name.toLowerCase(Locale.ROOT) + password);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,6 +3,8 @@ package fr.xephi.authme.security.crypts;
|
||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||
import fr.xephi.authme.security.crypts.description.Usage;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.security.HashUtils.isEqual;
|
||||
|
||||
@Recommendation(Usage.RECOMMENDED)
|
||||
@ -19,7 +21,7 @@ public class XAuth extends HexSaltedMethod {
|
||||
|
||||
@Override
|
||||
public String computeHash(String password, String salt, String name) {
|
||||
String hash = getWhirlpool(salt + password).toLowerCase();
|
||||
String hash = getWhirlpool(salt + password).toLowerCase(Locale.ROOT);
|
||||
int saltPos = password.length() >= hash.length() ? hash.length() - 1 : password.length();
|
||||
return hash.substring(0, saltPos) + salt + hash.substring(saltPos);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import fr.xephi.authme.util.expiring.ExpiringMap;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -32,7 +33,7 @@ public class GenerateTotpService implements HasCleanup {
|
||||
*/
|
||||
public TotpGenerationResult generateTotpKey(Player player) {
|
||||
TotpGenerationResult credentials = totpAuthenticator.generateTotpKey(player);
|
||||
totpKeys.put(player.getName().toLowerCase(), credentials);
|
||||
totpKeys.put(player.getName().toLowerCase(Locale.ROOT), credentials);
|
||||
return credentials;
|
||||
}
|
||||
|
||||
@ -43,11 +44,11 @@ public class GenerateTotpService implements HasCleanup {
|
||||
* @return TOTP generation result
|
||||
*/
|
||||
public TotpGenerationResult getGeneratedTotpKey(Player player) {
|
||||
return totpKeys.get(player.getName().toLowerCase());
|
||||
return totpKeys.get(player.getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public void removeGenerateTotpKey(Player player) {
|
||||
totpKeys.remove(player.getName().toLowerCase());
|
||||
totpKeys.remove(player.getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +59,7 @@ public class GenerateTotpService implements HasCleanup {
|
||||
* @return true if the input code is correct, false if the code is invalid or no unexpired totp key is available
|
||||
*/
|
||||
public boolean isTotpCodeCorrectForGeneratedTotpKey(Player player, String totpCode) {
|
||||
TotpGenerationResult totpDetails = totpKeys.get(player.getName().toLowerCase());
|
||||
TotpGenerationResult totpDetails = totpKeys.get(player.getName().toLowerCase(Locale.ROOT));
|
||||
return totpDetails != null && totpAuthenticator.checkCode(player.getName(), totpDetails.getTotpKey(), totpCode);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.util.Utils.MILLIS_PER_MINUTE;
|
||||
|
||||
/**
|
||||
@ -54,7 +56,7 @@ public class TotpAuthenticator implements HasCleanup {
|
||||
* @return true if code is valid, false otherwise
|
||||
*/
|
||||
public boolean checkCode(String playerName, String totpKey, String inputCode) {
|
||||
String nameLower = playerName.toLowerCase();
|
||||
String nameLower = playerName.toLowerCase(Locale.ROOT);
|
||||
Integer totpCode = Ints.tryParse(inputCode);
|
||||
if (totpCode != null && !usedCodes.contains(nameLower, totpCode)
|
||||
&& authenticator.authorize(totpKey, totpCode)) {
|
||||
|
@ -11,6 +11,7 @@ import fr.xephi.authme.util.AtomicIntervalCounter;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE;
|
||||
@ -55,7 +56,7 @@ public class AntiBotService implements SettingsDependent {
|
||||
duration = settings.getProperty(ProtectionSettings.ANTIBOT_DURATION);
|
||||
int sensibility = settings.getProperty(ProtectionSettings.ANTIBOT_SENSIBILITY);
|
||||
int interval = settings.getProperty(ProtectionSettings.ANTIBOT_INTERVAL);
|
||||
flaggedCounter = new AtomicIntervalCounter(sensibility, interval);
|
||||
flaggedCounter = new AtomicIntervalCounter(sensibility, interval * 1000);
|
||||
|
||||
// Stop existing protection
|
||||
stopProtection();
|
||||
@ -176,7 +177,7 @@ public class AntiBotService implements SettingsDependent {
|
||||
* @return true if the given name has been kicked because of Antibot
|
||||
*/
|
||||
public boolean wasPlayerKicked(String name) {
|
||||
return antibotKicked.contains(name.toLowerCase());
|
||||
return antibotKicked.contains(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +187,7 @@ public class AntiBotService implements SettingsDependent {
|
||||
* @param name the name to add
|
||||
*/
|
||||
public void addPlayerKick(String name) {
|
||||
antibotKicked.addIfAbsent(name.toLowerCase());
|
||||
antibotKicked.addIfAbsent(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public enum AntiBotStatus {
|
||||
|
@ -18,6 +18,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.util.Utils.logAndSendMessage;
|
||||
import static fr.xephi.authme.util.Utils.logAndSendWarning;
|
||||
@ -151,7 +152,7 @@ public class BackupService {
|
||||
* @return True if the path is correct, false if it is incorrect or the OS is not Windows
|
||||
*/
|
||||
private boolean useWindowsCommand(String windowsPath) {
|
||||
String isWin = System.getProperty("os.name").toLowerCase();
|
||||
String isWin = System.getProperty("os.name").toLowerCase(Locale.ROOT);
|
||||
if (isWin.contains("win")) {
|
||||
if (new File(windowsPath + "\\bin\\mysqldump.exe").exists()) {
|
||||
return true;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package fr.xephi.authme.service;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
@ -299,19 +298,17 @@ public class BukkitService implements SettingsDependent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the specified message to bungeecord using the first available player connection.
|
||||
* Send the specified bytes to bungeecord using the specified player connection.
|
||||
*
|
||||
* @param player the player
|
||||
* @param bytes the message
|
||||
*/
|
||||
public void sendBungeeMessage(byte[] bytes) {
|
||||
Player player = Iterables.getFirst(getOnlinePlayers(), null);
|
||||
if (player != null) {
|
||||
player.sendPluginMessage(authMe, "BungeeCord", bytes);
|
||||
}
|
||||
public void sendBungeeMessage(Player player, byte[] bytes) {
|
||||
player.sendPluginMessage(authMe, "BungeeCord", bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a ban to the this list. If a previous ban exists, this will
|
||||
* Adds a ban to the list. If a previous ban exists, this will
|
||||
* update the previous entry.
|
||||
*
|
||||
* @param ip the ip of the ban
|
||||
|
@ -38,7 +38,7 @@ public class JoinMessageService {
|
||||
*/
|
||||
public void sendMessage(String playerName) {
|
||||
String joinMessage = joinMessages.remove(playerName);
|
||||
if (!StringUtils.isEmpty(joinMessage)) {
|
||||
if (!StringUtils.isBlank(joinMessage)) {
|
||||
bukkitService.broadcastMessage(joinMessage);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH;
|
||||
@ -76,7 +77,7 @@ public class PasswordRecoveryService implements Reloadable, HasCleanup {
|
||||
boolean couldSendMail = emailService.sendRecoveryCode(player.getName(), email, recoveryCode);
|
||||
if (couldSendMail) {
|
||||
commonService.send(player, MessageKey.RECOVERY_CODE_SENT);
|
||||
emailCooldown.add(player.getName().toLowerCase());
|
||||
emailCooldown.add(player.getName().toLowerCase(Locale.ROOT));
|
||||
} else {
|
||||
commonService.send(player, MessageKey.EMAIL_SEND_FAILURE);
|
||||
}
|
||||
@ -104,7 +105,7 @@ public class PasswordRecoveryService implements Reloadable, HasCleanup {
|
||||
boolean couldSendMail = emailService.sendPasswordMail(name, email, thePass);
|
||||
if (couldSendMail) {
|
||||
commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
|
||||
emailCooldown.add(player.getName().toLowerCase());
|
||||
emailCooldown.add(player.getName().toLowerCase(Locale.ROOT));
|
||||
} else {
|
||||
commonService.send(player, MessageKey.EMAIL_SEND_FAILURE);
|
||||
}
|
||||
@ -141,7 +142,7 @@ public class PasswordRecoveryService implements Reloadable, HasCleanup {
|
||||
* @return True if the player is not on cooldown.
|
||||
*/
|
||||
private boolean checkEmailCooldown(Player player) {
|
||||
Duration waitDuration = emailCooldown.getExpiration(player.getName().toLowerCase());
|
||||
Duration waitDuration = emailCooldown.getExpiration(player.getName().toLowerCase(Locale.ROOT));
|
||||
if (waitDuration.getDuration() > 0) {
|
||||
String durationText = messages.formatDuration(waitDuration);
|
||||
messages.send(player, MessageKey.EMAIL_COOLDOWN_ERROR, durationText);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.xephi.authme.service;
|
||||
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
@ -23,8 +24,10 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -69,7 +72,7 @@ public class ValidationService implements Reloadable {
|
||||
* @return the validation result
|
||||
*/
|
||||
public ValidationResult validatePassword(String password, String username) {
|
||||
String passLow = password.toLowerCase();
|
||||
String passLow = password.toLowerCase(Locale.ROOT);
|
||||
if (!passwordRegex.matcher(passLow).matches()) {
|
||||
return new ValidationResult(MessageKey.PASSWORD_CHARACTERS_ERROR, passwordRegex.pattern());
|
||||
} else if (passLow.equalsIgnoreCase(username)) {
|
||||
@ -139,7 +142,7 @@ public class ValidationService implements Reloadable {
|
||||
* @return true if unrestricted, false otherwise
|
||||
*/
|
||||
public boolean isUnrestricted(String name) {
|
||||
return settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES).contains(name.toLowerCase());
|
||||
return settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES).contains(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,13 +152,13 @@ public class ValidationService implements Reloadable {
|
||||
* @return true if the player may join, false if the player does not satisfy the name restrictions
|
||||
*/
|
||||
public boolean fulfillsNameRestrictions(Player player) {
|
||||
Collection<String> restrictions = restrictedNames.get(player.getName().toLowerCase());
|
||||
Collection<String> restrictions = restrictedNames.get(player.getName().toLowerCase(Locale.ROOT));
|
||||
if (Utils.isCollectionEmpty(restrictions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String ip = PlayerUtils.getPlayerIp(player);
|
||||
String domain = player.getAddress().getHostName();
|
||||
String domain = getHostName(player.getAddress());
|
||||
for (String restriction : restrictions) {
|
||||
if (restriction.startsWith("regex:")) {
|
||||
restriction = restriction.replace("regex:", "");
|
||||
@ -172,6 +175,11 @@ public class ValidationService implements Reloadable {
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected String getHostName(InetSocketAddress inetSocketAddr) {
|
||||
return inetSocketAddr.getHostName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the given value is allowed according to the given whitelist and blacklist settings.
|
||||
* Whitelist has precedence over blacklist: if a whitelist is set, the value is rejected if not present
|
||||
@ -212,7 +220,7 @@ public class ValidationService implements Reloadable {
|
||||
for (String restriction : configuredRestrictions) {
|
||||
if (isInsideString(';', restriction)) {
|
||||
String[] data = restriction.split(";");
|
||||
restrictions.put(data[0].toLowerCase(), data[1]);
|
||||
restrictions.put(data[0].toLowerCase(Locale.ROOT), data[1]);
|
||||
} else {
|
||||
logger.warning("Restricted user rule must have a ';' separating name from restriction,"
|
||||
+ " but found: '" + restriction + "'");
|
||||
|
@ -5,7 +5,6 @@ import com.google.common.io.ByteStreams;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.data.ProxySessionManager;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.process.Management;
|
||||
@ -20,32 +19,32 @@ import javax.inject.Inject;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BungeeReceiver implements PluginMessageListener, SettingsDependent {
|
||||
|
||||
|
||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(BungeeReceiver.class);
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final BukkitService bukkitService;
|
||||
private final ProxySessionManager proxySessionManager;
|
||||
private final Management management;
|
||||
private final DataSource dataSource;
|
||||
|
||||
private boolean isEnabled;
|
||||
|
||||
@Inject
|
||||
BungeeReceiver(AuthMe plugin, BukkitService bukkitService, ProxySessionManager proxySessionManager,
|
||||
Management management, DataSource dataSource, Settings settings) {
|
||||
Management management, Settings settings) {
|
||||
this.plugin = plugin;
|
||||
this.bukkitService = bukkitService;
|
||||
this.proxySessionManager = proxySessionManager;
|
||||
this.management = management;
|
||||
this.dataSource = dataSource;
|
||||
reload(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(final Settings settings) {
|
||||
public void reload(Settings settings) {
|
||||
this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD);
|
||||
|
||||
if (this.isEnabled) {
|
||||
this.isEnabled = bukkitService.isBungeeCordConfiguredForSpigot().orElse(false);
|
||||
}
|
||||
if (this.isEnabled) {
|
||||
final Messenger messenger = plugin.getServer().getMessenger();
|
||||
if (!messenger.isIncomingChannelRegistered(plugin, "BungeeCord")) {
|
||||
@ -59,23 +58,23 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
|
||||
*
|
||||
* @param in the input to handle
|
||||
*/
|
||||
private void handleBroadcast(final ByteArrayDataInput in) {
|
||||
private void handleBroadcast(ByteArrayDataInput in) {
|
||||
// Read data byte array
|
||||
final short dataLength = in.readShort();
|
||||
final byte[] dataBytes = new byte[dataLength];
|
||||
short dataLength = in.readShort();
|
||||
byte[] dataBytes = new byte[dataLength];
|
||||
in.readFully(dataBytes);
|
||||
final ByteArrayDataInput dataIn = ByteStreams.newDataInput(dataBytes);
|
||||
ByteArrayDataInput dataIn = ByteStreams.newDataInput(dataBytes);
|
||||
|
||||
// Parse type
|
||||
final String typeId = dataIn.readUTF();
|
||||
final Optional<MessageType> type = MessageType.fromId(typeId);
|
||||
String typeId = dataIn.readUTF();
|
||||
Optional<MessageType> type = MessageType.fromId(typeId);
|
||||
if (!type.isPresent()) {
|
||||
logger.debug("Received unsupported forwarded bungeecord message type! ({0})", typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse argument
|
||||
final String argument;
|
||||
String argument;
|
||||
try {
|
||||
argument = dataIn.readUTF();
|
||||
} catch (IllegalStateException e) {
|
||||
@ -86,14 +85,9 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
|
||||
|
||||
// Handle type
|
||||
switch (type.get()) {
|
||||
case UNREGISTER:
|
||||
dataSource.invalidateCache(argument);
|
||||
break;
|
||||
case REFRESH_PASSWORD:
|
||||
case REFRESH_QUITLOC:
|
||||
case REFRESH_EMAIL:
|
||||
case REFRESH:
|
||||
dataSource.refreshCache(argument);
|
||||
case LOGIN:
|
||||
case LOGOUT:
|
||||
// TODO: unused
|
||||
break;
|
||||
default:
|
||||
}
|
||||
@ -106,15 +100,15 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
|
||||
*/
|
||||
private void handle(ByteArrayDataInput in) {
|
||||
// Parse type
|
||||
final String typeId = in.readUTF();
|
||||
final Optional<MessageType> type = MessageType.fromId(typeId);
|
||||
String typeId = in.readUTF();
|
||||
Optional<MessageType> type = MessageType.fromId(typeId);
|
||||
if (!type.isPresent()) {
|
||||
logger.debug("Received unsupported bungeecord message type! ({0})", typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse argument
|
||||
final String argument;
|
||||
String argument;
|
||||
try {
|
||||
argument = in.readUTF();
|
||||
} catch (IllegalStateException e) {
|
||||
@ -133,15 +127,15 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(final String channel, final Player player, final byte[] data) {
|
||||
public void onPluginMessageReceived(String channel, Player player, byte[] data) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ByteArrayDataInput in = ByteStreams.newDataInput(data);
|
||||
ByteArrayDataInput in = ByteStreams.newDataInput(data);
|
||||
|
||||
// Check subchannel
|
||||
final String subChannel = in.readUTF();
|
||||
String subChannel = in.readUTF();
|
||||
if ("AuthMe.v2.Broadcast".equals(subChannel)) {
|
||||
handleBroadcast(in);
|
||||
} else if ("AuthMe.v2".equals(subChannel)) {
|
||||
@ -149,7 +143,7 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
|
||||
}
|
||||
}
|
||||
|
||||
private void performLogin(final String name) {
|
||||
private void performLogin(String name) {
|
||||
Player player = bukkitService.getPlayerExact(name);
|
||||
if (player != null && player.isOnline()) {
|
||||
management.forceLogin(player, true);
|
||||
@ -159,7 +153,7 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent
|
||||
proxySessionManager.processProxySessionMessage(name);
|
||||
logger.info("The user " + name + " should be automatically logged in, "
|
||||
+ "as requested via plugin messaging but has not been detected, nickname has been"
|
||||
+" added to autologin queue.");
|
||||
+ " added to autologin queue.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
@ -14,13 +13,13 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.Messenger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
public class BungeeSender implements SettingsDependent {
|
||||
|
||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(BungeeSender.class);
|
||||
private final AuthMe plugin;
|
||||
private final BukkitService bukkitService;
|
||||
private final DataSource dataSource;
|
||||
|
||||
private boolean isEnabled;
|
||||
private String destinationServerOnLogin;
|
||||
@ -29,21 +28,19 @@ public class BungeeSender implements SettingsDependent {
|
||||
* Constructor.
|
||||
*/
|
||||
@Inject
|
||||
BungeeSender(final AuthMe plugin, final BukkitService bukkitService, final DataSource dataSource,
|
||||
final Settings settings) {
|
||||
BungeeSender(AuthMe plugin, BukkitService bukkitService, Settings settings) {
|
||||
this.plugin = plugin;
|
||||
this.bukkitService = bukkitService;
|
||||
this.dataSource = dataSource;
|
||||
reload(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(final Settings settings) {
|
||||
public void reload(Settings settings) {
|
||||
this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD);
|
||||
this.destinationServerOnLogin = settings.getProperty(HooksSettings.BUNGEECORD_SERVER);
|
||||
|
||||
if (this.isEnabled) {
|
||||
final Messenger messenger = plugin.getServer().getMessenger();
|
||||
Messenger messenger = plugin.getServer().getMessenger();
|
||||
if (!messenger.isOutgoingChannelRegistered(plugin, "BungeeCord")) {
|
||||
messenger.registerOutgoingPluginChannel(plugin, "BungeeCord");
|
||||
}
|
||||
@ -54,27 +51,27 @@ public class BungeeSender implements SettingsDependent {
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
private void sendBungeecordMessage(final String... data) {
|
||||
final ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
for (final String element : data) {
|
||||
private void sendBungeecordMessage(Player player, String... data) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
for (String element : data) {
|
||||
out.writeUTF(element);
|
||||
}
|
||||
bukkitService.sendBungeeMessage(out.toByteArray());
|
||||
bukkitService.sendBungeeMessage(player, out.toByteArray());
|
||||
}
|
||||
|
||||
private void sendForwardedBungeecordMessage(final String subChannel, final String... data) {
|
||||
final ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
private void sendForwardedBungeecordMessage(Player player, String subChannel, String... data) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Forward");
|
||||
out.writeUTF("ONLINE");
|
||||
out.writeUTF(subChannel);
|
||||
final ByteArrayDataOutput dataOut = ByteStreams.newDataOutput();
|
||||
for (final String element : data) {
|
||||
ByteArrayDataOutput dataOut = ByteStreams.newDataOutput();
|
||||
for (String element : data) {
|
||||
dataOut.writeUTF(element);
|
||||
}
|
||||
final byte[] dataBytes = dataOut.toByteArray();
|
||||
byte[] dataBytes = dataOut.toByteArray();
|
||||
out.writeShort(dataBytes.length);
|
||||
out.write(dataBytes);
|
||||
bukkitService.sendBungeeMessage(out.toByteArray());
|
||||
bukkitService.sendBungeeMessage(player, out.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,33 +80,33 @@ public class BungeeSender implements SettingsDependent {
|
||||
*
|
||||
* @param player The player to send.
|
||||
*/
|
||||
public void connectPlayerOnLogin(final Player player) {
|
||||
if (isEnabled && !destinationServerOnLogin.isEmpty()) {
|
||||
bukkitService.scheduleSyncDelayedTask(() ->
|
||||
sendBungeecordMessage("ConnectOther", player.getName(), destinationServerOnLogin), 5L);
|
||||
public void connectPlayerOnLogin(Player player) {
|
||||
if (!isEnabled || destinationServerOnLogin.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Add a small delay, just in case...
|
||||
bukkitService.scheduleSyncDelayedTask(() ->
|
||||
sendBungeecordMessage(player, "Connect", destinationServerOnLogin), 10L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the AuthMe plugin messaging channel, if enabled.
|
||||
*
|
||||
* @param player The player related to the message
|
||||
* @param type The message type, See {@link MessageType}
|
||||
* @param playerName the player related to the message
|
||||
*/
|
||||
public void sendAuthMeBungeecordMessage(final MessageType type, final String playerName) {
|
||||
if (isEnabled) {
|
||||
if (!plugin.isEnabled()) {
|
||||
logger.debug("Tried to send a " + type + " bungeecord message but the plugin was disabled!");
|
||||
return;
|
||||
}
|
||||
if (type.isRequiresCaching() && !dataSource.isCached()) {
|
||||
return;
|
||||
}
|
||||
if (type.isBroadcast()) {
|
||||
sendForwardedBungeecordMessage("AuthMe.v2.Broadcast", type.getId(), playerName.toLowerCase());
|
||||
} else {
|
||||
sendBungeecordMessage("AuthMe.v2", type.getId(), playerName.toLowerCase());
|
||||
}
|
||||
public void sendAuthMeBungeecordMessage(Player player, MessageType type) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!plugin.isEnabled()) {
|
||||
logger.debug("Tried to send a " + type + " bungeecord message but the plugin was disabled!");
|
||||
return;
|
||||
}
|
||||
if (type.isBroadcast()) {
|
||||
sendForwardedBungeecordMessage(player, "AuthMe.v2.Broadcast", type.getId(), player.getName().toLowerCase(Locale.ROOT));
|
||||
} else {
|
||||
sendBungeecordMessage(player, "AuthMe.v2", type.getId(), player.getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,29 +3,16 @@ package fr.xephi.authme.service.bungeecord;
|
||||
import java.util.Optional;
|
||||
|
||||
public enum MessageType {
|
||||
REFRESH_PASSWORD("refresh.password", true, true),
|
||||
REFRESH_SESSION("refresh.session", true, true),
|
||||
REFRESH_QUITLOC("refresh.quitloc", true, true),
|
||||
REFRESH_EMAIL("refresh.email", true, true),
|
||||
REFRESH("refresh", true, true),
|
||||
REGISTER("register", true),
|
||||
UNREGISTER("unregister", true),
|
||||
LOGIN("login", true),
|
||||
LOGOUT("logout", true),
|
||||
PERFORM_LOGIN("perform.login", false);
|
||||
|
||||
private final String id;
|
||||
private final boolean broadcast;
|
||||
private final boolean requiresCaching;
|
||||
|
||||
MessageType(final String id, final boolean broadcast, final boolean requiresCaching) {
|
||||
MessageType(String id, boolean broadcast) {
|
||||
this.id = id;
|
||||
this.broadcast = broadcast;
|
||||
this.requiresCaching = requiresCaching;
|
||||
}
|
||||
|
||||
MessageType(final String id, final boolean broadcast) {
|
||||
this(id, broadcast, false);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@ -36,10 +23,6 @@ public enum MessageType {
|
||||
return broadcast;
|
||||
}
|
||||
|
||||
public boolean isRequiresCaching() {
|
||||
return requiresCaching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MessageType with the given ID.
|
||||
*
|
||||
@ -47,8 +30,8 @@ public enum MessageType {
|
||||
*
|
||||
* @return the MessageType with the given id, empty if invalid.
|
||||
*/
|
||||
public static Optional<MessageType> fromId(final String id) {
|
||||
for (final MessageType current : values()) {
|
||||
public static Optional<MessageType> fromId(String id) {
|
||||
for (MessageType current : values()) {
|
||||
if (current.getId().equals(id)) {
|
||||
return Optional.of(current);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import ch.jalu.configme.properties.Property;
|
||||
import ch.jalu.configme.properties.convertresult.PropertyValue;
|
||||
import ch.jalu.configme.resource.PropertyReader;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||
import fr.xephi.authme.output.LogLevel;
|
||||
@ -65,10 +66,10 @@ public class SettingsMigrationService extends PlainMigrationService {
|
||||
configurationData.setValue(ALLOWED_NICKNAME_CHARACTERS, "[a-zA-Z0-9_]*");
|
||||
changes = true;
|
||||
}
|
||||
String driverClass = reader.getString(DatabaseSettings.MYSQL_DRIVER_CLASS_NAME.getPath());
|
||||
if ("com.mysql.jdbc.Driver".equals(driverClass) || "com.mysql.cj.jdbc.Driver".equals(driverClass)) {
|
||||
configurationData.setValue(DatabaseSettings.MYSQL_DRIVER_CLASS_NAME,
|
||||
DatabaseSettings.MYSQL_DRIVER_CLASS_NAME.getDefaultValue());
|
||||
|
||||
String driverClass = reader.getString("DataSource.mySQLDriverClassName");
|
||||
if ("fr.xephi.authme.libs.org.mariadb.jdbc.Driver".equals(driverClass)) {
|
||||
configurationData.setValue(DatabaseSettings.BACKEND, DataSourceType.MARIADB);
|
||||
changes = true;
|
||||
}
|
||||
|
||||
@ -100,7 +101,7 @@ public class SettingsMigrationService extends PlainMigrationService {
|
||||
"settings.restrictions.keepCollisionsDisabled", "settings.forceCommands", "settings.forceCommandsAsConsole",
|
||||
"settings.forceRegisterCommands", "settings.forceRegisterCommandsAsConsole",
|
||||
"settings.sessions.sessionExpireOnIpChange", "settings.restrictions.otherAccountsCmd",
|
||||
"settings.restrictions.otherAccountsCmdThreshold"};
|
||||
"settings.restrictions.otherAccountsCmdThreshold, DataSource.mySQLDriverClassName"};
|
||||
for (String deprecatedPath : deprecatedProperties) {
|
||||
if (reader.contains(deprecatedPath)) {
|
||||
return true;
|
||||
@ -113,7 +114,7 @@ public class SettingsMigrationService extends PlainMigrationService {
|
||||
// Old other accounts
|
||||
// --------
|
||||
public boolean hasOldOtherAccountsCommand() {
|
||||
return !StringUtils.isEmpty(oldOtherAccountsCommand);
|
||||
return !StringUtils.isBlank(oldOtherAccountsCommand);
|
||||
}
|
||||
|
||||
public String getOldOtherAccountsCommand() {
|
||||
|
@ -67,6 +67,14 @@ public class SettingsWarner {
|
||||
+ " AuthMeBungee add-on to work properly you have to enable this option!");
|
||||
}
|
||||
|
||||
if (!isTrue(bukkitService.isBungeeCordConfiguredForSpigot())
|
||||
&& settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
logger.warning("Note: Hooks.bungeecord is set to true but your server appears to be running in"
|
||||
+ " non-bungeecord mode (see your spigot.yml). In order to prevent untrusted payload attack, "
|
||||
+ "BungeeCord hook will be automatically disabled!");
|
||||
}
|
||||
|
||||
|
||||
// Check if argon2 library is present and can be loaded
|
||||
if (settings.getProperty(SecuritySettings.PASSWORD_HASH).equals(HashAlgorithm.ARGON2)
|
||||
&& !Argon2.isLibraryLoaded()) {
|
||||
|
@ -19,6 +19,7 @@ import org.bukkit.entity.Player;
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Manager for spawn points. It loads spawn definitions from AuthMe and third-party plugins
|
||||
@ -177,7 +178,7 @@ public class SpawnLoader implements Reloadable {
|
||||
World world = player.getWorld();
|
||||
Location spawnLoc = null;
|
||||
for (String priority : spawnPriority) {
|
||||
switch (priority.toLowerCase().trim()) {
|
||||
switch (priority.toLowerCase(Locale.ROOT).trim()) {
|
||||
case "default":
|
||||
if (world.getSpawnLocation() != null) {
|
||||
if (!isValidSpawnPoint(world.getSpawnLocation())) {
|
||||
@ -292,7 +293,7 @@ public class SpawnLoader implements Reloadable {
|
||||
String prefix = pathPrefix + ".";
|
||||
String worldName = configuration.getString(prefix + "world");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (!StringUtils.isEmpty(worldName) && world != null) {
|
||||
if (!StringUtils.isBlank(worldName) && world != null) {
|
||||
return new Location(world, configuration.getDouble(prefix + "x"),
|
||||
configuration.getDouble(prefix + "y"), configuration.getDouble(prefix + "z"),
|
||||
getFloat(configuration, prefix + "yaw"), getFloat(configuration, prefix + "pitch"));
|
||||
@ -314,7 +315,7 @@ public class SpawnLoader implements Reloadable {
|
||||
String prefix = pathPrefix + ".";
|
||||
String worldName = configuration.getString(prefix + "World");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (!StringUtils.isEmpty(worldName) && world != null) {
|
||||
if (!StringUtils.isBlank(worldName) && world != null) {
|
||||
return new Location(world, configuration.getDouble(prefix + "X"),
|
||||
configuration.getDouble(prefix + "Y"), configuration.getDouble(prefix + "Z"),
|
||||
getFloat(configuration, prefix + "Yaw"), getFloat(configuration, prefix + "Pitch"));
|
||||
|
@ -10,7 +10,7 @@ import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||
public final class DatabaseSettings implements SettingsHolder {
|
||||
|
||||
@Comment({"What type of database do you want to use?",
|
||||
"Valid values: SQLITE, MYSQL, POSTGRESQL"})
|
||||
"Valid values: SQLITE, MARIADB, MYSQL, POSTGRESQL"})
|
||||
public static final Property<DataSourceType> BACKEND =
|
||||
newProperty(DataSourceType.class, "DataSource.backend", DataSourceType.SQLITE);
|
||||
|
||||
@ -37,6 +37,11 @@ public final class DatabaseSettings implements SettingsHolder {
|
||||
public static final Property<Boolean> MYSQL_CHECK_SERVER_CERTIFICATE =
|
||||
newProperty( "DataSource.mySQLCheckServerCertificate", true );
|
||||
|
||||
@Comment({"Authorize client to retrieve RSA server public key.",
|
||||
"Advanced option, ignore if you don't know what it means."})
|
||||
public static final Property<Boolean> MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL =
|
||||
newProperty( "DataSource.mySQLAllowPublicKeyRetrieval", true );
|
||||
|
||||
@Comment("Username to connect to the MySQL database")
|
||||
public static final Property<String> MYSQL_USERNAME =
|
||||
newProperty("DataSource.mySQLUsername", "authme");
|
||||
@ -44,13 +49,6 @@ public final class DatabaseSettings implements SettingsHolder {
|
||||
@Comment("Password to connect to the MySQL database")
|
||||
public static final Property<String> MYSQL_PASSWORD =
|
||||
newProperty("DataSource.mySQLPassword", "12345");
|
||||
|
||||
@Comment({"Driver Name of the MySQL database.",
|
||||
"Built-in drivers:",
|
||||
" MySQL: 'fr.xephi.authme.libs.com.mysql.cj.jdbc.Driver'",
|
||||
" MariaDB: 'fr.xephi.authme.libs.org.mariadb.jdbc.Driver'"})
|
||||
public static final Property<String> MYSQL_DRIVER_CLASS_NAME =
|
||||
newProperty("DataSource.mySQLDriverClassName", "fr.xephi.authme.libs.com.mysql.cj.jdbc.Driver");
|
||||
|
||||
@Comment("Database Name, use with converters or as SQLITE database name")
|
||||
public static final Property<String> MYSQL_DATABASE =
|
||||
|
@ -15,6 +15,7 @@ import org.bukkit.Server;
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.util.FileUtils.makePath;
|
||||
|
||||
@ -80,7 +81,7 @@ public class PurgeExecutor {
|
||||
}
|
||||
|
||||
for (String file : dataFolder.list()) {
|
||||
if (cleared.contains(file.toLowerCase())) {
|
||||
if (cleared.contains(file.toLowerCase(Locale.ROOT))) {
|
||||
File playerFile = new File(dataFolder, file);
|
||||
if (playerFile.exists() && playerFile.delete()) {
|
||||
i++;
|
||||
@ -137,7 +138,7 @@ public class PurgeExecutor {
|
||||
if (name.equals(file)) {
|
||||
continue;
|
||||
}
|
||||
if (cleared.contains(name.toLowerCase())) {
|
||||
if (cleared.contains(name.toLowerCase(Locale.ROOT))) {
|
||||
File dataFile = new File(dataFolder, file);
|
||||
if (dataFile.exists() && dataFile.delete()) {
|
||||
i++;
|
||||
|
@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -74,7 +75,7 @@ class PurgeTask extends BukkitRunnable {
|
||||
}
|
||||
|
||||
OfflinePlayer offlinePlayer = offlinePlayers[nextPosition];
|
||||
if (offlinePlayer.getName() != null && toPurge.remove(offlinePlayer.getName().toLowerCase())) {
|
||||
if (offlinePlayer.getName() != null && toPurge.remove(offlinePlayer.getName().toLowerCase(Locale.ROOT))) {
|
||||
if (!permissionsManager.loadUserData(offlinePlayer)) {
|
||||
logger.warning("Unable to check if the user " + offlinePlayer.getName() + " can be purged!");
|
||||
continue;
|
||||
|
@ -14,12 +14,11 @@ public final class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the difference of two strings.
|
||||
* Calculates the difference of two strings.
|
||||
*
|
||||
* @param first First string
|
||||
* @param second Second string
|
||||
*
|
||||
* @return The difference value
|
||||
* @param first first string
|
||||
* @param second second string
|
||||
* @return the difference value
|
||||
*/
|
||||
public static double getDifference(String first, String second) {
|
||||
// Make sure the strings are valid.
|
||||
@ -35,12 +34,11 @@ public final class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given string contains any of the provided elements.
|
||||
* Returns whether the given string contains any of the provided elements.
|
||||
*
|
||||
* @param str The string to analyze
|
||||
* @param pieces The items to check the string for
|
||||
*
|
||||
* @return True if the string contains at least one of the items
|
||||
* @param str the string to analyze
|
||||
* @param pieces the items to check the string for
|
||||
* @return true if the string contains at least one of the items
|
||||
*/
|
||||
public static boolean containsAny(String str, Iterable<String> pieces) {
|
||||
if (str == null) {
|
||||
@ -58,21 +56,19 @@ public final class StringUtils {
|
||||
* Null-safe method for checking whether a string is empty. Note that the string
|
||||
* is trimmed, so this method also considers a string with whitespace as empty.
|
||||
*
|
||||
* @param str The string to verify
|
||||
*
|
||||
* @return True if the string is empty, false otherwise
|
||||
* @param str the string to verify
|
||||
* @return true if the string is empty, false otherwise
|
||||
*/
|
||||
public static boolean isEmpty(String str) {
|
||||
public static boolean isBlank(String str) {
|
||||
return str == null || str.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given needle is in the middle of the haystack, i.e. that the haystack
|
||||
* Checks that the given needle is in the middle of the haystack, i.e. that the haystack
|
||||
* contains the needle and that it is not at the very start or end.
|
||||
*
|
||||
* @param needle the needle to search for
|
||||
* @param haystack the haystack to search in
|
||||
*
|
||||
* @return true if the needle is in the middle of the word, false otherwise
|
||||
*/
|
||||
// Note ljacqu 20170314: `needle` is restricted to char type intentionally because something like
|
||||
|
@ -105,6 +105,6 @@ public final class Utils {
|
||||
* @return true if the email is empty
|
||||
*/
|
||||
public static boolean isEmailEmpty(String email) {
|
||||
return StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email);
|
||||
return StringUtils.isBlank(email) || "your@email.com".equalsIgnoreCase(email);
|
||||
}
|
||||
}
|
||||
|
45
src/main/resources/messages/help_ja.yml
Normal file
45
src/main/resources/messages/help_ja.yml
Normal file
@ -0,0 +1,45 @@
|
||||
# Translation config for the AuthMe help, e.g. when /authme help or /authme help register is called
|
||||
|
||||
# -------------------------------------------------------
|
||||
# List of texts used in the help section
|
||||
common:
|
||||
header: '==========[ AuthMeReloaded ヘルプ ]=========='
|
||||
optional: 'オプション'
|
||||
hasPermission: '権限を持っています'
|
||||
noPermission: '権限がありません'
|
||||
default: 'デフォルト'
|
||||
result: '結果'
|
||||
defaultPermissions:
|
||||
notAllowed: '権限がありません'
|
||||
opOnly: 'OPのみ'
|
||||
allowed: '全員に許可'
|
||||
|
||||
# -------------------------------------------------------
|
||||
# Titles of the individual help sections
|
||||
# Set the translation text to empty text to disable the section, e.g. to hide alternatives:
|
||||
# alternatives: ''
|
||||
section:
|
||||
command: 'コマンド'
|
||||
description: '簡単な説明'
|
||||
detailedDescription: '詳細な説明'
|
||||
arguments: '引数'
|
||||
permissions: '権限'
|
||||
alternatives: '代替'
|
||||
children: 'コマンド'
|
||||
|
||||
# -------------------------------------------------------
|
||||
# You can translate the data for all commands using the below pattern.
|
||||
# For example to translate /authme reload, create a section "authme.reload", or "login" for /login
|
||||
# If the command has arguments, you can use arg1 as below to translate the first argument, and so forth
|
||||
# Translations don't need to be complete; any missing section will be taken from the default silently
|
||||
# Important: Put main commands like "authme" before their children (e.g. "authme.reload")
|
||||
commands:
|
||||
authme.register:
|
||||
description: 'プレイヤーを登録します'
|
||||
detailedDescription: '指定されたプレイヤーを指定されたパスワードで登録します。'
|
||||
arg1:
|
||||
label: 'プレイヤー名'
|
||||
description: 'プレイヤー名'
|
||||
arg2:
|
||||
label: 'パスワード'
|
||||
description: 'パスワード'
|
45
src/main/resources/messages/help_lt.yml
Normal file
45
src/main/resources/messages/help_lt.yml
Normal file
@ -0,0 +1,45 @@
|
||||
# Translation config for the AuthMe help, e.g. when /authme help or /authme help register is called
|
||||
|
||||
# -------------------------------------------------------
|
||||
# List of texts used in the help section
|
||||
common:
|
||||
header: '==========[ AuthMeReloaded PAGALBA ]=========='
|
||||
optional: 'Neprivaloma'
|
||||
hasPermission: 'Jūs turite leidimą'
|
||||
noPermission: 'Jūs neturite leidimo'
|
||||
default: 'Numatytas'
|
||||
result: 'Rezultatas'
|
||||
defaultPermissions:
|
||||
notAllowed: 'Nėra leidimo'
|
||||
opOnly: 'Tik OP'
|
||||
allowed: 'Visiems leistina'
|
||||
|
||||
# -------------------------------------------------------
|
||||
# Titles of the individual help sections
|
||||
# Set the translation text to empty text to disable the section, e.g. to hide alternatives:
|
||||
# alternatives: ''
|
||||
section:
|
||||
command: 'Komanda'
|
||||
description: 'Trumpas aprašas'
|
||||
detailedDescription: 'Detalus aprašas'
|
||||
arguments: 'Argumentai'
|
||||
permissions: 'Leidimai'
|
||||
alternatives: 'Alternatyvos'
|
||||
children: 'Komandos'
|
||||
|
||||
# -------------------------------------------------------
|
||||
# You can translate the data for all commands using the below pattern.
|
||||
# For example to translate /authme reload, create a section "authme.reload", or "login" for /login
|
||||
# If the command has arguments, you can use arg1 as below to translate the first argument, and so forth
|
||||
# Translations don't need to be complete; any missing section will be taken from the default silently
|
||||
# Important: Put main commands like "authme" before their children (e.g. "authme.reload")
|
||||
commands:
|
||||
authme.register:
|
||||
description: 'Užregistruoti žaidėją'
|
||||
detailedDescription: 'Užregistruokite nurodytą žaidėją su nurodytu slaptažodžiu.'
|
||||
arg1:
|
||||
label: 'žaidėjas'
|
||||
description: 'Žaidėjo vardas'
|
||||
arg2:
|
||||
label: 'slaptažodis'
|
||||
description: 'Slaptažodis'
|
156
src/main/resources/messages/messages_ja.yml
Normal file
156
src/main/resources/messages/messages_ja.yml
Normal file
@ -0,0 +1,156 @@
|
||||
# List of global tags:
|
||||
# %nl% - Goes to new line.
|
||||
# %username% - Replaces the username of the player receiving the message.
|
||||
# %displayname% - Replaces the nickname (and colors) of the player receiving the message.
|
||||
|
||||
# Registration
|
||||
registration:
|
||||
register_request: '&3サーバーに登録するには、次のコマンドを使用してください: /register <パスワード> <パスワードの確認>'
|
||||
command_usage: '&c使用方法: /register <パスワード> <パスワードの確認>'
|
||||
reg_only: '&4登録済みのユーザーのみサーバーに参加できます! 自分自身を登録するには、http://example.com にアクセスしてください!'
|
||||
kicked_admin_registered: '管理者があなたを登録しました。再度ログインしてください。'
|
||||
success: '&2登録が完了しました!'
|
||||
disabled: '&cゲーム内での登録は無効になっています!'
|
||||
name_taken: '&cこのユーザー名はすでに登録されています!'
|
||||
|
||||
# Password errors on registration
|
||||
password:
|
||||
match_error: '&cパスワードが一致しません。もう一度確認してください!'
|
||||
name_in_password: '&cパスワードには自分の名前を使用することはできません。別のパスワードを選択してください...'
|
||||
unsafe_password: '&c選択したパスワードは安全ではありません。別のパスワードを選択してください...'
|
||||
forbidden_characters: '&4パスワードに不正な文字が含まれています。許可されている文字: %valid_chars'
|
||||
wrong_length: '&cパスワードが短すぎるか長すぎます!別のパスワードを試してください!'
|
||||
|
||||
# Login
|
||||
login:
|
||||
command_usage: '&c使用方法: /login <パスワード>'
|
||||
wrong_password: '&cパスワードが間違っています!'
|
||||
success: '&2ログインが成功しました!'
|
||||
login_request: '&c次のコマンドを使用してログインしてください: /login <パスワード>'
|
||||
timeout_error: '&4ログインのタイムアウトが発生しました。サーバーからキックされました。もう一度試してください!'
|
||||
|
||||
# Errors
|
||||
error:
|
||||
unregistered_user: '&cこのユーザーは登録されていません!'
|
||||
denied_command: '&cこのコマンドを使用するには認証が必要です!'
|
||||
denied_chat: '&cチャットするには認証が必要です!'
|
||||
not_logged_in: '&cログインしていません!'
|
||||
tempban_max_logins: '&cログインに失敗した回数が多すぎるため、一時的にアクセスが制限されています。'
|
||||
max_registration: '&c接続ごとの登録数が最大値を超えています(%reg_count/%max_acc %reg_names)!'
|
||||
no_permission: '&4この操作を実行する権限がありません!'
|
||||
unexpected_error: '&4予期しないエラーが発生しました。管理者に連絡してください!'
|
||||
kick_for_vip: '&3VIPプレイヤーがサーバーが満員の状態で参加しました!'
|
||||
logged_in: '&cすでにログイン済みです!'
|
||||
kick_unresolved_hostname: '&cエラーが発生しました:解決できないプレイヤーのホスト名!'
|
||||
|
||||
# AntiBot
|
||||
antibot:
|
||||
kick_antibot: 'AntiBot保護モードが有効です!サーバーに参加するまでにしばらくお待ちください。'
|
||||
auto_enabled: '&4[AntiBotService] 接続数が非常に多いため、AntiBotが有効になりました!'
|
||||
auto_disabled: '&2[AntiBotService] %m 分後にAntiBotが無効になりました!'
|
||||
|
||||
unregister:
|
||||
success: '&c登録が正常に解除されました!'
|
||||
command_usage: '&c使用方法: /unregister <パスワード>'
|
||||
|
||||
# Other messages
|
||||
misc:
|
||||
accounts_owned_self: '所持しているアカウント数:%count 個'
|
||||
accounts_owned_other: 'プレイヤー %name のアカウント数:%count 個'
|
||||
account_not_activated: '&cアカウントはまだ有効化されていません。メールを確認してください!'
|
||||
password_changed: '&2パスワードが正常に変更されました!'
|
||||
logout: '&2正常にログアウトしました!'
|
||||
reload: '&2設定とデータベースが正常に再読み込みされました!'
|
||||
usage_change_password: '&c使用方法: /changepassword <旧パスワード> <新パスワード>'
|
||||
|
||||
# Session messages
|
||||
session:
|
||||
invalid_session: '&cIPアドレスが変更され、セッションのデータが期限切れです!'
|
||||
valid_session: '&2セッションの再接続によるログインです。'
|
||||
|
||||
# Error messages when joining
|
||||
on_join_validation:
|
||||
name_length: '&4ユーザー名が短すぎるか長すぎます!'
|
||||
characters_in_name: '&4ユーザー名に無効な文字が含まれています。許可される文字:%valid_chars'
|
||||
country_banned: '&4このサーバーへのアクセスは、お使いの国から制限されています!'
|
||||
not_owner_error: 'このアカウントの所有者ではありません。別の名前を選択してください!'
|
||||
kick_full_server: '&4サーバーが満員です。後でもう一度お試しください!'
|
||||
same_nick_online: '&4同じユーザー名のプレイヤーが既にサーバーでプレイしています!'
|
||||
invalid_name_case: '正しいユーザー名は %valid です。%invalid ではなく、このユーザー名で参加してください。'
|
||||
same_ip_online: '同じIPアドレスを持つプレイヤーが既にゲーム内にいます!'
|
||||
quick_command: 'コマンドを速すぎる速度で使用しました!もう一度サーバーに参加してから、コマンドを使用する前にしばらくお待ちください。'
|
||||
|
||||
# Email
|
||||
email:
|
||||
usage_email_add: '&c使用方法:/email add <メールアドレス> <メールアドレスの確認>'
|
||||
usage_email_change: '&c使用方法:/email change <古いメールアドレス> <新しいメールアドレス>'
|
||||
new_email_invalid: '&c無効な新しいメールアドレスです。もう一度やり直してください!'
|
||||
old_email_invalid: '&c無効な古いメールアドレスです。もう一度やり直してください!'
|
||||
invalid: '&c無効なメールアドレスです。もう一度やり直してください!'
|
||||
added: '&2メールアドレスがアカウントに正常に追加されました!'
|
||||
request_confirmation: '&cメールアドレスを確認してください!'
|
||||
changed: '&2メールアドレスが正しく変更されました!'
|
||||
email_show: '&2現在のメールアドレスは:%email'
|
||||
incomplete_settings: 'エラー:メールの送信に必要なすべての設定が設定されていません。管理者に連絡してください。'
|
||||
already_used: '&4そのメールアドレスは既に使用されています'
|
||||
send_failure: 'メールを送信できませんでした。管理者に連絡してください。'
|
||||
no_email_for_account: '&2現在、このアカウントに関連付けられたメールアドレスはありません。'
|
||||
add_email_request: '&3コマンド「/email add <あなたのメールアドレス> <確認用メールアドレス>」を使用して、アカウントにメールアドレスを追加してください。'
|
||||
change_password_expired: 'このコマンドを使用してパスワードを変更することはできません。'
|
||||
email_cooldown_error: '&c最近すでにメールが送信されています。新しいメールを送信する前に、%time 待つ必要があります。'
|
||||
add_not_allowed: '&cメールアドレスの追加は許可されていません。'
|
||||
change_not_allowed: '&cメールアドレスの変更は許可されていません。'
|
||||
|
||||
# Password recovery by email
|
||||
recovery:
|
||||
forgot_password_hint: '&3パスワードを忘れましたか?次のコマンドを使用してください:/email recovery <あなたのメールアドレス>'
|
||||
command_usage: '&c使用方法:/email recovery <メールアドレス>'
|
||||
email_sent: '&2パスワードの回復メールが正常に送信されました!メールの受信トレイを確認してください!'
|
||||
code:
|
||||
code_sent: 'パスワードをリセットするための回復コードがメールで送信されました。'
|
||||
incorrect: '回復コードが正しくありません!残りの試行回数:%count'
|
||||
tries_exceeded: '回復コードの入力試行回数が上限を超えました。新しいコードを生成するには、"/email recovery [メールアドレス]" を実行してください。'
|
||||
correct: '回復コードが正しく入力されました!'
|
||||
change_password: '即座にパスワードを変更するには、コマンド「/email setpassword <新しいパスワード>」を使用してください。'
|
||||
|
||||
# Captcha
|
||||
captcha:
|
||||
usage_captcha: '&3ログインするには、Captchaコードを解決する必要があります。次のコマンドを使用してください:/captcha %captcha_code'
|
||||
wrong_captcha: '&cCaptchaコードが間違っています。チャットに「/captcha %captcha_code」と入力してください!'
|
||||
valid_captcha: '&2Captchaコードが正しく解決されました!'
|
||||
captcha_for_registration: '登録するには、まずCaptchaを解決する必要があります。次のコマンドを使用してください:/captcha %captcha_code'
|
||||
register_captcha_valid: '&2有効なCaptchaです!/register を使用して登録できます'
|
||||
|
||||
# Verification code
|
||||
verification:
|
||||
code_required: '&3このコマンドはセンシティブな操作であり、メールの認証が必要です!受信トレイを確認し、メールの指示に従ってください。'
|
||||
command_usage: '&c使用方法:/verification <コード>'
|
||||
incorrect_code: '&cコードが正しくありません。メールで受け取ったコードを使用して、「/verification <コード>」とチャットに入力してください。'
|
||||
success: '&2身元が確認されました!現在のセッション内ですべてのコマンドを実行できます!'
|
||||
already_verified: '&2現在のセッションでは、既にすべてのセンシティブなコマンドを実行できます!'
|
||||
code_expired: '&3コードの有効期限が切れています!新しいコードを取得するには、別のセンシティブなコマンドを実行してください!'
|
||||
email_needed: '&3アカウントにはメールアドレスのリンクが必要です。身元を確認するためにはメールアドレスを関連付けてください!'
|
||||
|
||||
# Two-factor authentication
|
||||
two_factor:
|
||||
code_created: '&2秘密コードは %code です。こちらからスキャンできます:%url'
|
||||
confirmation_required: 'コードを確認するには、/2fa confirm <コード> を使用してください'
|
||||
code_required: '二要素認証コードを提出するには、/2fa code <コード> を使用してください'
|
||||
already_enabled: 'アカウントで既に二要素認証が有効になっています!'
|
||||
enable_error_no_code: '2要素認証キーが生成されていないか、期限が切れています。/2fa add を実行してください'
|
||||
enable_success: 'アカウントでの二要素認証が正常に有効になりました'
|
||||
enable_error_wrong_code: 'コードが間違っているか、期限が切れています。/2fa add を実行してください'
|
||||
not_enabled_error: 'アカウントでは二要素認証が有効になっていません。/2fa add を実行してください'
|
||||
removed_success: 'アカウントから二要素認証が正常に削除されました'
|
||||
invalid_code: '無効なコードです!'
|
||||
|
||||
# Time units
|
||||
time:
|
||||
second: '秒'
|
||||
seconds: '秒'
|
||||
minute: '分'
|
||||
minutes: '分'
|
||||
hour: '時間'
|
||||
hours: '時間'
|
||||
day: '日'
|
||||
days: '日'
|
@ -5,153 +5,153 @@
|
||||
|
||||
# Registration
|
||||
registration:
|
||||
disabled: '&6Registracija yra isjungta'
|
||||
name_taken: '&cVartotojo vardas jau uzregistruotas'
|
||||
register_request: '&ePrasome prisiregistruoti: /register slaptazodis pakartotiSlaptazodi'
|
||||
command_usage: '&eNaudojimas: /register slaptazodis pakartotiSlaptazodi'
|
||||
reg_only: '&cTik prisiregistravusiem zaidejams: apsilankykite: http://example.com tam kad uzsiregistruoti.'
|
||||
success: '&aSekmingai prisiregistravote.'
|
||||
# TODO kicked_admin_registered: 'An admin just registered you; please log in again'
|
||||
disabled: '&6Registracija yra išjungta'
|
||||
name_taken: '&cVartotojo vardas jau užregistruotas'
|
||||
register_request: '&ePrašome prisiregistruoti: /register slaptažodis pakartotiSlaptažodį'
|
||||
command_usage: '&eNaudojimas: /register slaptažodis pakartotiSlaptažodį'
|
||||
reg_only: '&cTik prisiregistravusiems žaidėjams: apsilankykite: http://example.com tam, kad užsiregistruoti.'
|
||||
success: '&aSėkmingai prisiregistravote.'
|
||||
kicked_admin_registered: 'Administatorius Jus užregistravo. Prisijunkite iš naujo'
|
||||
|
||||
# Password errors on registration
|
||||
password:
|
||||
match_error: '&cSlaptazodziai nesutampa'
|
||||
# TODO name_in_password: '&cYou can''t use your name as password, please choose another one...'
|
||||
# TODO unsafe_password: '&cThe chosen password isn''t safe, please choose another one...'
|
||||
# TODO forbidden_characters: '&4Your password contains illegal characters. Allowed chars: %valid_chars'
|
||||
wrong_length: '&cJusu slaptazodis buvo per ilgas arba per trumpas.'
|
||||
match_error: '&cSlaptažodžiai nesutampa'
|
||||
name_in_password: '&cJūs negalite naudoti savo vardo slaptažodyje'
|
||||
unsafe_password: '&cŠį Slaptažodį lengva nulaužti, pasirinkite kitą slaptažodį'
|
||||
forbidden_characters: '&4Jūsų slaptažodis turi netinkamų simbolių. Leidžiami simboliai: %valid_chars'
|
||||
wrong_length: '&cJūsų pasirinktas slaptažodis per ilgas arba per trumpas.'
|
||||
|
||||
# Login
|
||||
login:
|
||||
command_usage: '&eKomandos panaudojimas: /login slaptazodis'
|
||||
wrong_password: '&cNeteisingas slaptazosdis'
|
||||
success: '&aSekmingai prisijungete'
|
||||
login_request: '&ePrasome prisijungti: /login slaptazodis'
|
||||
timeout_error: '&cNespejote prisijungti'
|
||||
command_usage: '&eKomandos panaudojimas: /login slaptažodis'
|
||||
wrong_password: '&cNeteisingas Slaptažosdis'
|
||||
success: '&aSėkmingai prisijungėte'
|
||||
login_request: '&ePrašome prisijungti: /login slaptažodis'
|
||||
timeout_error: '&cNespėjote prisijungti'
|
||||
|
||||
# Errors
|
||||
error:
|
||||
# TODO denied_command: '&cIn order to use this command you must be authenticated!'
|
||||
# TODO denied_chat: '&cIn order to chat you must be authenticated!'
|
||||
unregistered_user: '&cVartotojas neprisiregistraves'
|
||||
not_logged_in: '&cTu neprisijunges!'
|
||||
no_permission: '&cNera leidimo'
|
||||
unexpected_error: '&cAtsirado klaida, praneskite adminstratoriui.'
|
||||
max_registration: '&cJus pasiekete maksimalu registraciju skaiciu.'
|
||||
logged_in: '&cTu aju prisijunges!'
|
||||
kick_for_vip: '&cA VIP prisijunge i pilna serveri!'
|
||||
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||
# TODO tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.'
|
||||
denied_command: '&cKad galetumėte naudoti šią komandą turite būti prisijungę!'
|
||||
denied_chat: '&cKad galetumėte kalbėti Jūs turite būti prisijungę!'
|
||||
unregistered_user: '&cVartotojas neprisiregistravęs'
|
||||
not_logged_in: '&cJūs neprisijungę!'
|
||||
no_permission: '&cNėra leidimo'
|
||||
unexpected_error: '&cAtsirado klaida, praneškite adminstratoriui.'
|
||||
max_registration: '&cJūs pasiekėte maksimalų registracijų skaičių.'
|
||||
logged_in: '&cTu jau prisijungęs!'
|
||||
kick_for_vip: '&cRėmėjas prisijungė į pilną serverį!'
|
||||
kick_unresolved_hostname: '&cĮvyko klaida su žaidejo adresu!'
|
||||
tempban_max_logins: '&cJūs laikinai užblokuotas, nes kelis kartus neteisingai suvedėte slaptažodį.'
|
||||
|
||||
# AntiBot
|
||||
antibot:
|
||||
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
|
||||
# TODO auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
|
||||
# TODO auto_disabled: '&2[AntiBotService] AntiBot disabled after %m minutes!'
|
||||
kick_antibot: 'AntiBot prevencija įjungta! Palaukite prieš prisijungiant.'
|
||||
auto_enabled: '&4[AntiBotService] AntiBot prevencija pajungta dėl didelio kiekio prisijungimų!'
|
||||
auto_disabled: '&2[AntiBotService] AntiBot bus išjungtas po %m minučių!'
|
||||
|
||||
# Unregister
|
||||
unregister:
|
||||
success: '&aSekmingai issiregistravote!'
|
||||
command_usage: '&ePanaikinti registracija: "/unregister slaptazodis"'
|
||||
success: '&aSėkmingai išsiregistravote!'
|
||||
command_usage: '&ePanaikinti registraciją: "/unregister slaptažodis"'
|
||||
|
||||
# Other messages
|
||||
misc:
|
||||
account_not_activated: '&aJusu vartotojas nera patvirtintas, patikrinkite el.pasta.'
|
||||
password_changed: '&aSlaptazodis pakeistas'
|
||||
logout: '&aSekmingai atsijungete'
|
||||
reload: '&aNustatymai ir duomenu baze buvo perkrauta.'
|
||||
usage_change_password: '&ePanaudojimas: /changepassword senasSlaptazodis naujasSlaptazodis'
|
||||
# TODO accounts_owned_self: 'You own %count accounts:'
|
||||
# TODO accounts_owned_other: 'The player %name has %count accounts:'
|
||||
account_not_activated: '&aJūsų vartotojas nėra patvirtintas, pasitikrinkite el.paštą.'
|
||||
password_changed: '&aSlaptažodis pakeistas'
|
||||
logout: '&aSėkmingai atsijungėte'
|
||||
reload: '&aNustatymai ir duomenų bazė buvo perkrauta.'
|
||||
usage_change_password: '&ePanaudojimas: /changepassword senasSlaptažodis naujasSlaptažodis'
|
||||
accounts_owned_self: 'Jūs turite %count paskyrą(-s):'
|
||||
accounts_owned_other: 'Žaidejas %name turi %count paskyrą(-s):'
|
||||
|
||||
# Session messages
|
||||
session:
|
||||
valid_session: '&aSesijos prisijungimas'
|
||||
invalid_session: '&cSesijos laikai nesutampa, prasome palaukti kol secija baigsis.'
|
||||
valid_session: '&aAutomatinis sesijos prisijungimas'
|
||||
invalid_session: '&cSesijos laikai nesutampa. Prašome palaukti kol sesija baigsis.'
|
||||
|
||||
# Error messages when joining
|
||||
on_join_validation:
|
||||
# TODO same_ip_online: 'A player with the same IP is already in game!'
|
||||
same_nick_online: '&cKazkas situo vardu jau zaidzia.'
|
||||
name_length: '&cJusu varsdas yra per ilgas arba per trumpas.'
|
||||
characters_in_name: '&cJusu varde yra neledziamu simboliu, leidziami: %valid_chars'
|
||||
kick_full_server: '&cServeris yra pilnas, Atsiprasome.'
|
||||
# TODO country_banned: '&4Your country is banned from this server!'
|
||||
# TODO not_owner_error: 'You are not the owner of this account. Please choose another name!'
|
||||
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
# TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.'
|
||||
same_ip_online: 'Žaidejas su tuo pačiu IP adresu jau yra žaidime!'
|
||||
same_nick_online: '&cKažkas šituo vardu jau žaidžia.'
|
||||
name_length: '&cJūsų vardas yra per ilgas arba per trumpas.'
|
||||
characters_in_name: '&cJūsų varde yra neledziamų simbolių. Leidžiami: %valid_chars'
|
||||
kick_full_server: '&cServeris yra pilnas, atsiprašome.'
|
||||
country_banned: '&4Jūsų šalis yra užblokuota šiame serveryje!'
|
||||
not_owner_error: 'J0s nesate šios paskyros savininkas, pasirinkite kitą vardą!'
|
||||
invalid_name_case: 'Turėtumėte prisijungti su vardu %valid, o ne su: %invalid.'
|
||||
quick_command: 'Jūs panaudojote komandą per greitai! Prisijunkite iš naujo ir šiek tiek palaukite prieš naudojant komandas.'
|
||||
|
||||
# Email
|
||||
email:
|
||||
add_email_request: '&ePrasau pridekite savo el.pasta : /email add Email confirmEmail'
|
||||
# TODO usage_email_add: '&cUsage: /email add <email> <confirmEmail>'
|
||||
# TODO usage_email_change: '&cUsage: /email change <oldEmail> <newEmail>'
|
||||
# TODO new_email_invalid: '&cInvalid new email, try again!'
|
||||
# TODO old_email_invalid: '&cInvalid old email, try again!'
|
||||
# TODO invalid: '&cInvalid email address, try again!'
|
||||
# TODO added: '&2Email address successfully added to your account!'
|
||||
# TODO add_not_allowed: '&cAdding email was not allowed'
|
||||
# TODO request_confirmation: '&cPlease confirm your email address!'
|
||||
# TODO changed: '&2Email address changed correctly!'
|
||||
# TODO change_not_allowed: '&cChanging email was not allowed'
|
||||
# TODO email_show: '&2Your current email address is: &f%email'
|
||||
# TODO no_email_for_account: '&2You currently don''t have email address associated with this account.'
|
||||
# TODO already_used: '&4The email address is already being used'
|
||||
# TODO incomplete_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
|
||||
# TODO send_failure: 'The email could not be sent. Please contact an administrator.'
|
||||
# TODO change_password_expired: 'You cannot change your password using this command anymore.'
|
||||
# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.'
|
||||
add_email_request: '&ePrašome jūsų pridėti savo el.paštą : /email add <el.paštas> <el.paštas>'
|
||||
usage_email_add: '&cNaudojimas: /email add <el.paštas> <el.paštas>'
|
||||
usage_email_change: '&cNaudojimas: /email change <senas el.pastas> <naujas el.pastas>'
|
||||
new_email_invalid: '&cNeteisingas el.paštas, bandykite iš naujo!'
|
||||
old_email_invalid: '&cNeteisingas senas el.paštas, bandykite iš naujo!'
|
||||
invalid: '&cNeteisingas el.paštas, bandykite iš naujo!'
|
||||
added: '&2El.paštas sėkmingai pridėtas!'
|
||||
add_not_allowed: '&cNaujo el.pašto pridejimas nėra galimas'
|
||||
request_confirmation: '&cPatvirtinkite savo el.paštą!'
|
||||
changed: '&2El.paštą pakeistas sėkmingai!'
|
||||
change_not_allowed: '&cEl.pašto keitimas nėra galimas'
|
||||
email_show: '&2Jūsų dabartinis el.pašto adresas: &f%email'
|
||||
no_email_for_account: '&2Šiuo metu Jūs neturite pridėję jokio el.pašto adreso.'
|
||||
already_used: '&4Jis el.pašto adresas jau yra naudojamas'
|
||||
incomplete_settings: 'Klaida: Ne visi nustatymai yra nustatyti laiško siuntimui. Susikietite su administratoriumi.'
|
||||
send_failure: 'El.pašto laiškas nebuvo išsiųstas. Susikietite su administratoriumi.'
|
||||
change_password_expired: 'Jūs nebegalite pakeisti savo slaptažodzio naudojant šią komandą.'
|
||||
email_cooldown_error: '&cEl.pašto laiškas jau buvo išsiųstas. Palaukite %time prieš šiunčiant naują.'
|
||||
|
||||
# Password recovery by email
|
||||
recovery:
|
||||
forgot_password_hint: '&cPamirsote slaptazodi? Rasykite: /email recovery el.pastas'
|
||||
# TODO command_usage: '&cUsage: /email recovery <Email>'
|
||||
# TODO email_sent: '&2Recovery email sent successfully! Please check your email inbox!'
|
||||
forgot_password_hint: '&cPamiršote savo slaptažodį? Rašykite: /email recovery el.paštas'
|
||||
command_usage: '&cNaudojimas: /email recovery el.paštas'
|
||||
email_sent: '&2Laiškas į Jūsų el.pašto adresą buvo išsiųstas!'
|
||||
code:
|
||||
# TODO code_sent: 'A recovery code to reset your password has been sent to your email.'
|
||||
# TODO incorrect: 'The recovery code is not correct! You have %count tries remaining.'
|
||||
# TODO tries_exceeded: 'You have exceeded the maximum number attempts to enter the recovery code. Use "/email recovery [email]" to generate a new one.'
|
||||
# TODO correct: 'Recovery code entered correctly!'
|
||||
# TODO change_password: 'Please use the command /email setpassword <new password> to change your password immediately.'
|
||||
code_sent: 'Kodas slaptažodžio atstatymui buvo išsiųstas į Jūsų el.paštą.'
|
||||
incorrect: 'Kodas neteisingas! Jums liko %count bandymai(-as).'
|
||||
tries_exceeded: 'Jūs išnaudojote visus bandymus. Naudokite "/email recovery el.paštas", kad gauti naują kodą.'
|
||||
correct: 'Kodas įvestas sėkmingai!'
|
||||
change_password: 'Naudokite /email setpassword <Naujas_slaptažodis>, kad pasikeistumėte slaptažodį.'
|
||||
|
||||
# Captcha
|
||||
captcha:
|
||||
usage_captcha: '&cPanaudojimas: /captcha %captcha_code'
|
||||
wrong_captcha: '&cNeteisinga Captcha, naudokite : /captcha %captcha_code'
|
||||
valid_captcha: '&cJusu captcha Teisinga!'
|
||||
# TODO captcha_for_registration: 'To register you have to solve a captcha first, please use the command: /captcha %captcha_code'
|
||||
# TODO register_captcha_valid: '&2Valid captcha! You may now register with /register'
|
||||
wrong_captcha: '&cNeteisinga captcha, naudokite : /captcha %captcha_code'
|
||||
valid_captcha: '&cJūsų captcha teisinga!'
|
||||
captcha_for_registration: 'Kad prisiregistruotumėte turite įvygdyti captchą. Rašykite: /captcha %captcha_code'
|
||||
register_captcha_valid: '&2Captcha teisinga! Galite naudoti /register'
|
||||
|
||||
# Verification code
|
||||
verification:
|
||||
# TODO code_required: '&3This command is sensitive and requires an email verification! Check your inbox and follow the email''s instructions.'
|
||||
# TODO command_usage: '&cUsage: /verification <code>'
|
||||
# TODO incorrect_code: '&cIncorrect code, please type "/verification <code>" into the chat, using the code you received by email'
|
||||
# TODO success: '&2Your identity has been verified! You can now execute all commands within the current session!'
|
||||
# TODO already_verified: '&2You can already execute every sensitive command within the current session!'
|
||||
# TODO code_expired: '&3Your code has expired! Execute another sensitive command to get a new code!'
|
||||
# TODO email_needed: '&3To verify your identity you need to link an email address with your account!!'
|
||||
code_required: '&3Kad galėtumėte naudoti šią komandą turite patvirtinti savo el.pašto adresą! Sekite instrukcijas savo el.pašte.'
|
||||
command_usage: '&cNaudojimas: /verification <kodas>'
|
||||
incorrect_code: '&cNeteisingas kodas, naudokite "/verification <kodas>" įvesdami kodą gautą savo el.pašte'
|
||||
success: '&2Jūsų paskyra patvirtinta! Jūs galite naudoti visas komandas!'
|
||||
already_verified: '&2Jūs jau esate patvirtinę savo paskyrą ir galite naudoti visas komandas!'
|
||||
code_expired: '&3Jūsų kodo galiojimas baigėsi! Panaudokite komandą iš naujo, kad gautumėte naują kodą!'
|
||||
email_needed: '&3Kad patvirtinti savo paskyra turite pridėti el.pašto adresą!'
|
||||
|
||||
# Time units
|
||||
time:
|
||||
# TODO second: 'second'
|
||||
# TODO seconds: 'seconds'
|
||||
# TODO minute: 'minute'
|
||||
# TODO minutes: 'minutes'
|
||||
# TODO hour: 'hour'
|
||||
# TODO hours: 'hours'
|
||||
# TODO day: 'day'
|
||||
# TODO days: 'days'
|
||||
second: 'sekundę'
|
||||
seconds: 'sekundes'
|
||||
minute: 'minutę'
|
||||
minutes: 'minutes'
|
||||
hour: 'valandą'
|
||||
hours: 'valandas'
|
||||
day: 'dieną'
|
||||
days: 'dienas'
|
||||
|
||||
# Two-factor authentication
|
||||
two_factor:
|
||||
# TODO code_created: '&2Your secret code is %code. You can scan it from here %url'
|
||||
# TODO confirmation_required: 'Please confirm your code with /2fa confirm <code>'
|
||||
# TODO code_required: 'Please submit your two-factor authentication code with /2fa code <code>'
|
||||
# TODO already_enabled: 'Two-factor authentication is already enabled for your account!'
|
||||
# TODO enable_error_no_code: 'No 2fa key has been generated for you or it has expired. Please run /2fa add'
|
||||
# TODO enable_success: 'Successfully enabled two-factor authentication for your account'
|
||||
# TODO enable_error_wrong_code: 'Wrong code or code has expired. Please run /2fa add'
|
||||
# TODO not_enabled_error: 'Two-factor authentication is not enabled for your account. Run /2fa add'
|
||||
# TODO removed_success: 'Successfully removed two-factor auth from your account'
|
||||
# TODO invalid_code: 'Invalid code!'
|
||||
code_created: '&2Jūsų slaptas kodas yra %code. Jį galite nuskenuoti čia: %url'
|
||||
confirmation_required: 'Patvirtinkite savo kodą su: /2fa confirm <kodas>'
|
||||
code_required: 'Patvirkinkite savo kodą su: /2fa code <kodas>'
|
||||
already_enabled: 'Jūs jau turite dviejų faktorių autentifikaciją!'
|
||||
enable_error_no_code: 'Jūs neturite dviejų faktorių autentifikacijos arba ji pasibaigė. Rašykite /2fa add'
|
||||
enable_success: 'Dviejų faktorių autentifikacija sėkmingai įjungta'
|
||||
enable_error_wrong_code: 'Neteisingas arba pasibaigęs kodas. Rašykite /2fa add'
|
||||
not_enabled_error: 'Dviejų faktorių autentifikavimas nėra įjungtas ant jūsų paskyros. Rašykite /2fa add'
|
||||
removed_success: 'Dviejų faktorių autentifikavimas sėkmingai pašalintas iš jūsų paskyros.'
|
||||
invalid_code: 'Neteisingas kodas!'
|
||||
|
@ -5,13 +5,13 @@
|
||||
|
||||
# Registration
|
||||
registration:
|
||||
disabled: '&cRegistracija v igri je onemogočena!'
|
||||
name_taken: '&cTo uporabniško ime ste ze registrirali!'
|
||||
register_request: '&3Registrirajte se z ukazom "/register <geslo> <PotrdiGeslo>"'
|
||||
command_usage: '&cUporaba: /register <geslo> <PotrdiGeslo>'
|
||||
reg_only: '&4Samo registrirani uporabniki se lahko povezejo! Obiscite http://example.com , da se registrirate!'
|
||||
kicked_admin_registered: 'Administrator vas je registriral; prosimo, da se prijavite.'
|
||||
success: '&2Uspešno registriran!'
|
||||
disabled: '&cRegistracija v igri je onemogočena!'
|
||||
name_taken: '&cTo uporabniško ime ste ze registrirali!'
|
||||
kicked_admin_registered: 'Administrator vas je registriral; prosimo, da se prijavite.'
|
||||
|
||||
# Password errors on registration
|
||||
password:
|
||||
@ -40,6 +40,7 @@ error:
|
||||
max_registration: '&cPresegli ste največjo stevilo registracij (%reg_count/%max_acc %reg_names) za vašo povezavo!'
|
||||
logged_in: '&cSte že povezani!'
|
||||
kick_for_vip: '&3VIP igralec se je pridruzil serverju, ko je bil poln!'
|
||||
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||
tempban_max_logins: '&cBil si začasno izločen zaradi preveč neuspešnih prijav.'
|
||||
|
||||
# AntiBot
|
||||
@ -131,6 +132,17 @@ verification:
|
||||
code_expired: '&3Your code has expired! Execute another sensitive command to get a new code!'
|
||||
email_needed: '&3To verify your identity you need to link an email address with your account!'
|
||||
|
||||
# Time units
|
||||
time:
|
||||
second: 'sekunda'
|
||||
seconds: 'sekund'
|
||||
minute: 'minuta'
|
||||
minutes: 'minut'
|
||||
hour: 'ur'
|
||||
hours: 'ure'
|
||||
day: 'dan'
|
||||
days: 'dni'
|
||||
|
||||
# Two-factor authentication
|
||||
two_factor:
|
||||
code_created: '&2Vasa skrivna koda je %code. Lahko je skenirate tu %url!'
|
||||
@ -143,15 +155,3 @@ two_factor:
|
||||
not_enabled_error: 'Dvo stopična prijava ni vključena za vaš račun. Uporabite /2fa add'
|
||||
removed_success: 'Usprešno ste odstranili dvo stopično prijavo za vaš račun.'
|
||||
invalid_code: 'Nepravilna koda!'
|
||||
|
||||
# Time units
|
||||
time:
|
||||
second: 'sekunda'
|
||||
seconds: 'sekund'
|
||||
minute: 'minuta'
|
||||
minutes: 'minut'
|
||||
hour: 'ur'
|
||||
hours: 'ure'
|
||||
day: 'dan'
|
||||
days: 'dni'
|
||||
|
@ -6,7 +6,7 @@
|
||||
# Registration
|
||||
registration:
|
||||
disabled: '&cKhông cho phép đăng ký tài khoản trong máy chủ!'
|
||||
name_taken: '&cBạn có thể đăng ký với tên tài khoản này!'
|
||||
name_taken: '&cTài khoản này đã được đăng ký!'
|
||||
register_request: '&2Xin vui lòng đăng ký tài khoản với lệnh "/register <mật khẩu> <nhập lại mật khẩu>"'
|
||||
command_usage: '&cSử dụng: /register <mật khẩu> <nhập lại mật khẩu>'
|
||||
reg_only: '&4Chỉ có thành viên mới có thể tham gia máy chủ, vui lòng truy cập trang web http://example.com để đăng ký thành viên!'
|
||||
@ -15,7 +15,7 @@ registration:
|
||||
|
||||
# Password errors on registration
|
||||
password:
|
||||
match_error: '&cMật khẩu không hợp, xin vui lòng kiểm tra lại!'
|
||||
match_error: '&cMật khẩu không đúng, vui lòng kiểm tra lại!'
|
||||
name_in_password: '&cBạn không thể đặt mật khẩu bằng tên của mình, vui lòng đặt lại...'
|
||||
unsafe_password: '&cMật khẩu của bạn vừa đặt không an toàn, vui lòng đặt lại...'
|
||||
forbidden_characters: '&4Mật khẩu của bạn chứa ký tự không hợp lệ. Các ký tự cho phép: %valid_chars'
|
||||
@ -31,17 +31,17 @@ login:
|
||||
|
||||
# Errors
|
||||
error:
|
||||
denied_command: '&cĐể được sử dụng lệnh bạn phải hoàn thành xác thực tài khoản đã!'
|
||||
denied_chat: '&cĐể được chát bạn phải hoàn thành xác thực tài khoản đã!'
|
||||
unregistered_user: '&cNgười dùng này đã được đăng ký!'
|
||||
denied_command: '&cBạn phải đăng nhập trước rồi mới có thể dùng lệnh này!'
|
||||
denied_chat: '&cBạn phải đăng nhập trước rồi mới có thể chat!'
|
||||
unregistered_user: '&cNgười dùng này chưa được đăng ký!'
|
||||
not_logged_in: '&cBạn chưa đăng nhập!'
|
||||
no_permission: '&4Bạn không có quyền truy cập lệnh này!'
|
||||
unexpected_error: '&4Lỗi! Vui lòng liên hệ quản trị viên hoặc admin'
|
||||
max_registration: '&cBạn đã vượt quá giới hạn tối đa đăng ký tài khoản (%reg_count/%max_acc %reg_names) cho những lần kết nối tài khoản!'
|
||||
logged_in: '&cBạn đã đăng nhập!'
|
||||
no_permission: '&4Bạn không có quyền dùng cập lệnh này!'
|
||||
unexpected_error: '&4Lỗi! Vui lòng liên hệ quản trị viên.'
|
||||
max_registration: '&cBạn đã vượt quá giới hạn tối đa đăng ký tài khoản (%reg_count/%max_acc %reg_names) trên đường truyền của bạn!'
|
||||
logged_in: '&cBạn đã đăng nhập rồi!'
|
||||
kick_for_vip: '&eChỉ có thành viên VIP mới được tham gia khi máy chủ đầy!'
|
||||
kick_unresolved_hostname: '&cLôi đã xảy ra: Không thể phân giải hostname!'
|
||||
tempban_max_logins: '&cBạn đã bị tạm thời khóa truy cập do đăng nhập sai nhiều lần.'
|
||||
kick_unresolved_hostname: '&cLỗi đã xảy ra: Không thể phân giải hostname của người chơi!'
|
||||
tempban_max_logins: '&cBạn đã bị chặn tạm thời do đăng nhập sai quá nhiều lần.'
|
||||
|
||||
# AntiBot
|
||||
antibot:
|
||||
@ -59,7 +59,7 @@ misc:
|
||||
account_not_activated: '&cTài khoản của bạn chưa được kích hoạt, vui lòng kiểm tra email!'
|
||||
password_changed: '&2Thay đổi mật khẩu thành công!'
|
||||
logout: '&2Bạn đã đăng xuất!'
|
||||
reload: '&2Cấu hình và cơ sở dử liệu đã được nạp lại!'
|
||||
reload: '&2Cấu hình và cơ sở dử liệu đã được tải lại thành công!'
|
||||
usage_change_password: '&cSử dụng: /changepassword <mật khẩu cũ> <mật khẩu mới>'
|
||||
accounts_owned_self: 'Bạn sở hữu %count tài khoản:'
|
||||
accounts_owned_other: 'Người chơi %name có %count tài khoản:'
|
||||
@ -71,7 +71,7 @@ session:
|
||||
|
||||
# Error messages when joining
|
||||
on_join_validation:
|
||||
same_ip_online: 'Một người chơi với cùng địa chỉ IP đã đang chơi!'
|
||||
same_ip_online: 'Một người chơi với cùng địa chỉ IP đã kết nối vào máy chủ!'
|
||||
same_nick_online: '&4Tài khoản đang được sử dụng trên máy chủ!'
|
||||
name_length: '&4Tên đăng nhập của bạn quá ngắn hoặc quá dài!'
|
||||
characters_in_name: '&4Tên nhân vật có chứa ký tự không hợp lệ. Các ký tự được cho phép: %valid_chars'
|
||||
@ -79,7 +79,7 @@ on_join_validation:
|
||||
country_banned: '&4Quốc gia của bạn bị cấm tham gia máy chủ này!'
|
||||
not_owner_error: 'Bạn không phải là chủ sở hữu tài khoản này, hãy chọn tên khác!'
|
||||
invalid_name_case: 'Bạn nên vào máy chủ với tên đăng nhập là %valid, không phải là %invalid.'
|
||||
quick_command: 'Bạn đang xài lệnh quá nhanh. Hãy thoát máy chủ và chờ một lúc trước khi sử dụng lệnh'
|
||||
quick_command: 'Bạn đang xài lệnh quá nhanh. Hãy thoát máy chủ và chờ một lúc trước khi sử dụng lệnh.'
|
||||
|
||||
# Email
|
||||
email:
|
||||
@ -89,24 +89,24 @@ email:
|
||||
new_email_invalid: '&cEmail mới không hợp lệ, vui lòng thử lại!'
|
||||
old_email_invalid: '&cEmail cũ không hợp lệ, vui lòng thử lại!'
|
||||
invalid: '&cĐại chỉ email không hợp lệ, vui lòng thử lại!'
|
||||
added: '&2Địa chỉ email đã thêm vào tài khoản của bạn thành công!'
|
||||
add_not_allowed: '&cViệc thêm email không được cho phép!'
|
||||
added: '&2Địa chỉ email đã được thêm vào tài khoản của bạn.'
|
||||
add_not_allowed: '&cKhông được phép thêm địa chỉ email!'
|
||||
request_confirmation: '&cVui lòng xác nhận địa chỉ email của bạn!'
|
||||
changed: '&2Địa chỉ email đã thay đổi!'
|
||||
change_not_allowed: '&cViệc đổi địa chỉ email không được cho phép'
|
||||
change_not_allowed: '&cKhông được phép thay đổi địa chỉ email!'
|
||||
email_show: '&2Địa chỉ email hiện tại của bạn là: &f%email'
|
||||
no_email_for_account: '&2Hiện tại bạn chưa liên kết bất kỳ email nào với tài khoản này.'
|
||||
already_used: '&4Địa chỉ email đã được sử dụng'
|
||||
incomplete_settings: 'Lỗi: các thiết lập để gửi thư không được cài đặt đầy đủ. Vui lòng liên hệ với quản trị viên để thông báo lỗi.'
|
||||
already_used: '&4Địa chỉ email đã được sử dụng!'
|
||||
incomplete_settings: 'Lỗi: các thiết lập để gửi thư không được cài đặt đúng cách. Vui lòng liên hệ với quản trị viên để báo lỗi.'
|
||||
send_failure: 'Không thể gửi thư. Vui lòng liên hệ với ban quản trị.'
|
||||
change_password_expired: '&cBạn không thể thay đổi mật khẩu bằng lệnh này từ nay.'
|
||||
email_cooldown_error: '&cMột bức thư đã được gửi gần đây. Bạn phải chờ %time trước khi có thể gửi một bức thư mới.'
|
||||
change_password_expired: '&cBạn không thể thay đổi mật khẩu bằng lệnh này nữa.'
|
||||
email_cooldown_error: '&cMột email đã được gửi gần đây. Bạn phải chờ %time trước khi có thể gửi một email mới.'
|
||||
|
||||
# Password recovery by email
|
||||
recovery:
|
||||
forgot_password_hint: '&aBạn quên mật khẩu? Vui lòng gõ lệnh "/email recovery <email>"'
|
||||
command_usage: '&cSử dụng: /email recovery <email>'
|
||||
email_sent: '&2Email phục hồi đã được gửi thành công! Vui lòng kiểm tra hộp thư đến trong email của bạn.'
|
||||
email_sent: '&2Email khôi phục đã được gửi thành công! Vui lòng kiểm tra hộp thư đến trong email của bạn.'
|
||||
code:
|
||||
code_sent: 'Một mã khôi phục mật khẩu đã được gửi đến địa chỉ email của bạn.'
|
||||
incorrect: 'Mã khôi phục không đúng! Dùng lệnh /email recovery [email] để tạo một mã mới'
|
||||
@ -116,20 +116,20 @@ recovery:
|
||||
|
||||
# Captcha
|
||||
captcha:
|
||||
usage_captcha: '&eĐể đăng nhập vui lòng hãy nhập mã Captcha, gõ lệnh "/captcha %captcha_code"'
|
||||
usage_captcha: '&eĐể đăng nhập, hãy nhập mã Captcha, Vui lòng gõ lệnh "/captcha %captcha_code"'
|
||||
wrong_captcha: '&cSai mã captcha, Vui lòng gõ lệnh "/captcha %captcha_code"!'
|
||||
valid_captcha: '&2Mã captcha đã được xác nhận!'
|
||||
# TODO captcha_for_registration: 'To register you have to solve a captcha first, please use the command: /captcha %captcha_code'
|
||||
# TODO register_captcha_valid: '&2Valid captcha! You may now register with /register'
|
||||
valid_captcha: '&2Đã xác minh captcha!'
|
||||
captcha_for_registration: 'Để đăng ký, hãy nhập mã Captcha trước. Vui lòng gõ lệnh "/captcha %captcha_code"'
|
||||
register_captcha_valid: '&2Đã xác minh captcha! Bây giờ bạn có thể đăng ký với lệnh "/register"'
|
||||
|
||||
# Verification code
|
||||
verification:
|
||||
# TODO code_required: '&3This command is sensitive and requires an email verification! Check your inbox and follow the email''s instructions.'
|
||||
code_required: '&3Lệnh này nhạy cảm và yêu cầu xác minh email! Vui lòng iểm tra hộp thư đến của bạn và làm theo hướng dẫn trong email.'
|
||||
command_usage: '&cLệnh: /verification <code>'
|
||||
# TODO incorrect_code: '&cIncorrect code, please type "/verification <code>" into the chat, using the code you received by email'
|
||||
success: '&2Danh tính của bạn đã được xác minh! Bạn đã có thể sử dụng các lệnh trong phiên đăng nhập này'
|
||||
# TODO already_verified: '&2You can already execute every sensitive command within the current session!'
|
||||
# TODO code_expired: '&3Your code has expired! Execute another sensitive command to get a new code!'
|
||||
incorrect_code: '&cMã xác minh không chính xác, vui lòng nhập "/verify <code>" với mã bạn nhận được qua email.'
|
||||
success: '&2Xác minh thành công! Bạn đã có thể sử dụng các lệnh trong phiên đăng nhập này.'
|
||||
already_verified: '&2Bạn đã có thể thực hiện mọi lệnh nhạy cảm trong phiên hiện tại!'
|
||||
code_expired: '&3Mã xác minh đã hết han! Hãy sử dụng một lệnh nhạy cảm để lấy mã mới.'
|
||||
email_needed: '&3Để xác định danh tính của bạn, bạn cần kết nối tài khoản này với 1 email!'
|
||||
|
||||
# Time units
|
||||
@ -147,7 +147,7 @@ time:
|
||||
two_factor:
|
||||
code_created: '&2Mã bí mật của bạn là %code. Bạn có thể quét nó tại đây %url'
|
||||
confirmation_required: 'Hãy xác thực mã của bạn bằng lệnh /2fa confirm <mã>'
|
||||
code_required: 'Hãy gửi đi mã xác thực 2 lớp của bạn bằng lệnh /2fa code <mã>'
|
||||
code_required: 'Hãy nhập mã xác thực 2 lớp của bạn bằng lệnh /2fa code <mã>'
|
||||
already_enabled: 'Xác thực 2 lớp đã được kích hoạt trên tài khoản của bạn!'
|
||||
enable_error_no_code: 'Không có mã xác thực nào đã được tạo cho tài khoản của bạn hoặc nó đã hết hạn. Hãy sử dụng lệnh /2fa add'
|
||||
enable_success: 'Đã thành công kích hoạt xác thực 2 lớp cho tài khoản của bạn!'
|
||||
|
@ -7,132 +7,132 @@
|
||||
|
||||
# Registration
|
||||
registration:
|
||||
disabled: '&b【AuthMe】&6已關閉註冊功能'
|
||||
name_taken: '&b【AuthMe】&6這個帳號已經被註冊過了!'
|
||||
disabled: '&b【AuthMe】&6已關閉註冊功能。'
|
||||
name_taken: '&b【AuthMe】&6這個帳號已經被註冊過了!'
|
||||
register_request: '&b【AuthMe】&6請使用 "&c/register <密碼> <確認密碼>" 來註冊。'
|
||||
command_usage: '&b【AuthMe】&6用法: &c"/register <密碼> <確認密碼>"'
|
||||
reg_only: '&b【AuthMe】&6請到下列網站 :「 https://example.tw 」 進行註冊'
|
||||
success: '&b【AuthMe】&6您已成功註冊'
|
||||
kicked_admin_registered: '&b【AuthMe】&6管理員已協助您註冊,請重新登入'
|
||||
reg_only: '&b【AuthMe】&6請到下列網站:「 https://example.tw 」進行註冊。'
|
||||
success: '&b【AuthMe】&6您已成功註冊!'
|
||||
kicked_admin_registered: '&b【AuthMe】&6管理員已協助您註冊,請重新登入。'
|
||||
|
||||
# Password errors on registration
|
||||
password:
|
||||
match_error: '&b【AuthMe】&6兩次輸入的密碼不一致!'
|
||||
name_in_password: '&b【AuthMe】&6您不可以用您的 ID (遊戲名稱) 來當作密碼 !'
|
||||
unsafe_password: '&b【AuthMe】&6您不可以使用這個不安全的密碼'
|
||||
forbidden_characters: '&b【AuthMe】&c密碼包含非法字符. 可使用: %valid_chars'
|
||||
match_error: '&b【AuthMe】&6兩次輸入的密碼不一致!'
|
||||
name_in_password: '&b【AuthMe】&6您不可以用您的 ID (遊戲名稱) 來當作密碼!'
|
||||
unsafe_password: '&b【AuthMe】&6您不可以使用這個不安全的密碼!'
|
||||
forbidden_characters: '&b【AuthMe】&c密碼包含非法字符,可使用:%valid_chars'
|
||||
wrong_length: '&b【AuthMe】&6您的密碼 超過最大字數 / 小於最小字數'
|
||||
|
||||
# Login
|
||||
login:
|
||||
command_usage: '&b【AuthMe】&6用法: &c"/login <密碼>"'
|
||||
wrong_password: '&b【AuthMe】&6密碼錯誤!'
|
||||
success: '&b【AuthMe】&6密碼正確,您已成功登入!'
|
||||
wrong_password: '&b【AuthMe】&6密碼錯誤!'
|
||||
success: '&b【AuthMe】&6密碼正確,您已成功登入!'
|
||||
login_request: '&b【AuthMe】&6請使用 &c"/login <密碼>" &6來登入。'
|
||||
timeout_error: '&b【AuthMe】&6超過登入時間,請稍後再試一次'
|
||||
timeout_error: '&b【AuthMe】&6超過登入時間,請稍後再試一次。'
|
||||
|
||||
# Errors
|
||||
error:
|
||||
denied_command: '&b【AuthMe】&c使用指令之前必須通過驗證!'
|
||||
denied_chat: '&b【AuthMe】&c說話之前必須通過驗證!'
|
||||
unregistered_user: '&b【AuthMe】&6這個帳號還沒有註冊過'
|
||||
not_logged_in: '&b【AuthMe】&6您還沒有登入!'
|
||||
denied_command: '&b【AuthMe】&c使用指令之前必須通過驗證!'
|
||||
denied_chat: '&b【AuthMe】&c說話之前必須通過驗證!'
|
||||
unregistered_user: '&b【AuthMe】&6這個帳號還沒有註冊過。'
|
||||
not_logged_in: '&b【AuthMe】&6您還沒有登入!'
|
||||
no_permission: '&b【AuthMe】&6您沒有使用該指令的權限。'
|
||||
unexpected_error: '&b【AuthMe】&6發生錯誤,請聯繫管理員'
|
||||
max_registration: '&b【AuthMe】&6您的 IP 位置所註冊的帳號數量已經達到最大。'
|
||||
logged_in: '&b【AuthMe】&6您已經登入了!'
|
||||
kick_for_vip: '&b【AuthMe】&6您已經被請出。&c原因 : 有 VIP 玩家登入伺服器'
|
||||
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||
tempban_max_logins: '&b【AuthMe】&c您已被暫時封鎖IP位置,因為您登入失敗太多次.'
|
||||
max_registration: '&b【AuthMe】&6您的 IP 位置所註冊的帳號數量已經達到最大限制。'
|
||||
logged_in: '&b【AuthMe】&6您已經登入了!'
|
||||
kick_for_vip: '&b【AuthMe】&6您已經被請出。&c原因:有 VIP 玩家登入伺服器'
|
||||
kick_unresolved_hostname: '&b【AuthMe】&6無法解析玩家主機名稱。'
|
||||
tempban_max_logins: '&b【AuthMe】&c您已被暫時封鎖IP位置,因為您登入失敗太多次。'
|
||||
|
||||
# AntiBot
|
||||
antibot:
|
||||
kick_antibot: '&b【AuthMe】&cAntiBotMod 正在啟用中,請稍後再嘗試登入吧!'
|
||||
auto_enabled: '&b【AuthMe】&6AntiBotMod 已自動啟用!'
|
||||
auto_disabled: '&b【AuthMe】&6AntiBotMod 將會於 &c%m &6分鐘後自動關閉'
|
||||
auto_enabled: '&b【AuthMe】&6AntiBotMod 已自動啟用!'
|
||||
auto_disabled: '&b【AuthMe】&6AntiBotMod 將於 &c%m &6分鐘後自動關閉'
|
||||
|
||||
# Unregister
|
||||
unregister:
|
||||
success: '&b【AuthMe】&6您已經成功註銷。'
|
||||
command_usage: '&b【AuthMe】&6用法: &c"/unregister <密碼>"'
|
||||
command_usage: '&b【AuthMe】&6用法:&c"/unregister <密碼>"'
|
||||
|
||||
# Other messages
|
||||
misc:
|
||||
account_not_activated: '&b【AuthMe】&6您的帳號還沒有經過驗證! 檢查看看您的電子信箱 (Email) 吧!'
|
||||
password_changed: '&b【AuthMe】&6密碼變更成功!'
|
||||
logout: '&b【AuthMe】&6您已成功登出'
|
||||
reload: '&b【AuthMe】&6已重新讀取設定檔及資料庫'
|
||||
usage_change_password: '&b【AuthMe】&6用法: &c"/changepassword <舊密碼> <新密碼>"'
|
||||
accounts_owned_self: '&b【AuthMe】&6您擁有 %count 個帳號:'
|
||||
accounts_owned_other: '&b【AuthMe】&6玩家 %name 擁有 %count 個帳號:'
|
||||
account_not_activated: '&b【AuthMe】&6您的帳號還沒有經過驗證!檢查看看您的電子郵件 (Email) 吧!'
|
||||
password_changed: '&b【AuthMe】&6密碼變更成功!'
|
||||
logout: '&b【AuthMe】&6您已成功登出。'
|
||||
reload: '&b【AuthMe】&6已重新讀取設定檔及資料庫。'
|
||||
usage_change_password: '&b【AuthMe】&6用法:&c"/changepassword <舊密碼> <新密碼>"'
|
||||
accounts_owned_self: '&b【AuthMe】&6您擁有 %count 個帳號:'
|
||||
accounts_owned_other: '&b【AuthMe】&6玩家 %name 擁有 %count 個帳號:'
|
||||
|
||||
# Session messages
|
||||
session:
|
||||
valid_session: '&b【AuthMe】&6您已經成功登入!'
|
||||
invalid_session: '&b【AuthMe】&6Session驗證不相符!'
|
||||
valid_session: '&b【AuthMe】&6您已經成功登入!'
|
||||
invalid_session: '&b【AuthMe】&6Session驗證不相符!'
|
||||
|
||||
# Error messages when joining
|
||||
on_join_validation:
|
||||
same_ip_online: '&b【AuthMe】&6同樣IP玩家在線上!'
|
||||
same_nick_online: '&b【AuthMe】&6有同樣帳號的玩家在線上!'
|
||||
name_length: '&b【AuthMe】&6您的暱稱 太長 / 太短 了!'
|
||||
same_ip_online: '&b【AuthMe】&6相同IP玩家在線上!'
|
||||
same_nick_online: '&b【AuthMe】&6有同樣帳號的玩家在線上!'
|
||||
name_length: '&b【AuthMe】&6您的暱稱 太長 / 太短 了!'
|
||||
characters_in_name: '&b【AuthMe】&6暱稱裡能使用的字符為: %valid_chars'
|
||||
kick_full_server: '&b【AuthMe】&6伺服器已經滿了,請等等再試一次'
|
||||
country_banned: '&b【AuthMe】&6您所在的地區無法進入此伺服器'
|
||||
kick_full_server: '&b【AuthMe】&6伺服器已經滿了,請等等再試一次。'
|
||||
country_banned: '&b【AuthMe】&6您所在的地區無法進入此伺服器。'
|
||||
not_owner_error: '&b【AuthMe】&4警告!&c您並不是此帳戶持有人,請立即登出。'
|
||||
invalid_name_case: '&b【AuthMe】&4警告!&c您應該使用「%valid」而並非「%invalid」登入遊戲。'
|
||||
# TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.'
|
||||
quick_command: '&b【AuthMe】&4指令使用過快,請加入伺服器後稍等一下再使用指令。'
|
||||
|
||||
# Email
|
||||
email:
|
||||
add_email_request: '&b【AuthMe】&6請使用 &c"/email add <您的Email> <再次輸入您的Email>" &6來添加 Email'
|
||||
usage_email_add: '&b【AuthMe】&6用法: &c"/email add <您的Email> <重複Email>"'
|
||||
usage_email_change: '&b【AuthMe】&6用法: &c"/email change <舊的Email> <新的Email>"'
|
||||
new_email_invalid: '&b【AuthMe】&6新的Email無效!'
|
||||
old_email_invalid: '&b【AuthMe】&6舊的Email無效!'
|
||||
invalid: '&b【AuthMe】&6無效的Email!'
|
||||
added: '&b【AuthMe】&6已添加Email!'
|
||||
# TODO add_not_allowed: '&cAdding email was not allowed'
|
||||
request_confirmation: '&b【AuthMe】&6請驗證您的Email!'
|
||||
changed: '&b【AuthMe】&6Email已變更!'
|
||||
# TODO change_not_allowed: '&cChanging email was not allowed'
|
||||
email_show: '&b【AuthMe】&2目前的電子郵件: &f%email'
|
||||
no_email_for_account: '&b【AuthMe】&2您目前沒有設置電子郵件.'
|
||||
already_used: '&b【AuthMe】&4這個電郵地址已被使用。'
|
||||
incomplete_settings: '&b【AuthMe】&4因為電子郵件設定無完整導致無法傳送,請聯絡管理員.'
|
||||
send_failure: '&b【AuthMe】&4無法傳送電子郵件,請聯絡管理員.'
|
||||
change_password_expired: '&b【AuthMe】&6您現在不能使用這個指令變更密碼了.'
|
||||
email_cooldown_error: '&b【AuthMe】&c電子郵件已經寄出了. 您只能在 %time 後才能傳送.'
|
||||
add_email_request: '&b【AuthMe】&6請使用 &c"/email add <電子郵件> <再次輸入電子郵件>" &6來新增電子郵件'
|
||||
usage_email_add: '&b【AuthMe】&6用法: &c"/email add <電子郵件> <再次輸入電子郵件>"'
|
||||
usage_email_change: '&b【AuthMe】&6用法: &c"/email change <舊的電子郵件> <新的電子郵件>"'
|
||||
new_email_invalid: '&b【AuthMe】&6新的電子郵件無效!'
|
||||
old_email_invalid: '&b【AuthMe】&6舊的電子郵件無效!'
|
||||
invalid: '&b【AuthMe】&6無效的電子郵件!'
|
||||
added: '&b【AuthMe】&6已新增電子郵件!'
|
||||
add_not_allowed: '&b【AuthMe】&c不允許新增電子郵件'
|
||||
request_confirmation: '&b【AuthMe】&6請驗證您的電子郵件!'
|
||||
changed: '&b【AuthMe】&6電子郵件已變更!'
|
||||
change_not_allowed: '&b【AuthMe】&c不允許變更電子郵件'
|
||||
email_show: '&b【AuthMe】&2目前的電子郵件:&f%email'
|
||||
no_email_for_account: '&b【AuthMe】&2您目前沒有設定電子郵件。'
|
||||
already_used: '&b【AuthMe】&4這個電子郵件已被使用。'
|
||||
incomplete_settings: '&b【AuthMe】&4因為電子郵件設定不完整導致無法傳送,請聯絡管理員。'
|
||||
send_failure: '&b【AuthMe】&4無法傳送電子郵件,請聯絡管理員。'
|
||||
change_password_expired: '&b【AuthMe】&6您現在不能使用這個指令變更密碼了。'
|
||||
email_cooldown_error: '&b【AuthMe】&c電子郵件已經寄出了,您只能在 %time 後才能傳送。'
|
||||
|
||||
# Password recovery by email
|
||||
recovery:
|
||||
forgot_password_hint: '&b【AuthMe】&6忘記密碼了嗎? 使用 &c"/email recovery <您的Email>"'
|
||||
command_usage: '&b【AuthMe】&6用法: &c"/email recovery <您的Email>"'
|
||||
email_sent: '&b【AuthMe】&6已經送出重設密碼要求至您的Email , 請查收。'
|
||||
forgot_password_hint: '&b【AuthMe】&6忘記密碼了嗎?使用 &c"/email recovery <電子郵件>"'
|
||||
command_usage: '&b【AuthMe】&6用法: &c"/email recovery <電子郵件>"'
|
||||
email_sent: '&b【AuthMe】&6已經送出重設密碼要求至您的電子郵件,請查收。'
|
||||
code:
|
||||
code_sent: '&b【AuthMe】&6忘記密碼的恢復密碼電子郵件已傳送至您的信箱中.'
|
||||
incorrect: '&b【AuthMe】&6恢復密碼錯誤! 您剩餘 %count 次嘗試機會.'
|
||||
tries_exceeded: '&b【AuthMe】&6恢復密碼過多次數錯誤. 使用 "/email recovery [email]" 取得新的恢復密碼.'
|
||||
correct: '&b【AuthMe】&6恢復密碼正確!'
|
||||
change_password: '&b【AuthMe】&6請使用 "/email setpassword <新密碼>" 變更您的密碼.'
|
||||
code_sent: '&b【AuthMe】&6忘記密碼的恢復密碼電子郵件已傳送至您的信箱中。'
|
||||
incorrect: '&b【AuthMe】&6恢復密碼錯誤!您剩餘 %count 次嘗試機會。'
|
||||
tries_exceeded: '&b【AuthMe】&6恢復密碼過多次數錯誤。使用 "/email recovery [電子郵件]" 取得新的恢復密碼。'
|
||||
correct: '&b【AuthMe】&6恢復密碼正確!'
|
||||
change_password: '&b【AuthMe】&6請使用 "/email setpassword <新密碼>" 變更您的密碼。'
|
||||
|
||||
# Captcha
|
||||
captcha:
|
||||
usage_captcha: '&b【AuthMe】&6請用 &c"/captcha %captcha_code" &6來輸入您的驗證碼.'
|
||||
wrong_captcha: '&b【AuthMe】&6錯誤的驗證碼,請使用 "/captcha %captcha_code" 再試一次.'
|
||||
valid_captcha: '&b【AuthMe】&6驗證碼無效!'
|
||||
# TODO captcha_for_registration: 'To register you have to solve a captcha first, please use the command: /captcha %captcha_code'
|
||||
# TODO register_captcha_valid: '&2Valid captcha! You may now register with /register'
|
||||
usage_captcha: '&b【AuthMe】&6請用 &c"/captcha %captcha_code" &6來輸入您的驗證碼。'
|
||||
wrong_captcha: '&b【AuthMe】&6錯誤的驗證碼,請使用 "/captcha %captcha_code" 再試一次。'
|
||||
valid_captcha: '&b【AuthMe】&6驗證碼無效。'
|
||||
captcha_for_registration: '&b【AuthMe】&6註冊前必須先提供驗證碼,使用 /captcha %captcha_code 來驗證。'
|
||||
register_captcha_valid: '&b【AuthMe】&2驗證已通過,現在可以使用 /register 來進行註冊了。'
|
||||
|
||||
# Verification code
|
||||
verification:
|
||||
code_required: '&b【AuthMe】&3敏感指令,需要電子郵件驗證後才能執行,請檢查電子郵件.'
|
||||
command_usage: '&b【AuthMe】&c用法: /verification <驗證碼>'
|
||||
code_required: '&b【AuthMe】&3敏感指令,需要電子郵件驗證後才能執行,請檢查電子郵件。'
|
||||
command_usage: '&b【AuthMe】&c用法:/verification <驗證碼>'
|
||||
incorrect_code: '&b【AuthMe】&c驗證碼錯誤,請在聊天室使用 "/verification <驗證碼>" 電子郵件收到的驗證碼'
|
||||
success: '&b【AuthMe】&2身分已驗證,您現在可以使用所有指令!'
|
||||
already_verified: '&b【AuthMe】&2您已經可以使用所有指令!'
|
||||
code_expired: '&b【AuthMe】&3驗證碼已過期,請使用其他敏感指令來取得新的驗證碼!'
|
||||
email_needed: '&b【AuthMe】&3若需要身分驗證,請先添加電子郵件!!'
|
||||
success: '&b【AuthMe】&2身分已驗證,您現在可以使用所有指令!'
|
||||
already_verified: '&b【AuthMe】&2您已經可以使用所有指令!'
|
||||
code_expired: '&b【AuthMe】&3驗證碼已過期,請使用其他敏感指令來取得新的驗證碼!'
|
||||
email_needed: '&b【AuthMe】&3若需要身分驗證,請先新增電子郵件!'
|
||||
|
||||
# Time units
|
||||
time:
|
||||
@ -147,13 +147,13 @@ time:
|
||||
|
||||
# Two-factor authentication
|
||||
two_factor:
|
||||
code_created: '&b【AuthMe - 兩步驗證碼】&b您的登入金鑰為&9「%c%code&9」&b,掃描連結為:&c %url'
|
||||
# TODO confirmation_required: 'Please confirm your code with /2fa confirm <code>'
|
||||
# TODO code_required: 'Please submit your two-factor authentication code with /2fa code <code>'
|
||||
# TODO already_enabled: 'Two-factor authentication is already enabled for your account!'
|
||||
# TODO enable_error_no_code: 'No 2fa key has been generated for you or it has expired. Please run /2fa add'
|
||||
# TODO enable_success: 'Successfully enabled two-factor authentication for your account'
|
||||
# TODO enable_error_wrong_code: 'Wrong code or code has expired. Please run /2fa add'
|
||||
# TODO not_enabled_error: 'Two-factor authentication is not enabled for your account. Run /2fa add'
|
||||
# TODO removed_success: 'Successfully removed two-factor auth from your account'
|
||||
# TODO invalid_code: 'Invalid code!'
|
||||
code_created: '&b【AuthMe】&b您的登入金鑰為&9「%c%code&9」&b,掃描連結為:&c %url'
|
||||
confirmation_required: '&b【AuthMe】&6請使用 /2fa confirm <驗證碼> 來確認雙重驗證。'
|
||||
code_required: '&b【AuthMe】&c請使用 /2fa code <驗證碼> 來完成驗證。'
|
||||
already_enabled: '&b【AuthMe】&c雙重驗證已經開啟。'
|
||||
enable_error_no_code: '&b【AuthMe】&6雙重驗證代碼不存在或失效,使用 /2fa add 來新增。'
|
||||
enable_success: '&b【AuthMe】&6雙重驗證已開啟!'
|
||||
enable_error_wrong_code: '&b【AuthMe】&6雙重驗證代碼錯誤或失效,使用 /2fa add 來新增。'
|
||||
not_enabled_error: '&b【AuthMe】&6雙重驗證尚未開啟,使用 /2fa add 來開啟。'
|
||||
removed_success: '&b【AuthMe】&6雙重驗證已成功移除!'
|
||||
invalid_code: '&b【AuthMe】&c驗證碼錯誤。'
|
||||
|
@ -12,13 +12,13 @@ import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* AuthMe test utilities.
|
||||
@ -99,11 +99,14 @@ public final class TestHelper {
|
||||
* @param player the player mock
|
||||
* @param ip the ip address it should return
|
||||
*/
|
||||
public static void mockPlayerIp(Player player, String ip) {
|
||||
InetAddress inetAddress = mock(InetAddress.class);
|
||||
given(inetAddress.getHostAddress()).willReturn(ip);
|
||||
InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 8093);
|
||||
given(player.getAddress()).willReturn(inetSocketAddress);
|
||||
public static void mockIpAddressToPlayer(Player player, String ip) {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(ip);
|
||||
InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 8093);
|
||||
given(player.getAddress()).willReturn(inetSocketAddress);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new IllegalStateException("Invalid IP address: " + ip, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,7 @@ import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -241,6 +242,12 @@ class AuthMeApiTest {
|
||||
assertThat(result, equalTo(Instant.ofEpochMilli(1501597979L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastLoginMillis() {
|
||||
AuthMeApi result = AuthMeApi.getInstance();
|
||||
assertThat(result.getLastLoginTime("notAPlayer"), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleNullLastLoginTime() {
|
||||
// given
|
||||
@ -451,7 +458,7 @@ class AuthMeApiTest {
|
||||
String name = "Marco";
|
||||
String password = "myP4ss";
|
||||
HashedPassword hashedPassword = new HashedPassword("0395872SLKDFJOWEIUTEJSD");
|
||||
given(passwordSecurity.computeHash(password, name.toLowerCase())).willReturn(hashedPassword);
|
||||
given(passwordSecurity.computeHash(password, name.toLowerCase(Locale.ROOT))).willReturn(hashedPassword);
|
||||
given(dataSource.saveAuth(any(PlayerAuth.class))).willReturn(true);
|
||||
|
||||
// when
|
||||
@ -459,10 +466,10 @@ class AuthMeApiTest {
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
verify(passwordSecurity).computeHash(password, name.toLowerCase());
|
||||
verify(passwordSecurity).computeHash(password, name.toLowerCase(Locale.ROOT));
|
||||
ArgumentCaptor<PlayerAuth> authCaptor = ArgumentCaptor.forClass(PlayerAuth.class);
|
||||
verify(dataSource).saveAuth(authCaptor.capture());
|
||||
assertThat(authCaptor.getValue().getNickname(), equalTo(name.toLowerCase()));
|
||||
assertThat(authCaptor.getValue().getNickname(), equalTo(name.toLowerCase(Locale.ROOT)));
|
||||
assertThat(authCaptor.getValue().getRealName(), equalTo(name));
|
||||
assertThat(authCaptor.getValue().getPassword(), equalTo(hashedPassword));
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
@ -90,7 +91,7 @@ class CommandInitializerTest {
|
||||
@Override
|
||||
public void accept(CommandDescription command, Integer depth) {
|
||||
for (String label : command.getLabels()) {
|
||||
if (!label.equals(label.toLowerCase())) {
|
||||
if (!label.equals(label.toLowerCase(Locale.ROOT))) {
|
||||
fail("Label '" + label + "' should be lowercase");
|
||||
} else if (invalidPattern.matcher(label).matches()) {
|
||||
fail("Label '" + label + "' has whitespace");
|
||||
@ -137,11 +138,11 @@ class CommandInitializerTest {
|
||||
String forCommandText = " for command with labels '" + command.getLabels() + "'";
|
||||
|
||||
assertThat("has description" + forCommandText,
|
||||
StringUtils.isEmpty(command.getDescription()), equalTo(false));
|
||||
StringUtils.isBlank(command.getDescription()), equalTo(false));
|
||||
assertThat("short description doesn't end in '.'" + forCommandText,
|
||||
command.getDescription().endsWith("."), equalTo(false));
|
||||
assertThat("has detailed description" + forCommandText,
|
||||
StringUtils.isEmpty(command.getDetailedDescription()), equalTo(false));
|
||||
StringUtils.isBlank(command.getDetailedDescription()), equalTo(false));
|
||||
assertThat("detailed description ends in '.'" + forCommandText,
|
||||
command.getDetailedDescription().endsWith("."), equalTo(true));
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -92,7 +93,7 @@ class ConverterCommandTest {
|
||||
// when / then
|
||||
for (Map.Entry<String, Class<? extends Converter>> entry : ConverterCommand.CONVERTERS.entrySet()) {
|
||||
assertThat("Name is not null or empty",
|
||||
StringUtils.isEmpty(entry.getKey()), equalTo(false));
|
||||
StringUtils.isBlank(entry.getKey()), equalTo(false));
|
||||
|
||||
assertThat("Converter class is unique for each entry",
|
||||
classes.add(entry.getValue()), equalTo(true));
|
||||
@ -129,7 +130,7 @@ class ConverterCommandTest {
|
||||
setBukkitServiceToRunTaskAsynchronously(bukkitService);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(converterName.toUpperCase()));
|
||||
command.executeCommand(sender, Collections.singletonList(converterName.toUpperCase(Locale.ROOT)));
|
||||
|
||||
// then
|
||||
verify(converter).execute(sender);
|
||||
|
@ -100,7 +100,7 @@ class GetIpCommandTest {
|
||||
private static Player mockPlayer(String name, String ip) {
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
TestHelper.mockPlayerIp(player, ip);
|
||||
TestHelper.mockIpAddressToPlayer(player, ip);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.collect.Sets.newHashSet;
|
||||
@ -67,7 +68,7 @@ class PurgeBannedPlayersCommandTest {
|
||||
private static Set<String> asLowerCaseSet(String... items) {
|
||||
Set<String> result = new HashSet<>(items.length);
|
||||
for (String item : items) {
|
||||
result.add(item.toLowerCase());
|
||||
result.add(item.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToRunTaskAsynchronously;
|
||||
import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToRunTaskOptionallyAsync;
|
||||
import static java.util.Arrays.asList;
|
||||
@ -71,7 +73,7 @@ class PurgePlayerCommandTest {
|
||||
|
||||
// then
|
||||
verify(dataSource).isAuthAvailable(name);
|
||||
verify(purgeExecutor).executePurge(singletonList(player), singletonList(name.toLowerCase()));
|
||||
verify(purgeExecutor).executePurge(singletonList(player), singletonList(name.toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -87,6 +89,6 @@ class PurgePlayerCommandTest {
|
||||
command.executeCommand(sender, asList(name, "force"));
|
||||
|
||||
// then
|
||||
verify(purgeExecutor).executePurge(singletonList(player), singletonList(name.toLowerCase()));
|
||||
verify(purgeExecutor).executePurge(singletonList(player), singletonList(name.toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user