Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89df4e451c | |||
| fe39310eca | |||
| b9790d458e | |||
| dc8d5f741a | |||
| b3288e9c72 | |||
| c88aa79377 | |||
| 2327c07f9a | |||
| 8e93d4cd19 | |||
| a963bde749 | |||
| 10b6997c32 | |||
| 970c77678b | |||
| 07c479746b | |||
| d90a8a36cf | |||
| c1eee8e139 | |||
| dd831a65a5 | |||
| 51783604c6 | |||
| 9f8471d4e9 | |||
| c4ac2601ad | |||
| b4a0994871 | |||
| b619e1dac5 | |||
| ba1703c684 | |||
| 131b5b7805 | |||
| 099415e823 | |||
| 91261f4315 | |||
| 548be5042d | |||
| e9fd7fd80f | |||
| e44cd3edc6 | |||
| 219a7a3493 | |||
| 6876a6dd9f | |||
| d04a69f481 | |||
| dfa8317706 | |||
| 555514f7dd | |||
| 74633937bc | |||
| 948736b5ea | |||
| 5e54b8b105 | |||
| 0d818dd00f | |||
| 22586e601f | |||
| 9938df3c28 | |||
| ec2e8d3654 | |||
| 71a9c0c98f | |||
| 54cef57ea5 | |||
| 73c1116047 | |||
| abb85f005d | |||
| 5e91ee9844 | |||
| 8e781651a9 | |||
| 74db202cd9 | |||
| 26b3b3ea78 | |||
| bfc2197089 | |||
| 49c515169e | |||
| d9c04a58c0 | |||
| 57be7b2dfe | |||
| 07b62d4bf2 | |||
| 726aead1c1 | |||
| a1af29dff9 | |||
| 388e80ee92 | |||
| 7d09faf528 | |||
| f2876d79fb | |||
| 1155bed754 | |||
| c6278b17e9 | |||
| 3a0d5f6347 | |||
| 7e6d511ae4 | |||
| f35ac01399 | |||
| 64807852ff | |||
| 342d9c96ee | |||
| eaa0cdd600 | |||
| 7507fb9ea2 | |||
| 839e192711 | |||
| 2ad33f4567 | |||
| 8db573a789 | |||
| c50a413fcd | |||
| 6a96d993e1 | |||
| a93f0546e3 |
@@ -47,8 +47,10 @@ body:
|
|||||||
description: Which server implementation are you using?
|
description: Which server implementation are you using?
|
||||||
multiple: false
|
multiple: false
|
||||||
options:
|
options:
|
||||||
- Standalone server (no proxy)
|
- Standalone(Spigot)
|
||||||
|
- Standalone(Folia)
|
||||||
- BungeeCord
|
- BungeeCord
|
||||||
|
- Velocity
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@@ -60,6 +62,9 @@ body:
|
|||||||
options:
|
options:
|
||||||
- SQLite
|
- SQLite
|
||||||
- MySQL
|
- MySQL
|
||||||
|
- H2
|
||||||
|
- MariaDB
|
||||||
|
- PostgreSQL
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Feature request
|
name: Feature request
|
||||||
description: Suggest an idea for AuthMe
|
description: Suggest an idea for AuthMe
|
||||||
labels: 'Type: enhancement'
|
labels: 'enhancement'
|
||||||
|
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ jobs:
|
|||||||
Build:
|
Build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
jdkversion: [ 17 ]
|
jdkversion: [ 21 ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: ${{ matrix.jdkversion }}
|
java-version: ${{ matrix.jdkversion }}
|
||||||
@@ -22,10 +22,10 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: mvn -V -B clean package --file pom.xml
|
run: mvn -V -B clean package --file pom.xml
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v3.1.2
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: Download
|
name: Download
|
||||||
path: ./target/AuthMe-5.6.0-FORK-Spigot-Universal.jar
|
path: ./target/AuthMe-5.6.0-FORK-Universal.jar
|
||||||
runtime-test:
|
runtime-test:
|
||||||
name: Plugin Runtime Test
|
name: Plugin Runtime Test
|
||||||
needs: [Build]
|
needs: [Build]
|
||||||
@@ -37,8 +37,10 @@ jobs:
|
|||||||
javaVersion: '8'
|
javaVersion: '8'
|
||||||
- mcVersion: '1.12.2'
|
- mcVersion: '1.12.2'
|
||||||
javaVersion: '8'
|
javaVersion: '8'
|
||||||
- mcVersion: '1.20.2'
|
- mcVersion: '1.18.2'
|
||||||
javaVersion: '20'
|
javaVersion: '17'
|
||||||
|
- mcVersion: '1.20.4'
|
||||||
|
javaVersion: '21'
|
||||||
steps:
|
steps:
|
||||||
- uses: HaHaWTH/minecraft-plugin-runtime-test@paper
|
- uses: HaHaWTH/minecraft-plugin-runtime-test@paper
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -114,3 +114,4 @@ nb-configuration.xml
|
|||||||
### Git ###
|
### Git ###
|
||||||
# Don't exclude the .gitignore itself
|
# Don't exclude the .gitignore itself
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
/samples/
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# AuthMeReReloaded
|
||||||
|
**"Bukkit 的最佳身份验证插件的分支!"**
|
||||||
|
|
||||||
|

|
||||||
|
<p align="center">
|
||||||
|
<img src="https://img.shields.io/github/languages/code-size/HaHaWTH/AuthMeReReloaded.svg" alt="Code size"/>
|
||||||
|
<img src="https://img.shields.io/github/repo-size/HaHaWTH/AuthMeReReloaded.svg" alt="GitHub repo size"/>
|
||||||
|
<img src="https://www.codefactor.io/repository/github/hahawth/authmerereloaded/badge" alt="CodeFactor" />
|
||||||
|
<img src="https://img.shields.io/github/downloads/HaHaWTH/AuthMeReReloaded/total" alt="Downloads" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
**详细改动:**
|
||||||
|
1. 改进邮件发送逻辑,支持更多邮件
|
||||||
|
2. 关闭邮件发送(当服务器关闭时,向您发送邮件)
|
||||||
|
3. 原有漏洞修复
|
||||||
|
4. 反幽灵玩家(重复登录错误)
|
||||||
|
5. 按服务器分支使用最佳性能方法
|
||||||
|
6. 基岩兼容性(需要Floodgate)(基于 UUID)
|
||||||
|
7. 更新检查器
|
||||||
|
8. 集成 GUI 验证码功能(需要 Bedrock 兼容性和 ProtocolLib)(70% 异步)
|
||||||
|
9. 改进监听器
|
||||||
|
10. 改进玩家登录逻辑以减少延迟
|
||||||
|
11. 自动清除机器人数据
|
||||||
|
12. 支持**Folia(正在测试中)**
|
||||||
|
13. F键菜单兼容
|
||||||
|
14. 自动修复传送卡传送门/地底问题
|
||||||
|
15. **Velocity支持 (详见 [Velocity Support](./vc-support.md))**
|
||||||
|
16. 基岩版玩家自动登录(可配置)
|
||||||
|
17. 修复旧版本(MC 1.13-)中的 "潜影盒 "崩溃问题
|
||||||
|
18. 支持 **H2 数据库**
|
||||||
|
19. 虚拟线程支持
|
||||||
|
20. **100% 兼容原版 authme 和扩展**
|
||||||
|
21. 更多......
|
||||||
|
|
||||||
|
**下载链接:**
|
||||||
|
[Release](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest)
|
||||||
|
[Actions(开发版,使用风险自负!)](https://github.com/HaHaWTH/AuthMeReReloaded/actions/workflows/maven.yml)
|
||||||
|
|
||||||
|
如果您的服务器使用 FRP(内网穿透),此插件可能会有所帮助 [HAProxy-Detector](https://github.com/HaHaWTH/HAProxy-Detector)
|
||||||
|
|
||||||
|
**欢迎提出请求和建议!**
|
||||||
|
|
||||||
|
<picture>
|
||||||
|
<source
|
||||||
|
media="(prefers-color-scheme: dark)"
|
||||||
|
srcset="
|
||||||
|
https://api.star-history.com/svg?repos=HaHaWTH/AuthMeReReloaded&type=Date&theme=dark
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=HaHaWTH/AuthMeReReloaded&type=Date" />
|
||||||
|
</picture>
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
# AuthMeReReloaded
|
# AuthMeReReloaded
|
||||||
**"A fork of the best authentication plugin for the Bukkit modding API!⭐"**
|
**"A fork of the best authentication plugin for the Bukkit modding API!⭐"**
|
||||||
|
|
||||||
|
[English](https://github.com/HaHaWTH/AuthMeReReloaded) | [简体中文](https://github.com/HaHaWTH/AuthMeReReloaded/blob/master/README-zh.md)
|
||||||
|
|
||||||

|

|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/github/languages/code-size/HaHaWTH/AuthMeReReloaded.svg" alt="Code size"/>
|
<img src="https://img.shields.io/github/languages/code-size/HaHaWTH/AuthMeReReloaded.svg" alt="Code size"/>
|
||||||
<img src="https://img.shields.io/github/repo-size/HaHaWTH/AuthMeReReloaded.svg" alt="GitHub repo size"/>
|
<img src="https://img.shields.io/github/repo-size/HaHaWTH/AuthMeReReloaded.svg" alt="GitHub repo size"/>
|
||||||
<img src="https://www.codefactor.io/repository/github/hahawth/authmerereloaded/badge" alt="CodeFactor" />
|
<img src="https://www.codefactor.io/repository/github/hahawth/authmerereloaded/badge" alt="CodeFactor" />
|
||||||
|
<img alt="GitHub Downloads (all assets, all releases)" src="https://img.shields.io/github/downloads/HaHaWTH/AuthMeReReloaded/total?logo=github&label=GitHub%20Downloads&color=black">
|
||||||
|
<img alt="Spiget Downloads" src="https://img.shields.io/spiget/downloads/114010?logo=spigotmc&label=SpigotMC%20Downloads&color=orange">
|
||||||
|
<img alt="Modrinth Downloads" src="https://img.shields.io/modrinth/dt/3IEZ9vol?logo=modrinth&label=Modrinth%20Downloads&color=light-green">
|
||||||
|
<img alt="Hangar Downloads" src="https://img.shields.io/hangar/dt/AuthMeReReloaded?logo=hangar&label=Hangar%20Downloads&color=white">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**Detailed Changes:**
|
**Detailed Changes:**
|
||||||
@@ -20,14 +26,16 @@
|
|||||||
9. Improved listeners
|
9. Improved listeners
|
||||||
10. Player login logic improvement to reduce lag
|
10. Player login logic improvement to reduce lag
|
||||||
11. Automatically purge bot data
|
11. Automatically purge bot data
|
||||||
12. Folia compatibility (Still WIP)
|
12. **Folia support (in active testing)**
|
||||||
13. Offhand Menu compatibility(Thats amazing)
|
13. Offhand Menu compatibility(Thats amazing)
|
||||||
14. Automatically fix portal stuck issue
|
14. **Velocity support (See [Velocity Support](./vc-support.md))**
|
||||||
15. Automatically login for Bedrock players(configurable)
|
15. Support Virtual Threads caching
|
||||||
16. Fix shulker box crash bug on legacy versions(MC 1.13-)
|
16. Automatically fix portal stuck issue
|
||||||
17. **H2 database support**
|
17. Automatically login for Bedrock players(configurable)
|
||||||
18. **100% compatibility with original authme and extensions**
|
18. Fix shulker box crash bug on legacy versions(MC 1.13-)
|
||||||
19. More......
|
19. **H2 database support**
|
||||||
|
20. **100% compatibility with original authme and extensions**
|
||||||
|
21. More......
|
||||||
|
|
||||||
**Download links:**
|
**Download links:**
|
||||||
[Releases](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest)
|
[Releases](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest)
|
||||||
@@ -37,6 +45,10 @@ If you are using FRP(内网穿透) for your server, this plugin may help [HAProx
|
|||||||
|
|
||||||
**Pull Requests and suggestions are welcome!**
|
**Pull Requests and suggestions are welcome!**
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Only additions to AuthMeReloaded is under AGPL-3.0 license, AuthMeReloaded is licensed under GPL-3.0.
|
||||||
|
|
||||||
<picture>
|
<picture>
|
||||||
<source
|
<source
|
||||||
media="(prefers-color-scheme: dark)"
|
media="(prefers-color-scheme: dark)"
|
||||||
|
|||||||
@@ -82,54 +82,11 @@
|
|||||||
<pluginDescription.authors>sgdc3, games647, Hex3l, krusic22</pluginDescription.authors>
|
<pluginDescription.authors>sgdc3, games647, Hex3l, krusic22</pluginDescription.authors>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- Jenkins profile -->
|
|
||||||
<profiles>
|
|
||||||
<!-- Set the buildNumber using the jenkins env. variable -->
|
|
||||||
<profile>
|
|
||||||
<id>jenkins</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>env.BUILD_NUMBER</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<project.buildNumber>${env.BUILD_NUMBER}</project.buildNumber>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
<!-- Skip long hash tests, reduce the test time of 20-30 seconds -->
|
|
||||||
<profile>
|
|
||||||
<id>skipLongHashTests</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>skipLongHashTests</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<project.skipExtendedHashTests>true</project.skipExtendedHashTests>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
<!-- Skip javadoc generation for faster local build -->
|
|
||||||
<profile>
|
|
||||||
<id>skipJavadocGeneration</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<skip>true</skip>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<defaultGoal>clean package</defaultGoal>
|
<defaultGoal>clean package</defaultGoal>
|
||||||
<!-- Little hack to make the shade plugin output a file with the right name -->
|
<!-- Little hack to make the shade plugin output a file with the right name -->
|
||||||
<finalName>${project.finalNameBase}-noshade</finalName>
|
<finalName>${project.finalNameBase}-noshade</finalName>
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>.</directory>
|
<directory>.</directory>
|
||||||
@@ -222,7 +179,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.11</version>
|
<version>0.8.12</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>pre-unit-test</id>
|
<id>pre-unit-test</id>
|
||||||
@@ -258,7 +215,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>3.4.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Generate a jar containing the source javadoc -->
|
<!-- Generate a jar containing the source javadoc -->
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -282,7 +239,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>3.3.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<finalName>${project.finalNameBase}</finalName>
|
<finalName>${project.finalNameBase}</finalName>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -299,7 +256,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.5.2</version>
|
<version>3.5.3</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>shaded-jar</id>
|
<id>shaded-jar</id>
|
||||||
@@ -308,6 +265,7 @@
|
|||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<finalName>${project.finalNameBase}-Lite</finalName>
|
||||||
<artifactSet>
|
<artifactSet>
|
||||||
<excludes>
|
<excludes>
|
||||||
<!-- Guava -->
|
<!-- Guava -->
|
||||||
@@ -320,16 +278,60 @@
|
|||||||
<exclude>com.google.code.gson:gson</exclude>
|
<exclude>com.google.code.gson:gson</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</artifactSet>
|
</artifactSet>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.h2</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.org.h2</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.apache.http</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.org.apache.http</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.apache.commons</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.org.apache.commons</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>javax.activation</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.javax.activation</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>javax.annotation</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.javax.annotation</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>javax.mail</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.javax.mail</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>waffle</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.waffle</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.github.benmanes.caffeine</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.com.github.benmanes.caffeine</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>META-INF/*.SF</exclude>
|
||||||
|
<exclude>META-INF/*.DSA</exclude>
|
||||||
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>shaded-jar-legacy</id>
|
<id>shaded-jar-relocate</id>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<finalName>${project.finalNameBase}-Spigot-Universal</finalName>
|
<finalName>${project.finalNameBase}-Universal</finalName>
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>com.google.common</pattern>
|
<pattern>com.google.common</pattern>
|
||||||
@@ -355,6 +357,34 @@
|
|||||||
<pattern>org.h2</pattern>
|
<pattern>org.h2</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.org.h2</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.org.h2</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.apache.http</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.org.apache.http</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.apache.commons</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.org.apache.commons</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>javax.activation</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.javax.activation</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>javax.annotation</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.javax.annotation</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>javax.mail</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.javax.mail</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>waffle</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.waffle</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.github.benmanes.caffeine</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.com.github.benmanes.caffeine</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
@@ -709,7 +739,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-email</artifactId>
|
<artifactId>commons-email</artifactId>
|
||||||
<version>1.6.0</version>
|
<version>1.6-SNAPSHOT</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -1126,9 +1156,9 @@
|
|||||||
|
|
||||||
<!-- Universal Scheduler -->
|
<!-- Universal Scheduler -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.HomoMC</groupId>
|
<groupId>com.github.Anon8281</groupId>
|
||||||
<artifactId>UniversalScheduler</artifactId>
|
<artifactId>UniversalScheduler</artifactId>
|
||||||
<version>0.1.7</version>
|
<version>0.1.6</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -1136,7 +1166,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xerial</groupId>
|
<groupId>org.xerial</groupId>
|
||||||
<artifactId>sqlite-jdbc</artifactId>
|
<artifactId>sqlite-jdbc</artifactId>
|
||||||
<version>3.45.2.0</version>
|
<version>3.45.3.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -1,564 +0,0 @@
|
|||||||
# =======================================================================================================
|
|
||||||
# _____ __ .__ _____ __________ .__ .___ .___
|
|
||||||
# / _ \ __ ___/ |_| |__ / \ ____\______ \ ____ | | _________ __| _/____ __| _/
|
|
||||||
# / /_\ \| | \ __| | \ / \ / \_/ __ \| __/ __ \| | / _ \__ \ / __ _/ __ \ / __ |
|
|
||||||
# / | | | /| | | Y / Y \ ___/| | \ ___/| |_( <_> / __ \/ /_/ \ ___// /_/ |
|
|
||||||
# \____|__ |____/ |__| |___| \____|__ /\___ |____|_ /\___ |____/\____(____ \____ |\___ \____ |
|
|
||||||
# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
|
|
||||||
#
|
|
||||||
# =======================================================================================================
|
|
||||||
#
|
|
||||||
# Authme Main Configuration File.
|
|
||||||
#
|
|
||||||
# =======================================================================================================
|
|
||||||
|
|
||||||
# Plugin infos (overwritten on start, just a simple way to find out your plugin version).
|
|
||||||
authors: ${pluginAuthors}
|
|
||||||
version: ${project.version}
|
|
||||||
buildNumber: ${buildNumber}
|
|
||||||
|
|
||||||
# Set this setting to true when you have configured the plugin,
|
|
||||||
# when false the server will be stopped with a warning message.
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Database settings.
|
|
||||||
data_source:
|
|
||||||
# ===========================
|
|
||||||
# Database general settings.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
# Database backend (sqlite, mysql).
|
|
||||||
backend: sqlite
|
|
||||||
# Enable database queries caching, should improve performance.
|
|
||||||
caching: true
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# SqLite db parameters.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
sqlite:
|
|
||||||
# The name of the database storage file.
|
|
||||||
filename: 'authme.db'
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# MySql db parameters.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
mysql:
|
|
||||||
# Connection parameters.
|
|
||||||
host: '127.0.0.1'
|
|
||||||
port: 3306
|
|
||||||
username: 'change_me'
|
|
||||||
password: 'change_me'
|
|
||||||
database: 'my_minecraft_server'
|
|
||||||
tablename: 'authme'
|
|
||||||
|
|
||||||
# Column names.
|
|
||||||
column_names:
|
|
||||||
id: id
|
|
||||||
# Column for storing nicknames (ignore case nickname).
|
|
||||||
name: username
|
|
||||||
# Column for storing the realname (case sensitive nickname).
|
|
||||||
real_name: realname
|
|
||||||
# Column for storing passwords.
|
|
||||||
password: password
|
|
||||||
# Column for storing email addresses.
|
|
||||||
email: email
|
|
||||||
# Column for storing the authentication status (logged or not).
|
|
||||||
login_status: isLogged
|
|
||||||
# Column for storing player IPs.
|
|
||||||
ip: ip
|
|
||||||
# Column for storing lastlogins date and time.
|
|
||||||
last_login_timestamp: lastlogin
|
|
||||||
# Latest logout location of the players.
|
|
||||||
last_location:
|
|
||||||
world: world
|
|
||||||
x: x
|
|
||||||
y: y
|
|
||||||
z: z
|
|
||||||
# Enabled only if the bungeecord integration is activated.
|
|
||||||
server: world
|
|
||||||
|
|
||||||
# Support for registrations via WebInterfaces/CSM.
|
|
||||||
# Disable some backend caching parameters.
|
|
||||||
disableAggressiveCaching: false
|
|
||||||
|
|
||||||
# Main settings
|
|
||||||
settings:
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Bungeecord integration
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
bungeecord:
|
|
||||||
# Enable bungeecord integration features
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Server name (must be unique, please use the name in the bungeecord configuration).
|
|
||||||
# Use 'auto' for auto configuration (requires the bungeecord module).
|
|
||||||
serverName: LoginLobby1
|
|
||||||
# Keep the auth status when the player moves between servers.
|
|
||||||
# Required if you're using the bungeecord module.
|
|
||||||
keepAuthBetweenServers: true
|
|
||||||
|
|
||||||
# Target server after login
|
|
||||||
send_after_login:
|
|
||||||
enabled: false
|
|
||||||
message: ''
|
|
||||||
delay: 5
|
|
||||||
# Server name ("ServerName") or group ("G:GroupName")
|
|
||||||
# Groups are avariable only when the bungeecord module is avariable.
|
|
||||||
# If the server change fails the player will be kicked.
|
|
||||||
target: Lobby1
|
|
||||||
failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
|
|
||||||
# Target server after logout
|
|
||||||
send_after_logout:
|
|
||||||
enabled: false
|
|
||||||
message: ''
|
|
||||||
delay: 5
|
|
||||||
# Server name ("ServerName") or group ("G:GroupName")
|
|
||||||
# Groups are avariable only when the bungeecord module is avariable.
|
|
||||||
# If the server change fails the player will be kicked.
|
|
||||||
target: LoginLobby1
|
|
||||||
failKickMessage: 'Failed to connect to the lobby! Please try to join the server again!'
|
|
||||||
|
|
||||||
# Variables:
|
|
||||||
# %p playername
|
|
||||||
bungee_commands:
|
|
||||||
player_command_after_register:
|
|
||||||
enabled: false
|
|
||||||
cmd: ''
|
|
||||||
console_command_after_register:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p joined for the first time the network!'
|
|
||||||
player_command_after_login:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'glist'
|
|
||||||
console_command_after_login:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p logged in correctly!'
|
|
||||||
player_command_after_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: ''
|
|
||||||
console_command_after_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p joined the network!'
|
|
||||||
player_command_first_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: ''
|
|
||||||
console_command_first_join:
|
|
||||||
enabled: false
|
|
||||||
cmd: 'alert %p joined for the first time the network!'
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Sessions configuration.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
sessions:
|
|
||||||
# Enable sessions.
|
|
||||||
# When a player is authenticated, his IP and his nickname is saved.
|
|
||||||
# The next time the player will join the server, if his IP is the same
|
|
||||||
# of the last time, and the timeout time hasn't expired, he will be
|
|
||||||
# automatically authenticated.
|
|
||||||
enabled: false
|
|
||||||
# Session timeout.
|
|
||||||
# 0 for unlimited time (Very dangerous, use it at your own risk!)
|
|
||||||
# Consider that if player's ip has changed but the timeout hasn't
|
|
||||||
# expired, player will be kicked out of the sever!
|
|
||||||
timeout: 10
|
|
||||||
# When enabled a player's session will expire if someone tries to
|
|
||||||
# login with a different IP Address.
|
|
||||||
expire_on_ip_change: true
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Registration settings.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
registration:
|
|
||||||
# After how many time unregistered players should be kicked?
|
|
||||||
# Set to 0 to disable. (default: 30)
|
|
||||||
timeout: 30
|
|
||||||
|
|
||||||
nickname:
|
|
||||||
min_length: 4
|
|
||||||
max_lenght: 16
|
|
||||||
# Regex syntax.
|
|
||||||
allowed_characters: '[a-zA-Z0-9_]*'
|
|
||||||
|
|
||||||
password:
|
|
||||||
# Enable double check of password on registration:
|
|
||||||
# /register <password> <confirmPassword>
|
|
||||||
double_check: true
|
|
||||||
# Minimum password lenght.
|
|
||||||
min_length: 5
|
|
||||||
# Regex syntax.
|
|
||||||
allowed_characters: '[\x21-\x7E]*'
|
|
||||||
# Denied unsafe passwords.
|
|
||||||
unsafePasswords:
|
|
||||||
- '123456'
|
|
||||||
- 'password'
|
|
||||||
- 'qwerty'
|
|
||||||
- '12345'
|
|
||||||
- '54321'
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Login settings.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
login:
|
|
||||||
# After how many time unlogged players should be kicked?
|
|
||||||
# Set to 0 to disable. (default: 30)
|
|
||||||
timeout: 30
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Encryption parameters.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
password_encryption:
|
|
||||||
# The hashing algorithm.
|
|
||||||
# Possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB, MYBB, IPB3,
|
|
||||||
# PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, DOUBLEMD5,
|
|
||||||
# PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (developpers only).
|
|
||||||
encryption_algorithm: SHA256
|
|
||||||
# The salt length for the SALTED2MD5 and MD5(MD5(password)+salt) algorithms.
|
|
||||||
md5_salt_length: 8
|
|
||||||
# If password check fails try all the other hash algorithm.
|
|
||||||
# AuthMe will update the password to the new passwordHash.
|
|
||||||
enable_convertion: false
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Unlogged user restrictions.
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
unlogged_restrictions:
|
|
||||||
# Deny chat messages send for unlogged users.
|
|
||||||
deny_chat: true
|
|
||||||
# Hide chat to unlogged users.
|
|
||||||
# Only player messages, plugins will be able to send messages to the player anyway.
|
|
||||||
hide_chat: false
|
|
||||||
|
|
||||||
# Deny any command message not in the whitelist below.
|
|
||||||
deny_commands: true
|
|
||||||
command_whitelist:
|
|
||||||
- /login
|
|
||||||
- /register
|
|
||||||
- /l
|
|
||||||
- /reg
|
|
||||||
- /email
|
|
||||||
- /captcha
|
|
||||||
|
|
||||||
movements:
|
|
||||||
# Restrict player movements.
|
|
||||||
restrict: true
|
|
||||||
# Allowed radius.
|
|
||||||
allowed_radius: 0
|
|
||||||
# Should unlogged players have speed = 0?
|
|
||||||
# After the login the walking/flying speeed will be reset to the default value.
|
|
||||||
removeSpeed: true
|
|
||||||
|
|
||||||
# End is there atm xD
|
|
||||||
|
|
||||||
# This option will save the quit location of the players.
|
|
||||||
SaveQuitLocation: false
|
|
||||||
# Should not logged in players be teleported to the spawn?
|
|
||||||
# After the authentication, if SaveQuitLocation is enabled,
|
|
||||||
# they will be teleported back to their normal position.
|
|
||||||
teleportUnAuthedToSpawn: false
|
|
||||||
|
|
||||||
# If enabled, after the login, if the ForceSpawnOnTheseWorlds setting contains
|
|
||||||
# the player's world, he will be teleported to the world spawnpoint.
|
|
||||||
# The quit location of the player will be overwritten.
|
|
||||||
# This is different from "teleportUnAuthedToSpawn" that teleports player
|
|
||||||
# back to his quit location after the authentication.
|
|
||||||
ForceSpawnLocOnJoinEnabled: false
|
|
||||||
# WorldNames where we need to force the spawn location
|
|
||||||
# Warning: This setting is Case Sensitive!
|
|
||||||
ForceSpawnOnTheseWorlds:
|
|
||||||
- world
|
|
||||||
- world_nether
|
|
||||||
- world_the_end
|
|
||||||
|
|
||||||
# this is very important options,
|
|
||||||
# every time player join the server,
|
|
||||||
# if they are registered, AuthMe will switch him
|
|
||||||
# to unLoggedInGroup, this
|
|
||||||
# should prevent all major exploit.
|
|
||||||
# So you can set up on your Permission Plugin
|
|
||||||
# this special group with 0 permissions, or permissions to chat,
|
|
||||||
# or permission to
|
|
||||||
# send private message or all other perms that you want,
|
|
||||||
# the better way is to set up
|
|
||||||
# this group with few permissions,
|
|
||||||
# so if player try to exploit some account,
|
|
||||||
# they can
|
|
||||||
# do anything except what you set in perm Group.
|
|
||||||
# After a correct logged-in player will be
|
|
||||||
# moved to his correct permissions group!
|
|
||||||
# Pay attention group name is case sensitive,
|
|
||||||
# so Admin is different from admin,
|
|
||||||
# otherwise your group will be wiped,
|
|
||||||
# and player join in default group []!
|
|
||||||
# Example unLoggedinGroup: NotLogged
|
|
||||||
unLoggedinGroup: unLoggedinGroup
|
|
||||||
|
|
||||||
# ===========================
|
|
||||||
# Address restrictions
|
|
||||||
# ===========================
|
|
||||||
|
|
||||||
# Max number of registrations per IP (default: 1)
|
|
||||||
maxRegPerIp: 1
|
|
||||||
# Maximum allowed number of Logins per IP, 0 to disable (default: 0)
|
|
||||||
maxLoginPerIp: 0
|
|
||||||
# Maximum allowed number of Joins per IP, 0 to disable (default: 0)
|
|
||||||
maxJoinPerIp: 0
|
|
||||||
|
|
||||||
# When this setting is enabled, online players can't be kicked out
|
|
||||||
# due to "Logged in from another Location"
|
|
||||||
# This setting will prevent potential security exploits.
|
|
||||||
ForceSingleSession: true
|
|
||||||
|
|
||||||
# To activate the restricted user feature you need
|
|
||||||
# to enable this option and configure the
|
|
||||||
# AllowedRestrictedUser field.
|
|
||||||
AllowRestrictedUser: false
|
|
||||||
# The restricted user feature will kick players listed below
|
|
||||||
# if they dont match of the defined ip address.
|
|
||||||
# Example:
|
|
||||||
# AllowedRestrictedUser:
|
|
||||||
# - playername;127.0.0.1
|
|
||||||
AllowedRestrictedUser:
|
|
||||||
- playername;127.0.0.
|
|
||||||
# Ban ip when the ip is not the ip registered in database
|
|
||||||
banUnsafedIP: false
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ===============================
|
|
||||||
# Other restrictions
|
|
||||||
# ===============================
|
|
||||||
|
|
||||||
# Should we protect the player inventory before logging in?
|
|
||||||
# Warning: Requires the latest version of ProtocolLib!
|
|
||||||
ProtectInventoryBeforeLogIn: true
|
|
||||||
|
|
||||||
# Should unregistered players be kicked immediately?
|
|
||||||
kickNonRegistered: false
|
|
||||||
# Should players be kicked on wrong password?
|
|
||||||
kickOnWrongPassword: false
|
|
||||||
|
|
||||||
# Should we display all other accounts of a player when he joins?
|
|
||||||
# Required permission: authme.admin.accounts
|
|
||||||
displayOtherAccounts: true
|
|
||||||
|
|
||||||
# ===============================
|
|
||||||
# Restrictions compatibility
|
|
||||||
# ===============================
|
|
||||||
|
|
||||||
# Spawn Priority. Avariable values : authme, essentials, multiverse, default
|
|
||||||
spawnPriority: authme,essentials,multiverse,default
|
|
||||||
# AuthMe will NEVER teleport players!
|
|
||||||
noTeleport: false
|
|
||||||
|
|
||||||
GameMode:
|
|
||||||
# Do you want to set player's gamemode to survival when he joins?
|
|
||||||
# This enables also the settings below.
|
|
||||||
ForceSurvivalMode: false
|
|
||||||
# Do you want to reset player's inventory if player joins with creative mode?
|
|
||||||
ResetInventoryIfCreative: false
|
|
||||||
# Do you want to force the survival mode ONLY after the /login process?
|
|
||||||
ForceOnlyAfterLogin: false
|
|
||||||
|
|
||||||
# sgdc3: Ok, our configuration is shit.... xD Today I will stop there
|
|
||||||
|
|
||||||
|
|
||||||
registration:
|
|
||||||
# enable registration on the server?
|
|
||||||
enabled: true
|
|
||||||
# Send every X seconds a message to a player to
|
|
||||||
# remind him that he has to login/register
|
|
||||||
messageInterval: 5
|
|
||||||
# Only registered and logged in players can play.
|
|
||||||
# See restrictions for exceptions
|
|
||||||
force: true
|
|
||||||
# Does we replace password registration by an Email registration method ?
|
|
||||||
enableEmailRegistrationSystem: false
|
|
||||||
# Enable double check of email when you register
|
|
||||||
# when it's true, registration require that kind of command:
|
|
||||||
# /register <email> <confirmEmail>
|
|
||||||
doubleEmailCheck: false
|
|
||||||
# Do we force kicking player after a successful registration ?
|
|
||||||
# Do not use with login feature below
|
|
||||||
forceKickAfterRegister: false
|
|
||||||
# Does AuthMe need to enforce a /login after a successful registration ?
|
|
||||||
forceLoginAfterRegister: false
|
|
||||||
unrestrictions:
|
|
||||||
# below you can list all your account name, that
|
|
||||||
# AuthMe will ignore for registration or login, configure it
|
|
||||||
# at your own risk!! Remember that if you are going to add
|
|
||||||
# nickname with [], you have to delimit name with ' '.
|
|
||||||
# this option add compatibility with BuildCraft and some
|
|
||||||
# other mods.
|
|
||||||
# It is CaseSensitive!
|
|
||||||
UnrestrictedName: []
|
|
||||||
# Message language, available : en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt
|
|
||||||
messagesLanguage: en
|
|
||||||
# Force these commands after /login, without any '/', use %p for replace with player name
|
|
||||||
forceCommands: []
|
|
||||||
# Force these commands after /login as a server console, without any '/', use %p for replace with player name
|
|
||||||
forceCommandsAsConsole: []
|
|
||||||
# Force these commands after /register, without any '/', use %p for replace with player name
|
|
||||||
forceRegisterCommands: []
|
|
||||||
# Force these commands after /register as a server console, without any '/', use %p for replace with player name
|
|
||||||
forceRegisterCommandsAsConsole: []
|
|
||||||
# Do we need to broadcast the welcome message to all server or only to the player? set true for server or false for player
|
|
||||||
broadcastWelcomeMessage: false
|
|
||||||
# Do we need to delay the join/leave message to be displayed only when the player is authenticated ?
|
|
||||||
delayJoinMessage: false
|
|
||||||
removeJoinMessage: false
|
|
||||||
removeLeaveMessage: false
|
|
||||||
# Do we need to add potion effect Blinding before login/register ?
|
|
||||||
applyBlindEffect: false
|
|
||||||
ExternalBoardOptions:
|
|
||||||
# MySQL column for the salt , needed for some forum/cms support
|
|
||||||
mySQLColumnSalt: ''
|
|
||||||
# MySQL column for the group, needed for some forum/cms support
|
|
||||||
mySQLColumnGroup: ''
|
|
||||||
# -1 mean disabled. If u want that only
|
|
||||||
# activated player can login in your server
|
|
||||||
# u can put in this options the group number
|
|
||||||
# of unactivated user, needed for some forum/cms support
|
|
||||||
nonActivedUserGroup: -1
|
|
||||||
# Other MySQL columns where we need to put the Username (case sensitive)
|
|
||||||
mySQLOtherUsernameColumns: []
|
|
||||||
# How much Log to Round needed in BCrypt(do not change it if you do not know what's your doing)
|
|
||||||
bCryptLog2Round: 10
|
|
||||||
# phpBB prefix defined during phpbb installation process
|
|
||||||
phpbbTablePrefix: 'phpbb_'
|
|
||||||
# phpBB activated group id , 2 is default registered group defined by phpbb
|
|
||||||
phpbbActivatedGroupId: 2
|
|
||||||
# WordPress prefix defined during WordPress installation process
|
|
||||||
wordpressTablePrefix: 'wp_'
|
|
||||||
permission:
|
|
||||||
# Take care with this options, if you dont want
|
|
||||||
# to use Vault and Group Switching of
|
|
||||||
# AuthMe for unloggedIn players put true
|
|
||||||
# below, default is false.
|
|
||||||
EnablePermissionCheck: false
|
|
||||||
BackupSystem:
|
|
||||||
# Enable or Disable Automatic Backup
|
|
||||||
ActivateBackup: false
|
|
||||||
# set Backup at every start of Server
|
|
||||||
OnServerStart: false
|
|
||||||
# set Backup at every stop of Server
|
|
||||||
OnServerStop: true
|
|
||||||
# Windows only mysql installation Path
|
|
||||||
MysqlWindowsPath: 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\'
|
|
||||||
Security:
|
|
||||||
SQLProblem:
|
|
||||||
# Stop the server if we can't contact the sql database
|
|
||||||
# Take care with this, if you set that to false,
|
|
||||||
# AuthMe automatically disable and the server is not protected!
|
|
||||||
stopServer: true
|
|
||||||
ReloadCommand:
|
|
||||||
# /reload support
|
|
||||||
useReloadCommandSupport: true
|
|
||||||
console:
|
|
||||||
# Remove spam console
|
|
||||||
noConsoleSpam: false
|
|
||||||
captcha:
|
|
||||||
# Player need to put a captcha when he fails too lot the password
|
|
||||||
useCaptcha: false
|
|
||||||
# Max allowed tries before request a captcha
|
|
||||||
maxLoginTry: 5
|
|
||||||
# Captcha length
|
|
||||||
captchaLength: 5
|
|
||||||
Converter:
|
|
||||||
Rakamak:
|
|
||||||
# Rakamak file name
|
|
||||||
fileName: users.rak
|
|
||||||
# Rakamak use ip ?
|
|
||||||
useIP: false
|
|
||||||
# IP file name for rakamak
|
|
||||||
ipFileName: UsersIp.rak
|
|
||||||
CrazyLogin:
|
|
||||||
# CrazyLogin database file
|
|
||||||
fileName: accounts.db
|
|
||||||
Email:
|
|
||||||
# Email SMTP server host
|
|
||||||
mailSMTP: smtp.gmail.com
|
|
||||||
# Email SMTP server port
|
|
||||||
mailPort: 465
|
|
||||||
# Email account that send the mail
|
|
||||||
mailAccount: ''
|
|
||||||
# Email account password
|
|
||||||
mailPassword: ''
|
|
||||||
# Custom SenderName, that replace the mailAccount name in the email
|
|
||||||
mailSenderName: ''
|
|
||||||
# Random password length
|
|
||||||
RecoveryPasswordLength: 8
|
|
||||||
# Email subject of password get
|
|
||||||
mailSubject: 'Your new AuthMe Password'
|
|
||||||
# Email text here
|
|
||||||
mailText: 'Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword'
|
|
||||||
# Like maxRegPerIp but with email
|
|
||||||
maxRegPerEmail: 1
|
|
||||||
# Recall players to add an email ?
|
|
||||||
recallPlayers: false
|
|
||||||
# Delay in minute for the recall scheduler
|
|
||||||
delayRecall: 5
|
|
||||||
# Blacklist these domains for emails
|
|
||||||
emailBlacklisted:
|
|
||||||
- 10minutemail.com
|
|
||||||
# WhiteList only these domains for emails
|
|
||||||
emailWhitelisted: []
|
|
||||||
# Do we need to send new password draw in an image ?
|
|
||||||
generateImage: false
|
|
||||||
Hooks:
|
|
||||||
# Do we need to hook with multiverse for spawn checking?
|
|
||||||
multiverse: true
|
|
||||||
# Do we need to hook with BungeeCord for get the real Player ip ?
|
|
||||||
bungeecord: false
|
|
||||||
# Do we need to disable Essentials SocialSpy on join ?
|
|
||||||
disableSocialSpy: true
|
|
||||||
# Do we need to force /motd Essentials command on join ?
|
|
||||||
useEssentialsMotd: false
|
|
||||||
# Do we need to cache custom Attributes ?
|
|
||||||
customAttributes: false
|
|
||||||
Purge:
|
|
||||||
# On Enable , does AuthMe need to purge automatically old accounts unused ?
|
|
||||||
useAutoPurge: false
|
|
||||||
# Number of Days an account become Unused
|
|
||||||
daysBeforeRemovePlayer: 60
|
|
||||||
# Do we need to remove the player.dat file during purge process ?
|
|
||||||
removePlayerDat: false
|
|
||||||
# Do we need to remove the Essentials/users/player.yml file during purge process ?
|
|
||||||
removeEssentialsFile: false
|
|
||||||
# World where are players.dat stores
|
|
||||||
defaultWorld: 'world'
|
|
||||||
# Do we need to remove LimitedCreative/inventories/player.yml , player_creative.yml files during purge process ?
|
|
||||||
removeLimitedCreativesInventories: false
|
|
||||||
# Do we need to remove the AntiXRayData/PlayerData/player file during purge process ?
|
|
||||||
removeAntiXRayFile: false
|
|
||||||
# Do we need to remove permissions ?
|
|
||||||
removePermissions: false
|
|
||||||
Protection:
|
|
||||||
# Enable some servers protection ( country based login, antibot )
|
|
||||||
enableProtection: false
|
|
||||||
# Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes
|
|
||||||
countries:
|
|
||||||
- US
|
|
||||||
- GB
|
|
||||||
# Countries blacklisted automatically ( without any needed to enable protection )
|
|
||||||
countriesBlacklist:
|
|
||||||
- A1
|
|
||||||
# Do we need to enable automatic antibot system?
|
|
||||||
enableAntiBot: false
|
|
||||||
# Max number of player allowed to login in 5 secs before enable AntiBot system automatically
|
|
||||||
antiBotSensibility: 5
|
|
||||||
# Duration in minutes of the antibot automatic system
|
|
||||||
antiBotDuration: 10
|
|
||||||
VeryGames:
|
|
||||||
# These features are only available on VeryGames Server Provider
|
|
||||||
enableIpCheck: false
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
name: ${pluginName}
|
|
||||||
authors: [${pluginAuthors}]
|
|
||||||
website: ${project.url}
|
|
||||||
description: ${project.description}
|
|
||||||
main: ${mainClass}
|
|
||||||
version: ${project.version}-b${buildNumber}
|
|
||||||
softdepend:
|
|
||||||
- Vault
|
|
||||||
- PermissionsBukkit
|
|
||||||
- PermissionsEX
|
|
||||||
- EssentialsGroupManager
|
|
||||||
- Multiverse-Core
|
|
||||||
- Essentials
|
|
||||||
- EssentialsSpawn
|
|
||||||
- ProtocolLib
|
|
||||||
commands:
|
|
||||||
authme:
|
|
||||||
description: AuthMe admin commands
|
|
||||||
usage: '/authme reload|register playername password|changepassword playername password|unregister playername|version|converter datatype'
|
|
||||||
permission: authme.admin
|
|
||||||
register:
|
|
||||||
description: Register an account
|
|
||||||
usage: /register password confirmpassword
|
|
||||||
aliases: [reg]
|
|
||||||
permission: authme.player.register
|
|
||||||
login:
|
|
||||||
description: Login into a account
|
|
||||||
usage: /login password
|
|
||||||
aliases: [l,log]
|
|
||||||
permission: authme.player.login
|
|
||||||
changepassword:
|
|
||||||
description: Change password of a account
|
|
||||||
usage: /changepassword oldPassword newPassword
|
|
||||||
permission: authme.player.changepassword
|
|
||||||
logout:
|
|
||||||
description: Logout from the server
|
|
||||||
usage: /logout
|
|
||||||
permission: authme.player.logout
|
|
||||||
unregister:
|
|
||||||
description: unregister your account
|
|
||||||
usage: /unregister password
|
|
||||||
permission: authme.player.unregister
|
|
||||||
email:
|
|
||||||
description: Add Email or recover password
|
|
||||||
usage: '/email add your@email.com your@email.com|change oldEmail newEmail|recovery your@email.com'
|
|
||||||
permission: authme.player.email
|
|
||||||
captcha:
|
|
||||||
description: Captcha command
|
|
||||||
usage: /captcha theCaptcha
|
|
||||||
permission: authme.player.captcha
|
|
||||||
permissions:
|
|
||||||
authme.canbeforced:
|
|
||||||
description: Allow the user to be forced-logged via API
|
|
||||||
default: true
|
|
||||||
authme.player:
|
|
||||||
description: Gives access to all authme player commands
|
|
||||||
default: true
|
|
||||||
children:
|
|
||||||
authme.player.login: true
|
|
||||||
authme.player.logout: true
|
|
||||||
authme.player.register: true
|
|
||||||
authme.player.unregister: true
|
|
||||||
authme.player.changepassword: true
|
|
||||||
authme.player.captcha: true
|
|
||||||
authme.player.email: true
|
|
||||||
authme.player.register:
|
|
||||||
description: Register your account
|
|
||||||
default: false
|
|
||||||
authme.player.unregister:
|
|
||||||
description: Unregister your account
|
|
||||||
default: false
|
|
||||||
authme.player.login:
|
|
||||||
description: Login into your account
|
|
||||||
default: false
|
|
||||||
authme.player.logout:
|
|
||||||
description: Logout from your account
|
|
||||||
default: false
|
|
||||||
authme.player.changepassword:
|
|
||||||
description: Change password of your account
|
|
||||||
default: false
|
|
||||||
authme.player.email:
|
|
||||||
description: Gives access to player's email commands
|
|
||||||
default: false
|
|
||||||
children:
|
|
||||||
authme.player.email.add: true
|
|
||||||
authme.player.email.change: true
|
|
||||||
authme.player.email.recover: true
|
|
||||||
authme.player.email.add:
|
|
||||||
description: Add an email to your account
|
|
||||||
default: false
|
|
||||||
authme.player.email.change:
|
|
||||||
description: Change email of your account
|
|
||||||
default: false
|
|
||||||
authme.player.email.recover:
|
|
||||||
description: Recover your account
|
|
||||||
default: false
|
|
||||||
authme.player.captcha:
|
|
||||||
description: Captcha command
|
|
||||||
default: false
|
|
||||||
authme.admin:
|
|
||||||
description: Gives access to all authme admin commands
|
|
||||||
default: op
|
|
||||||
children:
|
|
||||||
authme.admin.forcelogin: true
|
|
||||||
authme.admin.forcelogout: true
|
|
||||||
authme.admin.register: true
|
|
||||||
authme.admin.unregister: true
|
|
||||||
authme.admin.changemail: true
|
|
||||||
authme.admin.changepassword: true
|
|
||||||
authme.admin.lastlogin: true
|
|
||||||
authme.admin.accounts: true
|
|
||||||
authme.admin.getemail: true
|
|
||||||
authme.admin.getip: true
|
|
||||||
authme.admin.setspawn: true
|
|
||||||
authme.admin.spawn: true
|
|
||||||
authme.admin.setfirstspawn: true
|
|
||||||
authme.admin.firstspawn: true
|
|
||||||
authme.admin.purge: true
|
|
||||||
authme.admin.purgebannedplayers: true
|
|
||||||
authme.admin.purgelastpos: true
|
|
||||||
authme.admin.converter: true
|
|
||||||
authme.admin.reload: true
|
|
||||||
authme.admin.switchantibot: true
|
|
||||||
authme.admin.seeotheraccounts: true
|
|
||||||
authme.admin.register:
|
|
||||||
description: Register an account
|
|
||||||
default: false
|
|
||||||
authme.admin.unregister:
|
|
||||||
description: Unregister an account
|
|
||||||
default: false
|
|
||||||
authme.admin.forcelogin:
|
|
||||||
description: Force login for that player
|
|
||||||
default: false
|
|
||||||
authme.admin.forcelogout:
|
|
||||||
description: Force logout for that player
|
|
||||||
default: false
|
|
||||||
authme.admin.changepassword:
|
|
||||||
description: Change the password of an account
|
|
||||||
default: false
|
|
||||||
authme.admin.getemail:
|
|
||||||
description: Get last email about a player
|
|
||||||
default: false
|
|
||||||
authme.admin.changeemail:
|
|
||||||
description: Change a player email
|
|
||||||
default: false
|
|
||||||
authme.admin.accounts:
|
|
||||||
description: Display Players Accounts
|
|
||||||
default: false
|
|
||||||
authme.admin.seeotheraccounts:
|
|
||||||
description: Display other accounts about a player when he logs in
|
|
||||||
default: false
|
|
||||||
authme.admin.lastlogin:
|
|
||||||
description: Get last login date about a player
|
|
||||||
default: false
|
|
||||||
authme.admin.getip:
|
|
||||||
description: Get IP from a player (fake and real)
|
|
||||||
default: false
|
|
||||||
authme.admin.setspawn:
|
|
||||||
description: Set the AuthMe spawn point
|
|
||||||
default: false
|
|
||||||
authme.admin.spawn:
|
|
||||||
description: Teleport to AuthMe spawn point
|
|
||||||
default: false
|
|
||||||
authme.admin.setfirstspawn:
|
|
||||||
description: Set the AuthMe First Spawn Point
|
|
||||||
default: false
|
|
||||||
authme.admin.firstspawn:
|
|
||||||
description: Teleport to AuthMe First Spawn Point
|
|
||||||
default: false
|
|
||||||
authme.admin.switchantibot:
|
|
||||||
description: Switch AntiBot mode on/off
|
|
||||||
default: false
|
|
||||||
authme.admin.purge:
|
|
||||||
description: Database purge command
|
|
||||||
default: false
|
|
||||||
authme.admin.purgebannedplayers:
|
|
||||||
description: Purge banned players
|
|
||||||
default: false
|
|
||||||
authme.admin.purgelastpos:
|
|
||||||
description: Purge last position of a player/players
|
|
||||||
default: false
|
|
||||||
authme.admin.converter:
|
|
||||||
description: Allow the /authme converter command
|
|
||||||
default: false
|
|
||||||
authme.admin.reload:
|
|
||||||
description: Reload the plugin
|
|
||||||
default: false
|
|
||||||
authme.vip:
|
|
||||||
description: Allow vip slot when the server is full
|
|
||||||
default: false
|
|
||||||
authme.bypassantibot:
|
|
||||||
description: Bypass the AntiBot check
|
|
||||||
default: false
|
|
||||||
authme.allowmultipleaccounts:
|
|
||||||
description: Allow more accounts for same ip
|
|
||||||
default: false
|
|
||||||
authme.bypassforcesurvival:
|
|
||||||
description: Bypass all ForceSurvival features
|
|
||||||
default: false
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,148 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* AuthMe website integration logic *
|
|
||||||
* ------------------------------------------------------------------------- *
|
|
||||||
* Allows interaction with the AuthMe database (registration, password *
|
|
||||||
* verification). Don't forget to update the AUTHME_TABLE value and your *
|
|
||||||
* database credentials in getAuthmeMySqli(). *
|
|
||||||
* *
|
|
||||||
* Source: https://github.com/AuthMe/AuthMeReloaded/ *
|
|
||||||
*****************************************************************************/
|
|
||||||
abstract class AuthMeController {
|
|
||||||
|
|
||||||
const AUTHME_TABLE = 'authme';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entry point function to check supplied credentials against the AuthMe database.
|
|
||||||
*
|
|
||||||
* @param string $username the username
|
|
||||||
* @param string $password the password
|
|
||||||
* @return bool true iff the data is correct, false otherwise
|
|
||||||
*/
|
|
||||||
function checkPassword($username, $password) {
|
|
||||||
if (is_scalar($username) && is_scalar($password)) {
|
|
||||||
$hash = $this->getHashFromDatabase($username);
|
|
||||||
if ($hash) {
|
|
||||||
return $this->isValidPassword($password, $hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the user exists in the database or not.
|
|
||||||
*
|
|
||||||
* @param string $username the username to check
|
|
||||||
* @return bool true if the user exists; false otherwise
|
|
||||||
*/
|
|
||||||
function isUserRegistered($username) {
|
|
||||||
$mysqli = $this->getAuthmeMySqli();
|
|
||||||
if ($mysqli !== null) {
|
|
||||||
$stmt = $mysqli->prepare('SELECT 1 FROM ' . self::AUTHME_TABLE . ' WHERE username = ?');
|
|
||||||
$stmt->bind_param('s', $username);
|
|
||||||
$stmt->execute();
|
|
||||||
return $stmt->fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defensive default to true; we actually don't know
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a player with the given username.
|
|
||||||
*
|
|
||||||
* @param string $username the username to register
|
|
||||||
* @param string $password the password to associate to the user
|
|
||||||
* @param string $email the email (may be empty)
|
|
||||||
* @return bool whether or not the registration was successful
|
|
||||||
*/
|
|
||||||
function register($username, $password, $email) {
|
|
||||||
$email = $email ? $email : 'your@email.com';
|
|
||||||
$mysqli = $this->getAuthmeMySqli();
|
|
||||||
if ($mysqli !== null) {
|
|
||||||
$hash = $this->hash($password);
|
|
||||||
$stmt = $mysqli->prepare('INSERT INTO ' . self::AUTHME_TABLE . ' (username, realname, password, email, ip) '
|
|
||||||
. 'VALUES (?, ?, ?, ?, ?)');
|
|
||||||
$username_low = strtolower($username);
|
|
||||||
$stmt->bind_param('sssss', $username_low, $username, $hash, $email, $_SERVER['REMOTE_ADDR']);
|
|
||||||
return $stmt->execute();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes password for player.
|
|
||||||
*
|
|
||||||
* @param string $username the username
|
|
||||||
* @param string $password the password
|
|
||||||
* @return bool true whether or not password change was successful
|
|
||||||
*/
|
|
||||||
function changePassword($username, $password) {
|
|
||||||
$mysqli = $this->getAuthmeMySqli();
|
|
||||||
if ($mysqli !== null) {
|
|
||||||
$hash = $this->hash($password);
|
|
||||||
$stmt = $mysqli->prepare('UPDATE ' . self::AUTHME_TABLE . ' SET password=? '
|
|
||||||
. 'WHERE username=?');
|
|
||||||
$username_low = strtolower($username);
|
|
||||||
$stmt->bind_param('ss', $hash, $username_low);
|
|
||||||
return $stmt->execute();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hashes the given password.
|
|
||||||
*
|
|
||||||
* @param $password string the clear-text password to hash
|
|
||||||
* @return string the resulting hash
|
|
||||||
*/
|
|
||||||
protected abstract function hash($password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given password matches the hash.
|
|
||||||
*
|
|
||||||
* @param $password string the clear-text password
|
|
||||||
* @param $hash string the password hash
|
|
||||||
* @return boolean true if the password matches, false otherwise
|
|
||||||
*/
|
|
||||||
protected abstract function isValidPassword($password, $hash);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a connection to the database.
|
|
||||||
*
|
|
||||||
* @return mysqli|null the mysqli object or null upon error
|
|
||||||
*/
|
|
||||||
private function getAuthmeMySqli() {
|
|
||||||
// CHANGE YOUR DATABASE DETAILS HERE BELOW: host, user, password, database name
|
|
||||||
$mysqli = new mysqli('localhost', 'root', '', 'authme');
|
|
||||||
if (mysqli_connect_error()) {
|
|
||||||
printf('Could not connect to AuthMe database. Errno: %d, error: "%s"',
|
|
||||||
mysqli_connect_errno(), mysqli_connect_error());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $mysqli;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the hash associated with the given user from the database.
|
|
||||||
*
|
|
||||||
* @param string $username the username whose hash should be retrieved
|
|
||||||
* @return string|null the hash, or null if unavailable (e.g. username doesn't exist)
|
|
||||||
*/
|
|
||||||
private function getHashFromDatabase($username) {
|
|
||||||
$mysqli = $this->getAuthmeMySqli();
|
|
||||||
if ($mysqli !== null) {
|
|
||||||
$stmt = $mysqli->prepare('SELECT password FROM ' . self::AUTHME_TABLE . ' WHERE username = ?');
|
|
||||||
$stmt->bind_param('s', $username);
|
|
||||||
$stmt->execute();
|
|
||||||
$stmt->bind_result($password);
|
|
||||||
if ($stmt->fetch()) {
|
|
||||||
return $password;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* AuthMe website integration logic for BCrypt *
|
|
||||||
* ------------------------------------------------------- *
|
|
||||||
* See AuthMeController for details. *
|
|
||||||
* *
|
|
||||||
* Source: https://github.com/AuthMe/AuthMeReloaded/ *
|
|
||||||
***********************************************************/
|
|
||||||
class Bcrypt extends AuthMeController {
|
|
||||||
|
|
||||||
protected function hash($password) {
|
|
||||||
return password_hash($password, PASSWORD_BCRYPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function isValidPassword($password, $hash) {
|
|
||||||
return password_verify($password, $hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* AuthMe website integration logic for PBKDF2 *
|
|
||||||
* ------------------------------------------------------- *
|
|
||||||
* See AuthMeController for details. *
|
|
||||||
* *
|
|
||||||
* Source: https://github.com/AuthMe/AuthMeReloaded/ *
|
|
||||||
***********************************************************/
|
|
||||||
class Pbkdf2 extends AuthMeController {
|
|
||||||
|
|
||||||
/** @var string[] range of characters for salt generation */
|
|
||||||
private $CHARS;
|
|
||||||
|
|
||||||
const SALT_LENGTH = 16;
|
|
||||||
const NUMBER_OF_ITERATIONS = 10000;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->CHARS = self::initCharRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function isValidPassword($password, $hash) {
|
|
||||||
// hash := pbkdf2_sha256$iterations$salt$hash
|
|
||||||
$parts = explode('$', $hash);
|
|
||||||
return count($parts) === 4 && $hash === $this->computeHash($parts[1], $parts[2], $password);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function hash($password) {
|
|
||||||
$salt = $this->generateSalt();
|
|
||||||
return $this->computeHash(self::NUMBER_OF_ITERATIONS, $salt, $password);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function computeHash($iterations, $salt, $password) {
|
|
||||||
return 'pbkdf2_sha256$' . self::NUMBER_OF_ITERATIONS . '$' . $salt
|
|
||||||
. '$' . hash_pbkdf2('sha256', $password, $salt, self::NUMBER_OF_ITERATIONS, 64, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string randomly generated salt
|
|
||||||
*/
|
|
||||||
private function generateSalt() {
|
|
||||||
$maxCharIndex = count($this->CHARS) - 1;
|
|
||||||
$salt = '';
|
|
||||||
for ($i = 0; $i < self::SALT_LENGTH; ++$i) {
|
|
||||||
$salt .= $this->CHARS[mt_rand(0, $maxCharIndex)];
|
|
||||||
}
|
|
||||||
return $salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function initCharRange() {
|
|
||||||
return array_merge(range('0', '9'), range('a', 'f'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* AuthMe website integration logic for SHA256 *
|
|
||||||
* ------------------------------------------------------- *
|
|
||||||
* See AuthMeController for details. *
|
|
||||||
* *
|
|
||||||
* Source: https://github.com/AuthMe/AuthMeReloaded/ *
|
|
||||||
***********************************************************/
|
|
||||||
class Sha256 extends AuthMeController {
|
|
||||||
|
|
||||||
/** @var string[] range of characters for salt generation */
|
|
||||||
private $CHARS;
|
|
||||||
|
|
||||||
const SALT_LENGTH = 16;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->CHARS = self::initCharRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function isValidPassword($password, $hash) {
|
|
||||||
// $SHA$salt$hash, where hash := sha256(sha256(password) . salt)
|
|
||||||
$parts = explode('$', $hash);
|
|
||||||
return count($parts) === 4 && $parts[3] === hash('sha256', hash('sha256', $password) . $parts[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function hash($password) {
|
|
||||||
$salt = $this->generateSalt();
|
|
||||||
return '$SHA$' . $salt . '$' . hash('sha256', hash('sha256', $password) . $salt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string randomly generated salt
|
|
||||||
*/
|
|
||||||
private function generateSalt() {
|
|
||||||
$maxCharIndex = count($this->CHARS) - 1;
|
|
||||||
$salt = '';
|
|
||||||
for ($i = 0; $i < self::SALT_LENGTH; ++$i) {
|
|
||||||
$salt .= $this->CHARS[mt_rand(0, $maxCharIndex)];
|
|
||||||
}
|
|
||||||
return $salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function initCharRange() {
|
|
||||||
return array_merge(range('0', '9'), range('a', 'f'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
<!--
|
|
||||||
This is a demo page for AuthMe website integration.
|
|
||||||
See AuthMeController.php and the extending classes for the PHP code you need.
|
|
||||||
-->
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>AuthMe Integration Sample</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<?php
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
require 'AuthMeController.php';
|
|
||||||
|
|
||||||
// Change this to the file of the hash encryption you need, e.g. Bcrypt.php or Sha256.php
|
|
||||||
require 'Sha256.php';
|
|
||||||
// The class name must correspond to the file you have in require above! e.g. require 'Sha256.php'; and new Sha256();
|
|
||||||
$authme_controller = new Sha256();
|
|
||||||
|
|
||||||
$action = get_from_post_or_empty('action');
|
|
||||||
$user = get_from_post_or_empty('username');
|
|
||||||
$pass = get_from_post_or_empty('password');
|
|
||||||
$email = get_from_post_or_empty('email');
|
|
||||||
|
|
||||||
$was_successful = false;
|
|
||||||
if ($action && $user && $pass) {
|
|
||||||
if ($action === 'Log in') {
|
|
||||||
$was_successful = process_login($user, $pass, $authme_controller);
|
|
||||||
} else if ($action === 'Register') {
|
|
||||||
$was_successful = process_register($user, $pass, $email, $authme_controller);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$was_successful) {
|
|
||||||
echo '<h1>Login sample</h1>
|
|
||||||
This is a demo form for AuthMe website integration. Enter your AuthMe login details
|
|
||||||
into the following form to test it.
|
|
||||||
<form method="post">
|
|
||||||
<table>
|
|
||||||
<tr><td>Name</td><td><input type="text" value="' . htmlspecialchars($user) . '" name="username" /></td></tr>
|
|
||||||
<tr><td>Email</td><td><input type="text" value="' . htmlspecialchars($email) . '" name="email" /></td></tr>
|
|
||||||
<tr><td>Pass</td><td><input type="password" value="' . htmlspecialchars($pass) . '" name="password" /></td></tr>
|
|
||||||
<tr>
|
|
||||||
<td><input type="submit" name="action" value="Log in" /></td>
|
|
||||||
<td><input type="submit" name="action" value="Register" /></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_from_post_or_empty($index_name) {
|
|
||||||
return trim(
|
|
||||||
filter_input(INPUT_POST, $index_name, FILTER_UNSAFE_RAW, FILTER_REQUIRE_SCALAR | FILTER_FLAG_STRIP_LOW)
|
|
||||||
?: '');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Login logic
|
|
||||||
function process_login($user, $pass, AuthMeController $controller) {
|
|
||||||
if ($controller->checkPassword($user, $pass)) {
|
|
||||||
printf('<h1>Hello, %s!</h1>', htmlspecialchars($user));
|
|
||||||
echo 'Successful login. Nice to have you back!'
|
|
||||||
. '<br /><a href="index.php">Back to form</a>';
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
echo '<h1>Error</h1> Invalid username or password.';
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register logic
|
|
||||||
function process_register($user, $pass, $email, AuthMeController $controller) {
|
|
||||||
if ($controller->isUserRegistered($user)) {
|
|
||||||
echo '<h1>Error</h1> This user already exists.';
|
|
||||||
} else if (!is_email_valid($email)) {
|
|
||||||
echo '<h1>Error</h1> The supplied email is invalid.';
|
|
||||||
} else {
|
|
||||||
// Note that we don't validate the password or username at all in this demo...
|
|
||||||
$register_success = $controller->register($user, $pass, $email);
|
|
||||||
if ($register_success) {
|
|
||||||
printf('<h1>Welcome, %s!</h1>Thanks for registering', htmlspecialchars($user));
|
|
||||||
echo '<br /><a href="index.php">Back to form</a>';
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
echo '<h1>Error</h1>Unfortunately, there was an error during the registration.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_email_valid($email) {
|
|
||||||
return trim($email) === ''
|
|
||||||
? true // accept no email
|
|
||||||
: filter_var($email, FILTER_VALIDATE_EMAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -35,6 +35,7 @@ import fr.xephi.authme.service.BackupService;
|
|||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.service.MigrationService;
|
import fr.xephi.authme.service.MigrationService;
|
||||||
import fr.xephi.authme.service.bungeecord.BungeeReceiver;
|
import fr.xephi.authme.service.bungeecord.BungeeReceiver;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocityReceiver;
|
||||||
import fr.xephi.authme.service.yaml.YamlParseException;
|
import fr.xephi.authme.service.yaml.YamlParseException;
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.SettingsWarner;
|
import fr.xephi.authme.settings.SettingsWarner;
|
||||||
@@ -79,7 +80,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
// Version and build number values
|
// Version and build number values
|
||||||
private static String pluginVersion = "5.6.0-Fork";
|
private static String pluginVersion = "5.6.0-Fork";
|
||||||
private static final String pluginBuild = "b";
|
private static final String pluginBuild = "b";
|
||||||
private static String pluginBuildNumber = "45";
|
private static String pluginBuildNumber = "48";
|
||||||
// Private instances
|
// Private instances
|
||||||
private EmailService emailService;
|
private EmailService emailService;
|
||||||
private CommandHandler commandHandler;
|
private CommandHandler commandHandler;
|
||||||
@@ -300,6 +301,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
|
|
||||||
// Trigger instantiation (class not used elsewhere)
|
// Trigger instantiation (class not used elsewhere)
|
||||||
injector.getSingleton(BungeeReceiver.class);
|
injector.getSingleton(BungeeReceiver.class);
|
||||||
|
injector.getSingleton(VelocityReceiver.class);
|
||||||
|
|
||||||
// Trigger construction of API classes; they will keep track of the singleton
|
// Trigger construction of API classes; they will keep track of the singleton
|
||||||
injector.getSingleton(AuthMeApi.class);
|
injector.getSingleton(AuthMeApi.class);
|
||||||
@@ -465,7 +467,9 @@ public class AuthMe extends JavaPlugin {
|
|||||||
|
|
||||||
|
|
||||||
private void checkServerType() {
|
private void checkServerType() {
|
||||||
if (isClassLoaded("com.destroystokyo.paper.PaperConfig")) {
|
if (isClassLoaded("io.papermc.paper.threadedregions.RegionizedServer")) {
|
||||||
|
logger.info("AuthMeReReloaded is running on Folia");
|
||||||
|
} else if (isClassLoaded("com.destroystokyo.paper.PaperConfig")) {
|
||||||
logger.info("AuthMeReReloaded is running on Paper");
|
logger.info("AuthMeReReloaded is running on Paper");
|
||||||
} else if (isClassLoaded("catserver.server.CatServerConfig")) {
|
} else if (isClassLoaded("catserver.server.CatServerConfig")) {
|
||||||
logger.info("AuthMeReReloaded is running on CatServer");
|
logger.info("AuthMeReReloaded is running on CatServer");
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ import fr.xephi.authme.ConsoleLogger;
|
|||||||
import fr.xephi.authme.command.ExecutableCommand;
|
import fr.xephi.authme.command.ExecutableCommand;
|
||||||
import fr.xephi.authme.datasource.converter.Converter;
|
import fr.xephi.authme.datasource.converter.Converter;
|
||||||
import fr.xephi.authme.datasource.converter.CrazyLoginConverter;
|
import fr.xephi.authme.datasource.converter.CrazyLoginConverter;
|
||||||
|
import fr.xephi.authme.datasource.converter.H2ToSqlite;
|
||||||
import fr.xephi.authme.datasource.converter.LoginSecurityConverter;
|
import fr.xephi.authme.datasource.converter.LoginSecurityConverter;
|
||||||
import fr.xephi.authme.datasource.converter.MySqlToSqlite;
|
import fr.xephi.authme.datasource.converter.MySqlToSqlite;
|
||||||
import fr.xephi.authme.datasource.converter.RakamakConverter;
|
|
||||||
import fr.xephi.authme.datasource.converter.RoyalAuthConverter;
|
import fr.xephi.authme.datasource.converter.RoyalAuthConverter;
|
||||||
import fr.xephi.authme.datasource.converter.SqliteToH2;
|
import fr.xephi.authme.datasource.converter.SqliteToH2;
|
||||||
import fr.xephi.authme.datasource.converter.SqliteToSql;
|
import fr.xephi.authme.datasource.converter.SqliteToSql;
|
||||||
import fr.xephi.authme.datasource.converter.VAuthConverter;
|
|
||||||
import fr.xephi.authme.datasource.converter.XAuthConverter;
|
import fr.xephi.authme.datasource.converter.XAuthConverter;
|
||||||
import fr.xephi.authme.message.MessageKey;
|
import fr.xephi.authme.message.MessageKey;
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
@@ -85,12 +84,11 @@ public class ConverterCommand implements ExecutableCommand {
|
|||||||
return ImmutableSortedMap.<String, Class<? extends Converter>>naturalOrder()
|
return ImmutableSortedMap.<String, Class<? extends Converter>>naturalOrder()
|
||||||
.put("xauth", XAuthConverter.class)
|
.put("xauth", XAuthConverter.class)
|
||||||
.put("crazylogin", CrazyLoginConverter.class)
|
.put("crazylogin", CrazyLoginConverter.class)
|
||||||
.put("rakamak", RakamakConverter.class)
|
|
||||||
.put("royalauth", RoyalAuthConverter.class)
|
.put("royalauth", RoyalAuthConverter.class)
|
||||||
.put("vauth", VAuthConverter.class)
|
|
||||||
.put("sqlitetosql", SqliteToSql.class)
|
.put("sqlitetosql", SqliteToSql.class)
|
||||||
.put("mysqltosqlite", MySqlToSqlite.class)
|
.put("mysqltosqlite", MySqlToSqlite.class)
|
||||||
.put("sqlitetoh2", SqliteToH2.class)
|
.put("sqlitetoh2", SqliteToH2.class)
|
||||||
|
.put("h2tosqlite", H2ToSqlite.class)
|
||||||
.put("loginsecurity", LoginSecurityConverter.class)
|
.put("loginsecurity", LoginSecurityConverter.class)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import fr.xephi.authme.process.register.executors.PasswordRegisterParams;
|
|||||||
import fr.xephi.authme.process.register.executors.RegistrationMethod;
|
import fr.xephi.authme.process.register.executors.RegistrationMethod;
|
||||||
import fr.xephi.authme.process.register.executors.TwoFactorRegisterParams;
|
import fr.xephi.authme.process.register.executors.TwoFactorRegisterParams;
|
||||||
import fr.xephi.authme.security.HashAlgorithm;
|
import fr.xephi.authme.security.HashAlgorithm;
|
||||||
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.service.CommonService;
|
import fr.xephi.authme.service.CommonService;
|
||||||
import fr.xephi.authme.service.ValidationService;
|
import fr.xephi.authme.service.ValidationService;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
@@ -24,8 +25,6 @@ import org.bukkit.entity.Player;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
import static fr.xephi.authme.process.register.RegisterSecondaryArgument.CONFIRMATION;
|
import static fr.xephi.authme.process.register.RegisterSecondaryArgument.CONFIRMATION;
|
||||||
import static fr.xephi.authme.process.register.RegisterSecondaryArgument.EMAIL_MANDATORY;
|
import static fr.xephi.authme.process.register.RegisterSecondaryArgument.EMAIL_MANDATORY;
|
||||||
@@ -46,6 +45,9 @@ public class RegisterCommand extends PlayerCommand {
|
|||||||
@Inject
|
@Inject
|
||||||
private CommonService commonService;
|
private CommonService commonService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BukkitService bukkitService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
@@ -175,20 +177,15 @@ public class RegisterCommand extends PlayerCommand {
|
|||||||
} else if (isSecondArgValidForEmailRegistration(player, arguments)) {
|
} else if (isSecondArgValidForEmailRegistration(player, arguments)) {
|
||||||
management.performRegister(RegistrationMethod.EMAIL_REGISTRATION,
|
management.performRegister(RegistrationMethod.EMAIL_REGISTRATION,
|
||||||
EmailRegisterParams.of(player, email));
|
EmailRegisterParams.of(player, email));
|
||||||
Timer timer = new Timer();
|
if (commonService.getProperty(RegistrationSettings.UNREGISTER_ON_EMAIL_VERIFICATION_FAILURE) && commonService.getProperty(RegistrationSettings.UNREGISTER_AFTER_MINUTES) > 0) {
|
||||||
timer.schedule(new TimerTask() {
|
bukkitService.runTaskLater(player, () -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (dataSource.getAuth(player.getName()) != null) {
|
if (dataSource.getAuth(player.getName()) != null) {
|
||||||
if (dataSource.getAuth(player.getName()).getLastLogin() == null) {
|
if (dataSource.getAuth(player.getName()).getLastLogin() == null) {
|
||||||
management.performUnregisterByAdmin(null, player.getName(), player);
|
management.performUnregisterByAdmin(null, player.getName(), player);
|
||||||
timer.cancel();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
timer.cancel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 600000);
|
}, 60 * 20 * commonService.getProperty(RegistrationSettings.UNREGISTER_AFTER_MINUTES));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,22 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||||
import fr.xephi.authme.data.auth.PlayerCache;
|
import fr.xephi.authme.data.auth.PlayerCache;
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||||
|
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||||
import fr.xephi.authme.util.Utils;
|
import fr.xephi.authme.util.Utils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -28,11 +32,10 @@ import java.util.stream.Collectors;
|
|||||||
public class CacheDataSource implements DataSource {
|
public class CacheDataSource implements DataSource {
|
||||||
|
|
||||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(CacheDataSource.class);
|
private final ConsoleLogger logger = ConsoleLoggerFactory.get(CacheDataSource.class);
|
||||||
|
|
||||||
private final DataSource source;
|
private final DataSource source;
|
||||||
private final PlayerCache playerCache;
|
private final PlayerCache playerCache;
|
||||||
private final LoadingCache<String, Optional<PlayerAuth>> cachedAuths;
|
private final LoadingCache<String, Optional<PlayerAuth>> cachedAuths;
|
||||||
private final ListeningExecutorService executorService;
|
private ListeningExecutorService executorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for CacheDataSource.
|
* Constructor for CacheDataSource.
|
||||||
@@ -43,13 +46,30 @@ public class CacheDataSource implements DataSource {
|
|||||||
public CacheDataSource(DataSource source, PlayerCache playerCache) {
|
public CacheDataSource(DataSource source, PlayerCache playerCache) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.playerCache = playerCache;
|
this.playerCache = playerCache;
|
||||||
|
if (AuthMe.settings.getProperty(DatabaseSettings.USE_VIRTUAL_THREADS)) {
|
||||||
|
try {
|
||||||
|
Method method = Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
|
||||||
|
method.setAccessible(true);
|
||||||
|
ExecutorService ex = (ExecutorService) method.invoke(null);
|
||||||
|
executorService = MoreExecutors.listeningDecorator(ex);
|
||||||
|
logger.info("Using virtual threads for cache loader");
|
||||||
|
} catch (Exception e) {
|
||||||
executorService = MoreExecutors.listeningDecorator(
|
executorService = MoreExecutors.listeningDecorator(
|
||||||
Executors.newCachedThreadPool(new ThreadFactoryBuilder()
|
Executors.newCachedThreadPool(new ThreadFactoryBuilder()
|
||||||
.setDaemon(true)
|
.setDaemon(true)
|
||||||
.setNameFormat("AuthMe-CacheLoader")
|
.setNameFormat("AuthMe-CacheLoader")
|
||||||
.build())
|
.build())
|
||||||
);
|
);
|
||||||
|
logger.info("Cannot enable virtual threads, fallback to CachedThreadPool");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
executorService = MoreExecutors.listeningDecorator(
|
||||||
|
Executors.newCachedThreadPool(new ThreadFactoryBuilder()
|
||||||
|
.setDaemon(true)
|
||||||
|
.setNameFormat("AuthMe-CacheLoader")
|
||||||
|
.build())
|
||||||
|
);
|
||||||
|
}
|
||||||
cachedAuths = CacheBuilder.newBuilder()
|
cachedAuths = CacheBuilder.newBuilder()
|
||||||
.refreshAfterWrite(5, TimeUnit.MINUTES)
|
.refreshAfterWrite(5, TimeUnit.MINUTES)
|
||||||
.expireAfterAccess(15, TimeUnit.MINUTES)
|
.expireAfterAccess(15, TimeUnit.MINUTES)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public class MySQL extends AbstractSqlDataSource {
|
|||||||
private boolean useSsl;
|
private boolean useSsl;
|
||||||
private boolean serverCertificateVerification;
|
private boolean serverCertificateVerification;
|
||||||
private boolean allowPublicKeyRetrieval;
|
private boolean allowPublicKeyRetrieval;
|
||||||
|
private String mariaDbSslMode;
|
||||||
private String host;
|
private String host;
|
||||||
private String port;
|
private String port;
|
||||||
private String username;
|
private String username;
|
||||||
@@ -121,6 +122,7 @@ public class MySQL extends AbstractSqlDataSource {
|
|||||||
this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL);
|
this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL);
|
||||||
this.serverCertificateVerification = settings.getProperty(DatabaseSettings.MYSQL_CHECK_SERVER_CERTIFICATE);
|
this.serverCertificateVerification = settings.getProperty(DatabaseSettings.MYSQL_CHECK_SERVER_CERTIFICATE);
|
||||||
this.allowPublicKeyRetrieval = settings.getProperty(DatabaseSettings.MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL);
|
this.allowPublicKeyRetrieval = settings.getProperty(DatabaseSettings.MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL);
|
||||||
|
this.mariaDbSslMode = settings.getProperty(DatabaseSettings.MARIADB_SSL_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,12 +147,19 @@ public class MySQL extends AbstractSqlDataSource {
|
|||||||
ds.setDriverClassName(this.getDriverClassName());
|
ds.setDriverClassName(this.getDriverClassName());
|
||||||
|
|
||||||
// Request mysql over SSL
|
// Request mysql over SSL
|
||||||
|
if (this instanceof MariaDB) {
|
||||||
|
ds.addDataSourceProperty("sslMode", mariaDbSslMode);
|
||||||
|
} else {
|
||||||
ds.addDataSourceProperty("useSSL", String.valueOf(useSsl));
|
ds.addDataSourceProperty("useSSL", String.valueOf(useSsl));
|
||||||
|
|
||||||
// Disabling server certificate verification on need
|
// Disabling server certificate verification on need
|
||||||
if (!serverCertificateVerification) {
|
if (!serverCertificateVerification) {
|
||||||
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
|
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
|
||||||
} // Disabling server certificate verification on need
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Disabling server certificate verification on need
|
||||||
if (allowPublicKeyRetrieval) {
|
if (allowPublicKeyRetrieval) {
|
||||||
ds.addDataSourceProperty("allowPublicKeyRetrieval", String.valueOf(true));
|
ds.addDataSourceProperty("allowPublicKeyRetrieval", String.valueOf(true));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package fr.xephi.authme.datasource.converter;
|
||||||
|
|
||||||
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
|
import fr.xephi.authme.datasource.DataSourceType;
|
||||||
|
import fr.xephi.authme.datasource.H2;
|
||||||
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.io.File;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts H2 to SQLite.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class H2ToSqlite extends AbstractDataSourceConverter<H2>{
|
||||||
|
|
||||||
|
private final Settings settings;
|
||||||
|
private final File dataFolder;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
H2ToSqlite(Settings settings, DataSource dataSource, @DataFolder File dataFolder) {
|
||||||
|
super(dataSource, DataSourceType.SQLITE);
|
||||||
|
this.settings = settings;
|
||||||
|
this.dataFolder = dataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected H2 getSource() throws SQLException {
|
||||||
|
return new H2(settings, dataFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package fr.xephi.authme.datasource.converter;
|
|
||||||
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|
||||||
import fr.xephi.authme.security.PasswordSecurity;
|
|
||||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
|
||||||
import fr.xephi.authme.settings.Settings;
|
|
||||||
import fr.xephi.authme.settings.properties.ConverterSettings;
|
|
||||||
import fr.xephi.authme.util.Utils;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Xephi59
|
|
||||||
*/
|
|
||||||
public class RakamakConverter implements Converter {
|
|
||||||
|
|
||||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(RakamakConverter.class);
|
|
||||||
private final DataSource database;
|
|
||||||
private final Settings settings;
|
|
||||||
private final File pluginFolder;
|
|
||||||
private final PasswordSecurity passwordSecurity;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
RakamakConverter(@DataFolder File dataFolder, DataSource dataSource, Settings settings,
|
|
||||||
PasswordSecurity passwordSecurity) {
|
|
||||||
this.database = dataSource;
|
|
||||||
this.settings = settings;
|
|
||||||
this.pluginFolder = dataFolder;
|
|
||||||
this.passwordSecurity = passwordSecurity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
//TODO ljacqu 20151229: Restructure this into smaller portions
|
|
||||||
public void execute(CommandSender sender) {
|
|
||||||
boolean useIp = settings.getProperty(ConverterSettings.RAKAMAK_USE_IP);
|
|
||||||
String fileName = settings.getProperty(ConverterSettings.RAKAMAK_FILE_NAME);
|
|
||||||
String ipFileName = settings.getProperty(ConverterSettings.RAKAMAK_IP_FILE_NAME);
|
|
||||||
File source = new File(pluginFolder, fileName);
|
|
||||||
File ipFiles = new File(pluginFolder, ipFileName);
|
|
||||||
Map<String, String> playerIp = new HashMap<>();
|
|
||||||
Map<String, HashedPassword> playerPassword = new HashMap<>();
|
|
||||||
try {
|
|
||||||
BufferedReader ipFile = new BufferedReader(new FileReader(ipFiles));
|
|
||||||
String line;
|
|
||||||
if (useIp) {
|
|
||||||
String tempLine;
|
|
||||||
while ((tempLine = ipFile.readLine()) != null) {
|
|
||||||
if (tempLine.contains("=")) {
|
|
||||||
String[] args = tempLine.split("=");
|
|
||||||
playerIp.put(args[0], args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ipFile.close();
|
|
||||||
|
|
||||||
BufferedReader users = new BufferedReader(new FileReader(source));
|
|
||||||
while ((line = users.readLine()) != null) {
|
|
||||||
if (line.contains("=")) {
|
|
||||||
String[] arguments = line.split("=");
|
|
||||||
HashedPassword hashedPassword = passwordSecurity.computeHash(arguments[1], arguments[0]);
|
|
||||||
playerPassword.put(arguments[0], hashedPassword);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
users.close();
|
|
||||||
for (Entry<String, HashedPassword> m : playerPassword.entrySet()) {
|
|
||||||
String playerName = m.getKey();
|
|
||||||
HashedPassword psw = playerPassword.get(playerName);
|
|
||||||
String ip = playerIp.get(playerName);
|
|
||||||
PlayerAuth auth = PlayerAuth.builder()
|
|
||||||
.name(playerName)
|
|
||||||
.realName(playerName)
|
|
||||||
.lastIp(ip)
|
|
||||||
.password(psw)
|
|
||||||
.build();
|
|
||||||
database.saveAuth(auth);
|
|
||||||
database.updateSession(auth);
|
|
||||||
}
|
|
||||||
Utils.logAndSendMessage(sender, "Rakamak database has been imported successfully");
|
|
||||||
} catch (IOException ex) {
|
|
||||||
logger.logException("Can't open the rakamak database file! Does it exist?", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package fr.xephi.authme.datasource.converter;
|
|
||||||
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import static fr.xephi.authme.util.FileUtils.makePath;
|
|
||||||
|
|
||||||
public class VAuthConverter implements Converter {
|
|
||||||
|
|
||||||
private final ConsoleLogger logger = ConsoleLoggerFactory.get(VAuthConverter.class);
|
|
||||||
private final DataSource dataSource;
|
|
||||||
private final File vAuthPasswordsFile;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
VAuthConverter(@DataFolder File dataFolder, DataSource dataSource) {
|
|
||||||
vAuthPasswordsFile = new File(dataFolder.getParent(), makePath("vAuth", "passwords.yml"));
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender) {
|
|
||||||
try (Scanner scanner = new Scanner(vAuthPasswordsFile)) {
|
|
||||||
while (scanner.hasNextLine()) {
|
|
||||||
String line = scanner.nextLine();
|
|
||||||
String name = line.split(": ")[0];
|
|
||||||
String password = line.split(": ")[1];
|
|
||||||
PlayerAuth auth;
|
|
||||||
if (isUuidInstance(password)) {
|
|
||||||
String pname;
|
|
||||||
try {
|
|
||||||
pname = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName();
|
|
||||||
} catch (Exception | NoSuchMethodError e) {
|
|
||||||
pname = getName(UUID.fromString(name));
|
|
||||||
}
|
|
||||||
if (pname == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auth = PlayerAuth.builder()
|
|
||||||
.name(pname.toLowerCase(Locale.ROOT))
|
|
||||||
.realName(pname)
|
|
||||||
.password(password, null).build();
|
|
||||||
} else {
|
|
||||||
auth = PlayerAuth.builder()
|
|
||||||
.name(name.toLowerCase(Locale.ROOT))
|
|
||||||
.realName(name)
|
|
||||||
.password(password, null).build();
|
|
||||||
}
|
|
||||||
dataSource.saveAuth(auth);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.logException("Error while trying to import some vAuth data", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUuidInstance(String s) {
|
|
||||||
return s.length() > 8 && s.charAt(8) == '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getName(UUID uuid) {
|
|
||||||
for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {
|
|
||||||
if (op.getUniqueId().compareTo(uuid) == 0) {
|
|
||||||
return op.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -79,6 +79,7 @@ public class DataSourceProvider implements Provider<DataSource> {
|
|||||||
break;
|
break;
|
||||||
case H2:
|
case H2:
|
||||||
dataSource = new H2(settings, dataFolder);
|
dataSource = new H2(settings, dataFolder);
|
||||||
|
logger.warning("You are using H2 database, which is still in development!\nMake sure to backup and report any issues you encounter on GitHub!");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown data source type '" + dataSourceType + "'");
|
throw new UnsupportedOperationException("Unknown data source type '" + dataSourceType + "'");
|
||||||
|
|||||||
@@ -39,14 +39,16 @@ public class BedrockAutoLoginListener implements Listener {
|
|||||||
return settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(uuid) && getServer().getPluginManager().getPlugin("floodgate") != null;
|
return settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(uuid) && getServer().getPluginManager().getPlugin("floodgate") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
String name = event.getPlayer().getName();
|
String name = event.getPlayer().getName();
|
||||||
UUID uuid = event.getPlayer().getUniqueId();
|
UUID uuid = event.getPlayer().getUniqueId();
|
||||||
|
bukkitService.runTaskLater(player, () -> {
|
||||||
if (isBedrockPlayer(uuid) && !authmeApi.isAuthenticated(player) && authmeApi.isRegistered(name)) {
|
if (isBedrockPlayer(uuid) && !authmeApi.isAuthenticated(player) && authmeApi.isRegistered(name)) {
|
||||||
authmeApi.forceLogin(player);
|
authmeApi.forceLogin(player);
|
||||||
messages.send(player, MessageKey.BEDROCK_AUTO_LOGGED_IN);
|
messages.send(player, MessageKey.BEDROCK_AUTO_LOGGED_IN);
|
||||||
}
|
}
|
||||||
|
},20L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class PlayerListener implements Listener{
|
|||||||
if (validationService.isUnrestricted(name)) {
|
if (validationService.isUnrestricted(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER)) {
|
if (settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && settings.getProperty(HooksSettings.IGNORE_BEDROCK_NAME_CHECK)) {
|
||||||
if (getServer().getPluginManager().getPlugin("floodgate") != null) {
|
if (getServer().getPluginManager().getPlugin("floodgate") != null) {
|
||||||
if (org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(event.getUniqueId())) return;
|
if (org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(event.getUniqueId())) return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,11 +52,15 @@ public class PurgeListener implements Listener {
|
|||||||
|
|
||||||
// 构建玩家数据文件路径
|
// 构建玩家数据文件路径
|
||||||
File playerDataFile = new File(playerDataFolder, File.separator + playerUUID + ".dat");
|
File playerDataFile = new File(playerDataFolder, File.separator + playerUUID + ".dat");
|
||||||
|
File playerDataOldFile = new File(playerDataFolder, File.separator + playerUUID + ".dat_old");
|
||||||
|
|
||||||
// 删除玩家数据文件
|
// 删除玩家数据文件
|
||||||
if (playerDataFile.exists()) {
|
if (playerDataFile.exists()) {
|
||||||
playerDataFile.delete();
|
playerDataFile.delete();
|
||||||
}
|
}
|
||||||
|
if (playerDataOldFile.exists()) {
|
||||||
|
playerDataOldFile.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteAuthMePlayerData(UUID playerUUID) {
|
private void deleteAuthMePlayerData(UUID playerUUID) {
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ public class EmailService {
|
|||||||
try {
|
try {
|
||||||
htmlEmail = sendMailSsl.initializeMail(email);
|
htmlEmail = sendMailSsl.initializeMail(email);
|
||||||
} catch (EmailException e) {
|
} catch (EmailException e) {
|
||||||
logger.logException("Failed to create email for recovery code:", e);
|
logger.logException("Failed to create email for shutdown:", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import fr.xephi.authme.service.SessionService;
|
|||||||
import fr.xephi.authme.service.ValidationService;
|
import fr.xephi.authme.service.ValidationService;
|
||||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VMessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocitySender;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
@@ -45,6 +48,9 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private Server server;
|
private Server server;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DataSource database;
|
private DataSource database;
|
||||||
|
|
||||||
@@ -75,6 +81,9 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private VelocitySender velocitySender;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProxySessionManager proxySessionManager;
|
private ProxySessionManager proxySessionManager;
|
||||||
|
|
||||||
@@ -152,7 +161,11 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
// As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/
|
// 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."
|
// "Keep in mind that you can't send plugin messages directly after a player joins."
|
||||||
bukkitService.scheduleSyncDelayedTask(() ->
|
bukkitService.scheduleSyncDelayedTask(() ->
|
||||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
|
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
||||||
|
}
|
||||||
|
if (velocitySender.isEnabled()) {
|
||||||
|
bukkitService.scheduleSyncDelayedTask(() ->
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ import fr.xephi.authme.service.CommonService;
|
|||||||
import fr.xephi.authme.service.SessionService;
|
import fr.xephi.authme.service.SessionService;
|
||||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VMessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocitySender;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
@@ -81,9 +84,12 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SessionService sessionService;
|
private SessionService sessionService;
|
||||||
|
@Inject
|
||||||
|
private Settings settings;
|
||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
|
@Inject
|
||||||
|
private VelocitySender velocitySender;
|
||||||
|
|
||||||
AsynchronousLogin() {
|
AsynchronousLogin() {
|
||||||
}
|
}
|
||||||
@@ -112,7 +118,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
|||||||
*
|
*
|
||||||
* @param player the player to log in
|
* @param player the player to log in
|
||||||
*/
|
*/
|
||||||
public void forceLogin(Player player) {
|
public synchronized void forceLogin(Player player) {
|
||||||
PlayerAuth auth = getPlayerAuth(player);
|
PlayerAuth auth = getPlayerAuth(player);
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
performLogin(player, auth);
|
performLogin(player, auth);
|
||||||
@@ -306,7 +312,11 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
|||||||
// As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/
|
// 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."
|
// "Keep in mind that you can't send plugin messages directly after a player joins."
|
||||||
bukkitService.scheduleSyncDelayedTask(() ->
|
bukkitService.scheduleSyncDelayedTask(() ->
|
||||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
|
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
||||||
|
}
|
||||||
|
if (velocitySender.isEnabled()) {
|
||||||
|
bukkitService.scheduleSyncDelayedTask(() ->
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
// As the scheduling executes the Task most likely after the current
|
// As the scheduling executes the Task most likely after the current
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import fr.xephi.authme.service.CommonService;
|
|||||||
import fr.xephi.authme.service.SessionService;
|
import fr.xephi.authme.service.SessionService;
|
||||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.service.velocity.VMessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocitySender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -42,6 +43,8 @@ public class AsynchronousLogout implements AsynchronousProcess {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
|
@Inject
|
||||||
|
private VelocitySender velocitySender;
|
||||||
|
|
||||||
AsynchronousLogout() {
|
AsynchronousLogout() {
|
||||||
}
|
}
|
||||||
@@ -61,17 +64,18 @@ public class AsynchronousLogout implements AsynchronousProcess {
|
|||||||
PlayerAuth auth = playerCache.getAuth(name);
|
PlayerAuth auth = playerCache.getAuth(name);
|
||||||
database.updateSession(auth);
|
database.updateSession(auth);
|
||||||
// TODO: send an update when a messaging service will be implemented (SESSION)
|
// TODO: send an update when a messaging service will be implemented (SESSION)
|
||||||
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
//if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||||
auth.setQuitLocation(player.getLocation());
|
auth.setQuitLocation(player.getLocation());
|
||||||
database.updateQuitLoc(auth);
|
database.updateQuitLoc(auth);
|
||||||
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
// TODO: send an update when a messaging service will be implemented (QUITLOC)
|
||||||
}
|
//} AuthMeReReloaded - Always save quit location
|
||||||
|
|
||||||
playerCache.removePlayer(name);
|
playerCache.removePlayer(name);
|
||||||
codeManager.unverify(name);
|
codeManager.unverify(name);
|
||||||
database.setUnlogged(name);
|
database.setUnlogged(name);
|
||||||
sessionService.revokeSession(name);
|
sessionService.revokeSession(name);
|
||||||
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT);
|
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT);
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGOUT);
|
||||||
syncProcessManager.processSyncPlayerLogout(player);
|
syncProcessManager.processSyncPlayerLogout(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import fr.xephi.authme.service.SessionService;
|
|||||||
import fr.xephi.authme.service.ValidationService;
|
import fr.xephi.authme.service.ValidationService;
|
||||||
import fr.xephi.authme.settings.SpawnLoader;
|
import fr.xephi.authme.settings.SpawnLoader;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
|
||||||
import fr.xephi.authme.util.PlayerUtils;
|
import fr.xephi.authme.util.PlayerUtils;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -68,13 +67,16 @@ public class AsynchronousQuit implements AsynchronousProcess {
|
|||||||
boolean wasLoggedIn = playerCache.isAuthenticated(name);
|
boolean wasLoggedIn = playerCache.isAuthenticated(name);
|
||||||
|
|
||||||
if (wasLoggedIn) {
|
if (wasLoggedIn) {
|
||||||
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
//if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||||
|
// AuthMeReReloaded - Always save quit location on quit
|
||||||
Location loc = spawnLoader.getPlayerLocationOrSpawn(player);
|
Location loc = spawnLoader.getPlayerLocationOrSpawn(player);
|
||||||
PlayerAuth auth = PlayerAuth.builder()
|
PlayerAuth authLoc = PlayerAuth.builder()
|
||||||
.name(name).location(loc)
|
.name(name).location(loc)
|
||||||
.realName(player.getName()).build();
|
.realName(player.getName()).build();
|
||||||
database.updateQuitLoc(auth);
|
database.updateQuitLoc(authLoc);
|
||||||
}
|
// AuthMeReReloaded - Fix AuthMe#2769 -1
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
String ip = PlayerUtils.getPlayerIp(player);
|
String ip = PlayerUtils.getPlayerIp(player);
|
||||||
PlayerAuth auth = PlayerAuth.builder()
|
PlayerAuth auth = PlayerAuth.builder()
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class AsyncRegister implements AsynchronousProcess {
|
|||||||
* @param parameters the parameters
|
* @param parameters the parameters
|
||||||
* @param <P> parameters type
|
* @param <P> parameters type
|
||||||
*/
|
*/
|
||||||
public <P extends RegistrationParameters> void register(RegistrationMethod<P> variant, P parameters) {
|
public synchronized <P extends RegistrationParameters> void register(RegistrationMethod<P> variant, P parameters) {
|
||||||
if (preRegisterCheck(variant, parameters.getPlayer())) {
|
if (preRegisterCheck(variant, parameters.getPlayer())) {
|
||||||
RegistrationExecutor<P> executor = registrationExecutorFactory.getSingleton(variant.getExecutorClass());
|
RegistrationExecutor<P> executor = registrationExecutorFactory.getSingleton(variant.getExecutorClass());
|
||||||
if (executor.isRegistrationAdmitted(parameters)) {
|
if (executor.isRegistrationAdmitted(parameters)) {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|||||||
import fr.xephi.authme.process.SynchronousProcess;
|
import fr.xephi.authme.process.SynchronousProcess;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.service.CommonService;
|
import fr.xephi.authme.service.CommonService;
|
||||||
|
import fr.xephi.authme.service.velocity.VMessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocitySender;
|
||||||
import fr.xephi.authme.util.PlayerUtils;
|
import fr.xephi.authme.util.PlayerUtils;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@@ -28,6 +30,8 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private LimboService limboService;
|
private LimboService limboService;
|
||||||
|
@Inject
|
||||||
|
private VelocitySender velocitySender;
|
||||||
|
|
||||||
ProcessSyncEmailRegister() {
|
ProcessSyncEmailRegister() {
|
||||||
}
|
}
|
||||||
@@ -40,7 +44,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
|
|||||||
public void processEmailRegister(Player player) {
|
public void processEmailRegister(Player player) {
|
||||||
service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
|
service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
|
||||||
limboService.replaceTasksAfterRegistration(player);
|
limboService.replaceTasksAfterRegistration(player);
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.REGISTER);
|
||||||
bukkitService.callEvent(new RegisterEvent(player));
|
bukkitService.callEvent(new RegisterEvent(player));
|
||||||
logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));
|
logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import fr.xephi.authme.process.SynchronousProcess;
|
|||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.service.CommonService;
|
import fr.xephi.authme.service.CommonService;
|
||||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||||
|
import fr.xephi.authme.service.velocity.VMessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocitySender;
|
||||||
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
@@ -27,6 +29,9 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private VelocitySender velocitySender;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CommonService service;
|
private CommonService service;
|
||||||
|
|
||||||
@@ -66,7 +71,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
|
|||||||
if (!service.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
|
if (!service.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
|
||||||
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
service.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||||
}
|
}
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.REGISTER);
|
||||||
bukkitService.callEvent(new RegisterEvent(player));
|
bukkitService.callEvent(new RegisterEvent(player));
|
||||||
logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));
|
logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player));
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import fr.xephi.authme.service.CommonService;
|
|||||||
import fr.xephi.authme.service.TeleportationService;
|
import fr.xephi.authme.service.TeleportationService;
|
||||||
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
import fr.xephi.authme.service.bungeecord.BungeeSender;
|
||||||
import fr.xephi.authme.service.bungeecord.MessageType;
|
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VMessageType;
|
||||||
|
import fr.xephi.authme.service.velocity.VelocitySender;
|
||||||
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
@@ -56,6 +58,9 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private CommandManager commandManager;
|
private CommandManager commandManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private VelocitySender velocitySender;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
|
|
||||||
@@ -76,6 +81,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
|||||||
if (dataSource.removeAuth(name)) {
|
if (dataSource.removeAuth(name)) {
|
||||||
performPostUnregisterActions(name, player);
|
performPostUnregisterActions(name, player);
|
||||||
logger.info(name + " unregistered himself");
|
logger.info(name + " unregistered himself");
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.UNREGISTER);
|
||||||
bukkitService.createAndCallEvent(isAsync -> new UnregisterByPlayerEvent(player, isAsync));
|
bukkitService.createAndCallEvent(isAsync -> new UnregisterByPlayerEvent(player, isAsync));
|
||||||
} else {
|
} else {
|
||||||
service.send(player, MessageKey.ERROR);
|
service.send(player, MessageKey.ERROR);
|
||||||
@@ -97,8 +103,8 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
|||||||
public void adminUnregister(CommandSender initiator, String name, Player player) {
|
public void adminUnregister(CommandSender initiator, String name, Player player) {
|
||||||
if (dataSource.removeAuth(name)) {
|
if (dataSource.removeAuth(name)) {
|
||||||
performPostUnregisterActions(name, player);
|
performPostUnregisterActions(name, player);
|
||||||
|
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.FORCE_UNREGISTER);
|
||||||
bukkitService.createAndCallEvent(isAsync -> new UnregisterByAdminEvent(player, name, isAsync, initiator));
|
bukkitService.createAndCallEvent(isAsync -> new UnregisterByAdminEvent(player, name, isAsync, initiator));
|
||||||
|
|
||||||
if (initiator == null) {
|
if (initiator == null) {
|
||||||
logger.info(name + " was unregistered");
|
logger.info(name + " was unregistered");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -98,11 +98,19 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @throws IllegalArgumentException if task is null
|
* @throws IllegalArgumentException if task is null
|
||||||
*/
|
*/
|
||||||
public void runTask(Runnable task) {
|
public void runTask(Runnable task) {
|
||||||
|
if (IS_FOLIA) {
|
||||||
getScheduler().runTask(task);
|
getScheduler().runTask(task);
|
||||||
|
} else {
|
||||||
|
Bukkit.getScheduler().runTask(authMe, task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runTask(Entity entity, Runnable task) {
|
public void runTask(Entity entity, Runnable task) {
|
||||||
|
if (IS_FOLIA) {
|
||||||
getScheduler().runTask(entity, task);
|
getScheduler().runTask(entity, task);
|
||||||
|
} else {
|
||||||
|
Bukkit.getScheduler().runTask(authMe, task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runTask(Location location, Runnable task) {
|
public void runTask(Location location, Runnable task) {
|
||||||
@@ -159,6 +167,10 @@ public class BukkitService implements SettingsDependent {
|
|||||||
return getScheduler().runTaskLater(task, delay);
|
return getScheduler().runTaskLater(task, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MyScheduledTask runTaskLater(Entity entity, Runnable task, long delay) {
|
||||||
|
return getScheduler().runTaskLater(entity, task, delay);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules this task to run asynchronously or immediately executes it based on
|
* Schedules this task to run asynchronously or immediately executes it based on
|
||||||
* AuthMe's configuration.
|
* AuthMe's configuration.
|
||||||
@@ -361,6 +373,17 @@ public class BukkitService implements SettingsDependent {
|
|||||||
player.sendPluginMessage(authMe, "BungeeCord", bytes);
|
player.sendPluginMessage(authMe, "BungeeCord", bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the specified bytes to bungeecord using the specified player connection.
|
||||||
|
*
|
||||||
|
* @param player the player
|
||||||
|
* @param bytes the message
|
||||||
|
*/
|
||||||
|
public void sendVelocityMessage(Player player, byte[] bytes) {
|
||||||
|
player.sendPluginMessage(authMe, "authmevelocity:main", bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a ban to the 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.
|
* update the previous entry.
|
||||||
|
|||||||
@@ -272,11 +272,10 @@ public class ValidationService implements Reloadable {
|
|||||||
}
|
}
|
||||||
return new HaveIBeenPwnedResults(false, 0);
|
return new HaveIBeenPwnedResults(false, 0);
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException e) {
|
||||||
logger.warning("验证密码时出现错误,这可能是由于网络问题,如果无法解决,请关闭HaveIBeenPwned检查");
|
logger.warning("Error occurred while checking password online, check your connection.\nWhen this error shows, the player's password won't be check");
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class ValidationResult {
|
public static final class ValidationResult {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package fr.xephi.authme.service.velocity;
|
||||||
|
|
||||||
|
public enum VMessageType {
|
||||||
|
LOGIN, REGISTER, LOGOUT, FORCE_UNREGISTER, UNREGISTER
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package fr.xephi.authme.service.velocity;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteArrayDataInput;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import fr.xephi.authme.AuthMe;
|
||||||
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
|
import fr.xephi.authme.data.ProxySessionManager;
|
||||||
|
import fr.xephi.authme.initialization.SettingsDependent;
|
||||||
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
|
import fr.xephi.authme.process.Management;
|
||||||
|
import fr.xephi.authme.service.BukkitService;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.messaging.Messenger;
|
||||||
|
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class VelocityReceiver implements PluginMessageListener, SettingsDependent {
|
||||||
|
|
||||||
|
private final ConsoleLogger logger = ConsoleLoggerFactory.get(VelocityReceiver.class);
|
||||||
|
|
||||||
|
private final AuthMe plugin;
|
||||||
|
private final BukkitService bukkitService;
|
||||||
|
private final ProxySessionManager proxySessionManager;
|
||||||
|
private final Management management;
|
||||||
|
|
||||||
|
private boolean isEnabled;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
VelocityReceiver(AuthMe plugin, BukkitService bukkitService, ProxySessionManager proxySessionManager,
|
||||||
|
Management management, Settings settings) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.bukkitService = bukkitService;
|
||||||
|
this.proxySessionManager = proxySessionManager;
|
||||||
|
this.management = management;
|
||||||
|
reload(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reload(Settings settings) {
|
||||||
|
this.isEnabled = settings.getProperty(HooksSettings.VELOCITY);
|
||||||
|
if (this.isEnabled) {
|
||||||
|
final Messenger messenger = plugin.getServer().getMessenger();
|
||||||
|
if (!messenger.isIncomingChannelRegistered(plugin, "authmevelocity:main")) {
|
||||||
|
messenger.registerIncomingPluginChannel(plugin, "authmevelocity:main", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPluginMessageReceived(String channel, Player player, byte[] bytes) {
|
||||||
|
if (!isEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel.equals("authmevelocity:main")) {
|
||||||
|
final ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
|
||||||
|
|
||||||
|
final String data = in.readUTF();
|
||||||
|
final String username = in.readUTF();
|
||||||
|
processData(username, data);
|
||||||
|
logger.debug("PluginMessage | AuthMeVelocity identifier processed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processData(String username, String data) {
|
||||||
|
if (VMessageType.LOGIN.toString().equals(data)) {
|
||||||
|
performLogin(username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performLogin(String name) {
|
||||||
|
Player player = bukkitService.getPlayerExact(name);
|
||||||
|
if (player != null && player.isOnline()) {
|
||||||
|
management.forceLogin(player, true);
|
||||||
|
logger.info("The user " + player.getName() + " has been automatically logged in, "
|
||||||
|
+ "as requested via plugin messaging.");
|
||||||
|
} else {
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package fr.xephi.authme.service.velocity;
|
||||||
|
|
||||||
|
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.initialization.SettingsDependent;
|
||||||
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
|
import fr.xephi.authme.service.BukkitService;
|
||||||
|
import fr.xephi.authme.service.bungeecord.MessageType;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.messaging.Messenger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class VelocitySender implements SettingsDependent {
|
||||||
|
|
||||||
|
private final ConsoleLogger logger = ConsoleLoggerFactory.get(VelocitySender.class);
|
||||||
|
private final AuthMe plugin;
|
||||||
|
private final BukkitService bukkitService;
|
||||||
|
|
||||||
|
private boolean isEnabled;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
VelocitySender(AuthMe plugin, BukkitService bukkitService, Settings settings) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.bukkitService = bukkitService;
|
||||||
|
reload(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reload(Settings settings) {
|
||||||
|
this.isEnabled = settings.getProperty(HooksSettings.VELOCITY);
|
||||||
|
|
||||||
|
if (this.isEnabled) {
|
||||||
|
Messenger messenger = plugin.getServer().getMessenger();
|
||||||
|
if (!messenger.isOutgoingChannelRegistered(plugin, "authmevelocity:main")) {
|
||||||
|
messenger.registerOutgoingPluginChannel(plugin, "authmevelocity:main");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendForwardedVelocityMessage(Player player, VMessageType type, String playerName) {
|
||||||
|
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||||
|
out.writeUTF(type.toString());
|
||||||
|
out.writeUTF(playerName);
|
||||||
|
bukkitService.sendVelocityMessage(player, out.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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}
|
||||||
|
*/
|
||||||
|
public void sendAuthMeVelocityMessage(Player player, VMessageType type) {
|
||||||
|
if (!isEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!plugin.isEnabled()) {
|
||||||
|
logger.debug("Tried to send a " + type + " velocity message but the plugin was disabled!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendForwardedVelocityMessage(player, type, player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@ public class SettingsWarner {
|
|||||||
|
|
||||||
// Warn if spigot.yml has settings.bungeecord set to true but config.yml has Hooks.bungeecord set to false
|
// Warn if spigot.yml has settings.bungeecord set to true but config.yml has Hooks.bungeecord set to false
|
||||||
if (isTrue(bukkitService.isBungeeCordConfiguredForSpigot())
|
if (isTrue(bukkitService.isBungeeCordConfiguredForSpigot())
|
||||||
&& !settings.getProperty(HooksSettings.BUNGEECORD)) {
|
&& !settings.getProperty(HooksSettings.BUNGEECORD) && !settings.getProperty(HooksSettings.VELOCITY)) {
|
||||||
logger.warning("Note: Hooks.bungeecord is set to false but your server appears to be running in"
|
logger.warning("Note: Hooks.bungeecord is set to false but your server appears to be running in"
|
||||||
+ " bungeecord mode (see your spigot.yml). In order to allow the datasource caching and the"
|
+ " bungeecord mode (see your spigot.yml). In order to allow the datasource caching and the"
|
||||||
+ " AuthMeBungee add-on to work properly you have to enable this option!");
|
+ " AuthMeBungee add-on to work properly you have to enable this option!");
|
||||||
|
|||||||
@@ -8,19 +8,6 @@ import ch.jalu.configme.properties.Property;
|
|||||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||||
|
|
||||||
public final class ConverterSettings implements SettingsHolder {
|
public final class ConverterSettings implements SettingsHolder {
|
||||||
|
|
||||||
@Comment("Rakamak file name")
|
|
||||||
public static final Property<String> RAKAMAK_FILE_NAME =
|
|
||||||
newProperty("Converter.Rakamak.fileName", "users.rak");
|
|
||||||
|
|
||||||
@Comment("Rakamak use IP?")
|
|
||||||
public static final Property<Boolean> RAKAMAK_USE_IP =
|
|
||||||
newProperty("Converter.Rakamak.useIP", false);
|
|
||||||
|
|
||||||
@Comment("Rakamak IP file name")
|
|
||||||
public static final Property<String> RAKAMAK_IP_FILE_NAME =
|
|
||||||
newProperty("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
|
||||||
|
|
||||||
@Comment("CrazyLogin database file name")
|
@Comment("CrazyLogin database file name")
|
||||||
public static final Property<String> CRAZYLOGIN_FILE_NAME =
|
public static final Property<String> CRAZYLOGIN_FILE_NAME =
|
||||||
newProperty("Converter.CrazyLogin.fileName", "accounts.db");
|
newProperty("Converter.CrazyLogin.fileName", "accounts.db");
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ public final class DatabaseSettings implements SettingsHolder {
|
|||||||
public static final Property<Boolean> USE_CACHING =
|
public static final Property<Boolean> USE_CACHING =
|
||||||
newProperty("DataSource.caching", true);
|
newProperty("DataSource.caching", true);
|
||||||
|
|
||||||
|
@Comment("Should we try to use VirtualThreads(Java 21+) for database cache loader?")
|
||||||
|
public static final Property<Boolean> USE_VIRTUAL_THREADS =
|
||||||
|
newProperty("DataSource.useVirtualThreadsCache", false);
|
||||||
|
|
||||||
@Comment("Database host address")
|
@Comment("Database host address")
|
||||||
public static final Property<String> MYSQL_HOST =
|
public static final Property<String> MYSQL_HOST =
|
||||||
newProperty("DataSource.mySQLHost", "127.0.0.1");
|
newProperty("DataSource.mySQLHost", "127.0.0.1");
|
||||||
@@ -27,7 +31,17 @@ public final class DatabaseSettings implements SettingsHolder {
|
|||||||
public static final Property<String> MYSQL_PORT =
|
public static final Property<String> MYSQL_PORT =
|
||||||
newProperty("DataSource.mySQLPort", "3306");
|
newProperty("DataSource.mySQLPort", "3306");
|
||||||
|
|
||||||
@Comment("Connect to MySQL database over SSL")
|
@Comment({"Replacement of Mysql's useSsl (for MariaDB only).",
|
||||||
|
"- disable: No SSL",
|
||||||
|
"- trust: Trust blindly (no validation)",
|
||||||
|
"- verify_ca: Encryption, certificates validation, BUT no hostname verification",
|
||||||
|
"- verify_full: Encryption, certificate validation and hostname validation",
|
||||||
|
"Read more: https://bit.ly/mariadb-sslmode"})
|
||||||
|
public static final Property<String> MARIADB_SSL_MODE =
|
||||||
|
newProperty("DataSource.MariaDbSslMode", "disabled");
|
||||||
|
|
||||||
|
@Comment({"Connect to MySQL database over SSL",
|
||||||
|
"If you're using MariaDB, use sslMode instead"})
|
||||||
public static final Property<Boolean> MYSQL_USE_SSL =
|
public static final Property<Boolean> MYSQL_USE_SSL =
|
||||||
newProperty("DataSource.mySQLUseSSL", true);
|
newProperty("DataSource.mySQLUseSSL", true);
|
||||||
|
|
||||||
@@ -38,7 +52,8 @@ public final class DatabaseSettings implements SettingsHolder {
|
|||||||
newProperty( "DataSource.mySQLCheckServerCertificate", true);
|
newProperty( "DataSource.mySQLCheckServerCertificate", true);
|
||||||
|
|
||||||
@Comment({"Authorize client to retrieve RSA server public key.",
|
@Comment({"Authorize client to retrieve RSA server public key.",
|
||||||
"Advanced option, ignore if you don't know what it means."})
|
"Advanced option, ignore if you don't know what it means.",
|
||||||
|
"If you are using MariaDB, use MariaDbSslMode instead."})
|
||||||
public static final Property<Boolean> MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL =
|
public static final Property<Boolean> MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL =
|
||||||
newProperty( "DataSource.mySQLAllowPublicKeyRetrieval", true);
|
newProperty( "DataSource.mySQLAllowPublicKeyRetrieval", true);
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,26 @@ public final class HooksSettings implements SettingsHolder {
|
|||||||
@Comment("Do we need to hook with BungeeCord?")
|
@Comment("Do we need to hook with BungeeCord?")
|
||||||
public static final Property<Boolean> BUNGEECORD =
|
public static final Property<Boolean> BUNGEECORD =
|
||||||
newProperty("Hooks.bungeecord", false);
|
newProperty("Hooks.bungeecord", false);
|
||||||
|
@Comment("Do we need to hook with Velocity?")
|
||||||
|
public static final Property<Boolean> VELOCITY =
|
||||||
|
newProperty("Hooks.velocity", false);
|
||||||
|
|
||||||
@Comment({"Allow FloodGatePlayer Join Without checkIsValidName()",
|
@Comment({"How many ticks should we wait before sending login info to proxy?",
|
||||||
|
"Change this to higher if your player has high ping.",
|
||||||
|
"See: https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/"})
|
||||||
|
public static final Property<Long> PROXY_SEND_DELAY =
|
||||||
|
newProperty("Hooks.proxySendDelay", 10L);
|
||||||
|
|
||||||
|
@Comment({"Hook into floodgate.",
|
||||||
"This must be true if you want to use other bedrock features."
|
"This must be true if you want to use other bedrock features."
|
||||||
})
|
})
|
||||||
public static final Property<Boolean> HOOK_FLOODGATE_PLAYER =
|
public static final Property<Boolean> HOOK_FLOODGATE_PLAYER =
|
||||||
newProperty("Hooks.floodgate", false);
|
newProperty("Hooks.floodgate", false);
|
||||||
|
|
||||||
|
@Comment("Allow bedrock players join without check isValidName?")
|
||||||
|
public static final Property<Boolean> IGNORE_BEDROCK_NAME_CHECK =
|
||||||
|
newProperty("Hooks.ignoreBedrockNameCheck", true);
|
||||||
|
|
||||||
|
|
||||||
@Comment("Send player to this BungeeCord server after register/login")
|
@Comment("Send player to this BungeeCord server after register/login")
|
||||||
public static final Property<String> BUNGEECORD_SERVER =
|
public static final Property<String> BUNGEECORD_SERVER =
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ public final class PluginSettings implements SettingsHolder {
|
|||||||
|
|
||||||
@Comment({
|
@Comment({
|
||||||
"Message language, available languages:",
|
"Message language, available languages:",
|
||||||
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md"
|
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md",
|
||||||
|
"Example: zhcn, en"
|
||||||
})
|
})
|
||||||
public static final Property<String> MESSAGES_LANGUAGE =
|
public static final Property<String> MESSAGES_LANGUAGE =
|
||||||
newProperty("settings.messagesLanguage", "en");
|
newProperty("settings.messagesLanguage", "en");
|
||||||
|
|||||||
@@ -46,6 +46,16 @@ public final class RegistrationSettings implements SettingsHolder {
|
|||||||
newProperty(RegisterSecondaryArgument.class, "settings.registration.secondArg",
|
newProperty(RegisterSecondaryArgument.class, "settings.registration.secondArg",
|
||||||
RegisterSecondaryArgument.CONFIRMATION);
|
RegisterSecondaryArgument.CONFIRMATION);
|
||||||
|
|
||||||
|
@Comment({
|
||||||
|
"Should we unregister the player when he didn't verify the email?",
|
||||||
|
"This only works if you enabled email registration."})
|
||||||
|
public static final Property<Boolean> UNREGISTER_ON_EMAIL_VERIFICATION_FAILURE =
|
||||||
|
newProperty("settings.registration.email.unregisterOnEmailVerificationFailure", false);
|
||||||
|
|
||||||
|
@Comment({"How many minutes should we wait before unregister the player",
|
||||||
|
"when he didn't verify the email?"})
|
||||||
|
public static final Property<Long> UNREGISTER_AFTER_MINUTES =
|
||||||
|
newProperty("settings.registration.email.unregisterAfterMinutes", 10L);
|
||||||
@Comment({
|
@Comment({
|
||||||
"Do we force kick a player after a successful registration?",
|
"Do we force kick a player after a successful registration?",
|
||||||
"Do not use with login feature below"})
|
"Do not use with login feature below"})
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public final class SecuritySettings implements SettingsHolder {
|
|||||||
newProperty("3rdPartyFeature.fixes.advancedShulkerFix", false);
|
newProperty("3rdPartyFeature.fixes.advancedShulkerFix", false);
|
||||||
|
|
||||||
@Comment({"Choose the best teleport method by server brand?",
|
@Comment({"Choose the best teleport method by server brand?",
|
||||||
"(Enable this if you are using Paper)"})
|
"(Enable this if you are using Paper/Folia)"})
|
||||||
public static final Property<Boolean> SMART_ASYNC_TELEPORT =
|
public static final Property<Boolean> SMART_ASYNC_TELEPORT =
|
||||||
newProperty("3rdPartyFeature.optimizes.smartAsyncTeleport", true);
|
newProperty("3rdPartyFeature.optimizes.smartAsyncTeleport", true);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public final class PlayerUtils {
|
|||||||
// Utility class
|
// Utility class
|
||||||
private PlayerUtils() {
|
private PlayerUtils() {
|
||||||
}
|
}
|
||||||
|
private static final boolean IS_LEAVES_SERVER = Utils.isClassLoaded("top.leavesmc.leaves.LeavesConfig");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IP of the given player.
|
* Returns the IP of the given player.
|
||||||
@@ -28,7 +29,11 @@ public final class PlayerUtils {
|
|||||||
* @return True if the player is an NPC, false otherwise
|
* @return True if the player is an NPC, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean isNpc(Player player) {
|
public static boolean isNpc(Player player) {
|
||||||
|
if (IS_LEAVES_SERVER) {
|
||||||
return player.hasMetadata("NPC") || player.getAddress() == null;
|
return player.hasMetadata("NPC") || player.getAddress() == null;
|
||||||
|
} else {
|
||||||
|
return player.hasMetadata("NPC");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -4,7 +4,7 @@ website: http://github.com/HaHaWTH/AuthMeReReloaded/
|
|||||||
description: A fork of AuthMeReloaded that contains bug fixes
|
description: A fork of AuthMeReloaded that contains bug fixes
|
||||||
main: ${pluginDescription.main}
|
main: ${pluginDescription.main}
|
||||||
folia-supported: true
|
folia-supported: true
|
||||||
version: 5.6.0-FORK-b45
|
version: 5.6.0-FORK-b48
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
softdepend:
|
softdepend:
|
||||||
- Vault
|
- Vault
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
## About Velocity support
|
||||||
|
|
||||||
|
**AuthMeReReloaded offers integrated support for Velocity since b46, in order to use, please follow the instructions below.**
|
||||||
|
|
||||||
|
|
||||||
|
### Step 1: Enable Velocity hook in config.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Hooks:
|
||||||
|
# Do we need to hook with Velocity?
|
||||||
|
velocity: true # Set this to true
|
||||||
|
```
|
||||||
|
**Then restart your server if you have done so.**
|
||||||
|
|
||||||
|
### Step 2: Configure backend server and proxy
|
||||||
|
|
||||||
|
**Before we can continue, you need to configure your Velocity proxy forwarding method following [PaperMC's instructions](https://docs.papermc.io/velocity/player-information-forwarding#configuring-modern-forwarding).**
|
||||||
|
|
||||||
|
### Step 3: Install AuthMeVelocity on the Proxy
|
||||||
|
|
||||||
|
AuthMeVelocity is a plugin that allows Velocity to forward player information to AuthMeReloaded.
|
||||||
|
|
||||||
|
**Only install it on the proxy, not on the backend server.**
|
||||||
|
|
||||||
|
**You can download it from [Modrinth](https://modrinth.com/plugin/authmevelocity).**
|
||||||
|
|
||||||
|
**Then configure follow its instructions.**
|
||||||
Reference in New Issue
Block a user