Compare commits
No commits in common. "master" and "b44" have entirely different histories.
7
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
7
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -47,10 +47,8 @@ body:
|
|||||||
description: Which server implementation are you using?
|
description: Which server implementation are you using?
|
||||||
multiple: false
|
multiple: false
|
||||||
options:
|
options:
|
||||||
- Standalone(Spigot)
|
- Standalone server (no proxy)
|
||||||
- Standalone(Folia)
|
|
||||||
- BungeeCord
|
- BungeeCord
|
||||||
- Velocity
|
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@ -62,9 +60,6 @@ body:
|
|||||||
options:
|
options:
|
||||||
- SQLite
|
- SQLite
|
||||||
- MySQL
|
- MySQL
|
||||||
- H2
|
|
||||||
- MariaDB
|
|
||||||
- PostgreSQL
|
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
name: Feature request
|
name: Feature request
|
||||||
description: Suggest an idea for AuthMe
|
description: Suggest an idea for AuthMe
|
||||||
labels: 'enhancement'
|
labels: 'Type: enhancement'
|
||||||
|
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
|||||||
18
.github/workflows/maven.yml
vendored
18
.github/workflows/maven.yml
vendored
@ -10,11 +10,11 @@ jobs:
|
|||||||
Build:
|
Build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
jdkversion: [ 21 ]
|
jdkversion: [ 17 ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-java@v4
|
- uses: actions/setup-java@v3
|
||||||
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@v4
|
uses: actions/upload-artifact@v3.1.2
|
||||||
with:
|
with:
|
||||||
name: Download
|
name: Download
|
||||||
path: ./target/AuthMe-*-FORK-Universal.jar
|
path: ./target/AuthMe-5.6.0-FORK-Spigot-Universal.jar
|
||||||
runtime-test:
|
runtime-test:
|
||||||
name: Plugin Runtime Test
|
name: Plugin Runtime Test
|
||||||
needs: [Build]
|
needs: [Build]
|
||||||
@ -37,12 +37,8 @@ jobs:
|
|||||||
javaVersion: '8'
|
javaVersion: '8'
|
||||||
- mcVersion: '1.12.2'
|
- mcVersion: '1.12.2'
|
||||||
javaVersion: '8'
|
javaVersion: '8'
|
||||||
- mcVersion: '1.18.2'
|
- mcVersion: '1.20.2'
|
||||||
javaVersion: '17'
|
javaVersion: '20'
|
||||||
- mcVersion: '1.20.4'
|
|
||||||
javaVersion: '21'
|
|
||||||
- mcVersion: '1.21.1'
|
|
||||||
javaVersion: '21'
|
|
||||||
steps:
|
steps:
|
||||||
- uses: HaHaWTH/minecraft-plugin-runtime-test@paper
|
- uses: HaHaWTH/minecraft-plugin-runtime-test@paper
|
||||||
with:
|
with:
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -114,4 +114,3 @@ nb-configuration.xml
|
|||||||
### Git ###
|
### Git ###
|
||||||
# Don't exclude the .gitignore itself
|
# Don't exclude the .gitignore itself
|
||||||
!.gitignore
|
!.gitignore
|
||||||
/samples/
|
|
||||||
|
|||||||
51
README-zh.md
51
README-zh.md
@ -1,51 +0,0 @@
|
|||||||
# 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>
|
|
||||||
29
README.md
29
README.md
@ -1,17 +1,11 @@
|
|||||||
# 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:**
|
||||||
@ -26,26 +20,23 @@
|
|||||||
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 support (in active testing)**
|
12. Folia compatibility (Still WIP)
|
||||||
13. **Velocity support (See [Velocity Support](./vc-support.md))**
|
13. Offhand Menu compatibility(Thats amazing)
|
||||||
14. Support Virtual Threads caching
|
14. Automatically fix portal stuck issue
|
||||||
15. Automatically fix portal stuck issue
|
15. Automatically login for Bedrock players(configurable)
|
||||||
16. Automatically login for Bedrock players(configurable)
|
16. Fix shulker box crash bug on legacy versions(MC 1.13-)
|
||||||
17. Fix shulker box crash bug on legacy versions(MC 1.13-)
|
17. **H2 database support**
|
||||||
18. **H2 database support**
|
18. **100% compatibility with original authme and extensions**
|
||||||
19. **100% compatibility with original authme and extensions**
|
19. More......
|
||||||
20. More......
|
|
||||||
|
|
||||||
**Download links:**
|
**Download links:**
|
||||||
[Releases](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest)
|
[Releases](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest)
|
||||||
[Actions(Dev builds, use at your own risk!)](https://github.com/HaHaWTH/AuthMeReReloaded/actions/workflows/maven.yml)
|
[Actions(Dev builds, use at your own risk!)](https://github.com/HaHaWTH/AuthMeReReloaded/actions/workflows/maven.yml)
|
||||||
|
|
||||||
|
If you are using FRP(内网穿透) for your server, this plugin may help [HAProxy-Detector](https://github.com/HaHaWTH/HAProxy-Detector)
|
||||||
|
|
||||||
**Pull Requests and suggestions are welcome!**
|
**Pull Requests and suggestions are welcome!**
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Only modifications 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)"
|
||||||
|
|||||||
@ -108,4 +108,4 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This page was automatically generated on the [HaHaWTH/AuthMeReReloaded repository](https://github.com/HaHaWTH/AuthMeReReloaded/tree/master/docs/) on Sun Apr 04 21:31:42 CEST 2021
|
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Apr 04 21:31:42 CEST 2021
|
||||||
|
|||||||
1209
docs/config.md
1209
docs/config.md
File diff suppressed because it is too large
Load Diff
@ -80,4 +80,4 @@ or bad.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This page was automatically generated on the [HaHaWTH/AuthMeReReloaded repository](https://github.com/HaHaWTH/AuthMeReReloaded/tree/master/docs/) on Sun Apr 04 21:31:44 CEST 2021
|
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Apr 04 21:31:44 CEST 2021
|
||||||
|
|||||||
@ -73,4 +73,4 @@ The following are the permission nodes that are currently supported by the lates
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This page was automatically generated on the [HaHaWTH/AuthMeReReloaded repository](https://github.com/HaHaWTH/AuthMeReReloaded/tree/master/docs/) on Sun Apr 04 21:31:44 CEST 2021
|
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Apr 04 21:31:44 CEST 2021
|
||||||
|
|||||||
@ -1,49 +1,47 @@
|
|||||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||||
<!-- File auto-generated on Fri May 31 22:00:00 CST 2024. See docs/translations/translations.tpl.md -->
|
<!-- File auto-generated on Wed Jun 21 12:14:29 CEST 2023. See docs/translations/translations.tpl.md -->
|
||||||
|
|
||||||
# AuthMe Translations
|
# AuthMe Translations
|
||||||
|
|
||||||
The following translations are available in AuthMe. Set `messagesLanguage` to the language code
|
The following translations are available in AuthMe. Set `messagesLanguage` to the language code
|
||||||
in your config.yml to use the language, or use another language code to start a new translation.
|
in your config.yml to use the language, or use another language code to start a new translation.
|
||||||
|
|
||||||
| Code | Language | Translated | |
|
Code | Language | Translated |
|
||||||
|------------------------------------------------------------------------------------------------------------|---------------------|-----------:|---------------------------------------------------------------------------|
|
---- | -------- | ---------: | ------
|
||||||
| [en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [eo](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eo.yml) | Esperanto | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[eo](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eo.yml) | Esperanto | 79% | <img src="https://via.placeholder.com/79x7/bb9900?text=%20" alt="79" />
|
||||||
| [es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [et](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_et.yml) | Estonian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[et](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_et.yml) | Estonian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 45% | <img src="https://via.placeholder.com/45x7/aa5500?text=%20" alt="45" />
|
||||||
| [fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 48% | <img src="https://via.placeholder.com/48x7/aa5500?text=%20" alt="48" />
|
||||||
| [hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 93% | <img src="https://via.placeholder.com/93x7/77dd44?text=%20" alt="93" />
|
||||||
| [it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [ja](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ja.yml) | Japanese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[ja](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ja.yml) | Japanese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [si](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_si.yml) | Slovenian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[si](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_si.yml) | Slovenian | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 79% | <img src="https://via.placeholder.com/79x7/bb9900?text=%20" alt="79" />
|
||||||
| [sr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sr.yml) | Serbian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[sr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sr.yml) | Serbian | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
| [zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 99% | <img src="https://via.placeholder.com/99x7/66ee55?text=%20" alt="99" />
|
||||||
| [zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 64% | <img src="https://via.placeholder.com/64x7/bb7700?text=%20" alt="64" />
|
||||||
| [zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" /> |
|
[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 100% | <img src="https://via.placeholder.com/100x7/66ff66?text=%20" alt="100" />
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This page was automatically generated on
|
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Wed Jun 21 12:14:29 CEST 2023
|
||||||
the [HaHaWTH/AuthMeReReloaded repository](https://github.com/HaHaWTH/AuthMeReReloaded/tree/master/docs/) on Fri May 31
|
|
||||||
22:00:00 CST 2024
|
|
||||||
|
|||||||
293
pom.xml
293
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>fr.xephi</groupId>
|
<groupId>fr.xephi</groupId>
|
||||||
<artifactId>authme</artifactId>
|
<artifactId>authme</artifactId>
|
||||||
<version>5.7.0-FORK</version>
|
<version>5.6.0-FORK</version>
|
||||||
|
|
||||||
<name>AuthMeReReloaded</name>
|
<name>AuthMeReReloaded</name>
|
||||||
<description>Fork of the first authentication plugin for the Bukkit API!</description>
|
<description>Fork of the first authentication plugin for the Bukkit API!</description>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
<maven.minimumVersion>3.6.3</maven.minimumVersion>
|
<maven.minimumVersion>3.6.3</maven.minimumVersion>
|
||||||
|
|
||||||
<!-- Dependencies versions -->
|
<!-- Dependencies versions -->
|
||||||
<spigot.version>1.21.1-R0.1-SNAPSHOT</spigot.version>
|
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
|
||||||
|
|
||||||
<!-- Versioning properties -->
|
<!-- Versioning properties -->
|
||||||
<project.outputName>AuthMe</project.outputName>
|
<project.outputName>AuthMe</project.outputName>
|
||||||
@ -82,11 +82,54 @@
|
|||||||
<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>
|
||||||
@ -111,7 +154,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.11.1</version>
|
<version>3.4.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<failOnError>false</failOnError>
|
<failOnError>false</failOnError>
|
||||||
<failOnWarnings>false</failOnWarnings>
|
<failOnWarnings>false</failOnWarnings>
|
||||||
@ -126,7 +169,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
<version>3.5.0</version>
|
<version>3.2.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>enforce-environment</id>
|
<id>enforce-environment</id>
|
||||||
@ -139,7 +182,7 @@
|
|||||||
<version>${maven.minimumVersion}</version>
|
<version>${maven.minimumVersion}</version>
|
||||||
</requireMavenVersion>
|
</requireMavenVersion>
|
||||||
<requireJavaVersion>
|
<requireJavaVersion>
|
||||||
<version>[17,)</version>
|
<version>[11,)</version>
|
||||||
</requireJavaVersion>
|
</requireJavaVersion>
|
||||||
</rules>
|
</rules>
|
||||||
<fail>true</fail>
|
<fail>true</fail>
|
||||||
@ -151,7 +194,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-clean-plugin</artifactId>
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
<version>3.4.0</version>
|
<version>3.3.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Include resource files -->
|
<!-- Include resource files -->
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -179,7 +222,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.12</version>
|
<version>0.8.11</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>pre-unit-test</id>
|
<id>pre-unit-test</id>
|
||||||
@ -195,18 +238,27 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- Unit testing -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.2</version>
|
||||||
|
<configuration>
|
||||||
|
<!-- Force the right file encoding during unit testing -->
|
||||||
|
<!-- Set language to English in order to get consistent results for localized time formatting -->
|
||||||
|
<argLine>-Dfile.encoding=${project.build.sourceEncoding} -Duser.language=en @{argLine}</argLine>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<project.skipExtendedHashTests>${project.skipExtendedHashTests}</project.skipExtendedHashTests>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
<!-- Don't trim stack traces -->
|
||||||
|
<trimStackTrace>false</trimStackTrace>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<!-- Generate a jar containing classes and resources -->
|
<!-- Generate a jar containing classes and resources -->
|
||||||
<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.4.2</version>
|
<version>3.3.0</version>
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestEntries>
|
|
||||||
<paperweight-mappings-namespace>mojang</paperweight-mappings-namespace>
|
|
||||||
</manifestEntries>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Generate a jar containing the source javadoc -->
|
<!-- Generate a jar containing the source javadoc -->
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -230,7 +282,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.1</version>
|
<version>3.3.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<finalName>${project.finalNameBase}</finalName>
|
<finalName>${project.finalNameBase}</finalName>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -247,7 +299,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.6.0</version>
|
<version>3.5.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>shaded-jar</id>
|
<id>shaded-jar</id>
|
||||||
@ -256,7 +308,6 @@
|
|||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<finalName>${project.finalNameBase}-Lite</finalName>
|
|
||||||
<artifactSet>
|
<artifactSet>
|
||||||
<excludes>
|
<excludes>
|
||||||
<!-- Guava -->
|
<!-- Guava -->
|
||||||
@ -267,36 +318,8 @@
|
|||||||
<exclude>com.google.j2objc:j2objc-annotations</exclude>
|
<exclude>com.google.j2objc:j2objc-annotations</exclude>
|
||||||
<!-- Gson -->
|
<!-- Gson -->
|
||||||
<exclude>com.google.code.gson:gson</exclude>
|
<exclude>com.google.code.gson:gson</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</artifactSet>
|
</artifactSet>
|
||||||
<relocations>
|
|
||||||
<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>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>
|
||||||
@ -306,7 +329,7 @@
|
|||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<finalName>${project.finalNameBase}-Universal</finalName>
|
<finalName>${project.finalNameBase}-Spigot-Universal</finalName>
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>com.google.common</pattern>
|
<pattern>com.google.common</pattern>
|
||||||
@ -316,6 +339,10 @@
|
|||||||
<pattern>com.google.thirdparty</pattern>
|
<pattern>com.google.thirdparty</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.com.google.thirdparty</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.com.google.thirdparty</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.cryptomorin.xseries</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.xseries</shadedPattern>
|
||||||
|
</relocation>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>com.google.j2objc</pattern>
|
<pattern>com.google.j2objc</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.com.google.j2objc</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.com.google.j2objc</shadedPattern>
|
||||||
@ -328,6 +355,10 @@
|
|||||||
<pattern>com.google.gson</pattern>
|
<pattern>com.google.gson</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.com.google.gson</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.com.google.gson</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.h2</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.org.h2</shadedPattern>
|
||||||
|
</relocation>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>org.apache.http</pattern>
|
<pattern>org.apache.http</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.org.apache.http</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.org.apache.http</shadedPattern>
|
||||||
@ -336,10 +367,34 @@
|
|||||||
<pattern>org.apache.commons</pattern>
|
<pattern>org.apache.commons</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.org.apache.commons</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.org.apache.commons</shadedPattern>
|
||||||
</relocation>
|
</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>
|
<relocation>
|
||||||
<pattern>waffle</pattern>
|
<pattern>waffle</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.waffle</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.waffle</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.sun.mail</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.com.sun.mail</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.sun.jna</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.com.sun.jna</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.sun.activation</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.com.sun.activation</shadedPattern>
|
||||||
|
</relocation>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>com.github.benmanes.caffeine</pattern>
|
<pattern>com.github.benmanes.caffeine</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.com.github.benmanes.caffeine</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.com.github.benmanes.caffeine</shadedPattern>
|
||||||
@ -450,22 +505,6 @@
|
|||||||
<pattern>org.apache.commons.validator</pattern>
|
<pattern>org.apache.commons.validator</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.org.apache.commons.validator</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.org.apache.commons.validator</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
<relocation>
|
|
||||||
<pattern>com.alessiodp.libby</pattern>
|
|
||||||
<shadedPattern>fr.xephi.authme.libs.com.alessiodp.libby</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>net.kyori.adventure</pattern>
|
|
||||||
<shadedPattern>fr.xephi.authme.libs.net.kyori.adventure</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>net.kyori.examination</pattern>
|
|
||||||
<shadedPattern>fr.xephi.authme.libs.net.kyori.examination</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>net.kyori.option</pattern>
|
|
||||||
<shadedPattern>fr.xephi.authme.libs.net.kyori.option</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
</relocations>
|
</relocations>
|
||||||
|
|
||||||
<filters>
|
<filters>
|
||||||
@ -478,6 +517,7 @@
|
|||||||
<exclude>META-INF/*.DSA</exclude>
|
<exclude>META-INF/*.DSA</exclude>
|
||||||
<exclude>META-INF/*.RSA</exclude>
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
<exclude>META-INF/*.RSA</exclude>
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
|
<exclude>META-INF/*.MF</exclude>
|
||||||
<exclude>META-INF/DEPENDENCIES</exclude>
|
<exclude>META-INF/DEPENDENCIES</exclude>
|
||||||
<exclude>META-INF/**/module-info.class</exclude>
|
<exclude>META-INF/**/module-info.class</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
@ -497,19 +537,19 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-install-plugin</artifactId>
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
<version>3.1.3</version>
|
<version>3.1.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Deploy the jars as artifacts into the remote repository -->
|
<!-- Deploy the jars as artifacts into the remote repository -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-deploy-plugin</artifactId>
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
<version>3.1.3</version>
|
<version>3.0.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Handle documentation generation, required by other plugins -->
|
<!-- Handle documentation generation, required by other plugins -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
<version>3.21.0</version>
|
<version>3.12.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Publish coveralls test coverage reports, not included in the build cycle by default -->
|
<!-- Publish coveralls test coverage reports, not included in the build cycle by default -->
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -541,12 +581,6 @@
|
|||||||
<url>https://repo.opencollab.dev/maven-snapshots/</url>
|
<url>https://repo.opencollab.dev/maven-snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<!-- Adventure API -->
|
|
||||||
<repository>
|
|
||||||
<id>sonatype-oss-snapshots1</id>
|
|
||||||
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<!-- Apache snapshots repo -->
|
<!-- Apache snapshots repo -->
|
||||||
<repository>
|
<repository>
|
||||||
<id>apache-snapshots</id>
|
<id>apache-snapshots</id>
|
||||||
@ -617,23 +651,10 @@
|
|||||||
</snapshots>
|
</snapshots>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<!-- Maven Central Snapshots Repository -->
|
|
||||||
<repository>
|
|
||||||
<id>maven-snapshots</id>
|
|
||||||
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<!-- Placeholder API Repo -->
|
|
||||||
<repository>
|
|
||||||
<id>placeholderapi-repo</id>
|
|
||||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<!-- Multiverse Repo -->
|
<!-- Multiverse Repo -->
|
||||||
<repository>
|
<repository>
|
||||||
<id>multiverse-multiverse-releases</id>
|
<id>onarandombox-repo-releases</id>
|
||||||
<name>Multiverse Repository</name>
|
<url>https://repo.onarandombox.com/content/repositories/multiverse/</url>
|
||||||
<url>https://repo.onarandombox.com/multiverse-releases</url>
|
|
||||||
<releases>
|
<releases>
|
||||||
<enabled>true</enabled>
|
<enabled>true</enabled>
|
||||||
</releases>
|
</releases>
|
||||||
@ -641,6 +662,22 @@
|
|||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>onarandombox-repo-snapshots</id>
|
||||||
|
<url>https://repo.onarandombox.com/content/repositories/multiverse-snapshots/</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
<!-- FoliaLib -->
|
||||||
|
<repository>
|
||||||
|
<id>devmart-other</id>
|
||||||
|
<url>https://nexuslite.gcnt.net/repos/other/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>opencollab-snapshot</id>
|
<id>opencollab-snapshot</id>
|
||||||
@ -690,7 +727,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- MaxMind GEO IP with our modifications to use GSON in replacement of the big Jackson dependency -->
|
<!-- MaxMind GEO IP with our modifications to use GSON in replacement of the big Jackson dependency -->
|
||||||
<!-- GSON is already included, and therefore it reduces the file size in comparison to the original version -->
|
<!-- GSON is already included and therefore it reduces the file size in comparison to the original version -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.maxmind.db</groupId>
|
<groupId>com.maxmind.db</groupId>
|
||||||
<artifactId>maxmind-db-gson</artifactId>
|
<artifactId>maxmind-db-gson</artifactId>
|
||||||
@ -716,7 +753,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-email</artifactId>
|
<artifactId>commons-email</artifactId>
|
||||||
<version>1.6-SNAPSHOT</version>
|
<version>1.6.0</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -728,14 +765,6 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Libby -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alessiodp.libby</groupId>
|
|
||||||
<artifactId>libby-bukkit</artifactId>
|
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Database Connection Pool -->
|
<!-- Database Connection Pool -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.zaxxer</groupId>
|
<groupId>com.zaxxer</groupId>
|
||||||
@ -806,6 +835,10 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>com.googlecode.json-simple</groupId>
|
<groupId>com.googlecode.json-simple</groupId>
|
||||||
<artifactId>json-simple</artifactId>
|
<artifactId>json-simple</artifactId>
|
||||||
@ -877,23 +910,6 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Adventure API -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>adventure-text-minimessage</artifactId>
|
|
||||||
<version>4.17.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>adventure-platform-bukkit</artifactId>
|
|
||||||
<version>4.3.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>adventure-text-serializer-gson</artifactId>
|
|
||||||
<version>4.17.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- LuckPerms plugin -->
|
<!-- LuckPerms plugin -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.luckperms</groupId>
|
<groupId>net.luckperms</groupId>
|
||||||
@ -969,8 +985,8 @@
|
|||||||
<!-- Multi World plugin, https://www.spigotmc.org/resources/multiverse-core.390/ -->
|
<!-- Multi World plugin, https://www.spigotmc.org/resources/multiverse-core.390/ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.onarandombox.multiversecore</groupId>
|
<groupId>com.onarandombox.multiversecore</groupId>
|
||||||
<artifactId>multiverse-core</artifactId>
|
<artifactId>Multiverse-Core</artifactId>
|
||||||
<version>4.3.14</version>
|
<version>4.3.1</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
@ -1029,14 +1045,6 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Placeholder API -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>me.clip</groupId>
|
|
||||||
<artifactId>placeholderapi</artifactId>
|
|
||||||
<version>2.11.6</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- EssentialsX plugin -->
|
<!-- EssentialsX plugin -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.essentialsx</groupId>
|
<groupId>net.essentialsx</groupId>
|
||||||
@ -1123,11 +1131,40 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Unit Testing Libraries -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<version>4.13.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>java-hamcrest</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<version>2.0.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<version>5.2.0</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Required to mock the LuckPerms API-->
|
<!-- Required to mock the LuckPerms API-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.checkerframework</groupId>
|
<groupId>org.checkerframework</groupId>
|
||||||
<artifactId>checker-qual</artifactId>
|
<artifactId>checker-qual</artifactId>
|
||||||
<version>3.48.0</version>
|
<version>3.40.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -1143,14 +1180,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xerial</groupId>
|
<groupId>org.xerial</groupId>
|
||||||
<artifactId>sqlite-jdbc</artifactId>
|
<artifactId>sqlite-jdbc</artifactId>
|
||||||
<version>3.47.1.0</version>
|
<version>3.45.2.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
<version>2.2.224</version>
|
<version>2.2.224</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
564
samples/NewConfig.yml
Normal file
564
samples/NewConfig.yml
Normal file
@ -0,0 +1,564 @@
|
|||||||
|
# =======================================================================================================
|
||||||
|
# _____ __ .__ _____ __________ .__ .___ .___
|
||||||
|
# / _ \ __ ___/ |_| |__ / \ ____\______ \ ____ | | _________ __| _/____ __| _/
|
||||||
|
# / /_\ \| | \ __| | \ / \ / \_/ __ \| __/ __ \| | / _ \__ \ / __ _/ __ \ / __ |
|
||||||
|
# / | | | /| | | 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
|
||||||
199
samples/NewPlugin.yml
Normal file
199
samples/NewPlugin.yml
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
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
|
||||||
45798
samples/databases/xenforo.sql
Normal file
45798
samples/databases/xenforo.sql
Normal file
File diff suppressed because one or more lines are too long
148
samples/website_integration/AuthMeController.php
Normal file
148
samples/website_integration/AuthMeController.php
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
samples/website_integration/Bcrypt.php
Normal file
20
samples/website_integration/Bcrypt.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* AuthMe website integration logic for BCrypt *
|
||||||
|
* ------------------------------------------------------- *
|
||||||
|
* See AuthMeController for details. *
|
||||||
|
* *
|
||||||
|
* Source: https://github.com/AuthMe/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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
53
samples/website_integration/Pbkdf2.php
Normal file
53
samples/website_integration/Pbkdf2.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?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'));
|
||||||
|
}
|
||||||
|
}
|
||||||
48
samples/website_integration/Sha256.php
Normal file
48
samples/website_integration/Sha256.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* AuthMe website integration logic for SHA256 *
|
||||||
|
* ------------------------------------------------------- *
|
||||||
|
* See AuthMeController for details. *
|
||||||
|
* *
|
||||||
|
* Source: https://github.com/AuthMe/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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
102
samples/website_integration/index.php
Normal file
102
samples/website_integration/index.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<!--
|
||||||
|
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>
|
||||||
@ -2,7 +2,6 @@ package fr.xephi.authme;
|
|||||||
|
|
||||||
import ch.jalu.injector.Injector;
|
import ch.jalu.injector.Injector;
|
||||||
import ch.jalu.injector.InjectorBuilder;
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
import com.alessiodp.libby.BukkitLibraryManager;
|
|
||||||
import com.github.Anon8281.universalScheduler.UniversalScheduler;
|
import com.github.Anon8281.universalScheduler.UniversalScheduler;
|
||||||
import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler;
|
import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler;
|
||||||
import fr.xephi.authme.api.v3.AuthMeApi;
|
import fr.xephi.authme.api.v3.AuthMeApi;
|
||||||
@ -20,6 +19,7 @@ import fr.xephi.authme.listener.BedrockAutoLoginListener;
|
|||||||
import fr.xephi.authme.listener.BlockListener;
|
import fr.xephi.authme.listener.BlockListener;
|
||||||
import fr.xephi.authme.listener.DoubleLoginFixListener;
|
import fr.xephi.authme.listener.DoubleLoginFixListener;
|
||||||
import fr.xephi.authme.listener.EntityListener;
|
import fr.xephi.authme.listener.EntityListener;
|
||||||
|
import fr.xephi.authme.listener.GuiCaptchaHandler;
|
||||||
import fr.xephi.authme.listener.LoginLocationFixListener;
|
import fr.xephi.authme.listener.LoginLocationFixListener;
|
||||||
import fr.xephi.authme.listener.PlayerListener;
|
import fr.xephi.authme.listener.PlayerListener;
|
||||||
import fr.xephi.authme.listener.PlayerListener111;
|
import fr.xephi.authme.listener.PlayerListener111;
|
||||||
@ -35,7 +35,6 @@ 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;
|
||||||
@ -43,7 +42,6 @@ import fr.xephi.authme.settings.properties.EmailSettings;
|
|||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.task.CleanupTask;
|
import fr.xephi.authme.task.CleanupTask;
|
||||||
import fr.xephi.authme.task.Updater;
|
|
||||||
import fr.xephi.authme.task.purge.PurgeService;
|
import fr.xephi.authme.task.purge.PurgeService;
|
||||||
import fr.xephi.authme.util.ExceptionUtils;
|
import fr.xephi.authme.util.ExceptionUtils;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
@ -55,10 +53,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Scanner;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE;
|
import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE;
|
||||||
import static fr.xephi.authme.util.Utils.isClassLoaded;
|
import static fr.xephi.authme.util.Utils.isClassLoaded;
|
||||||
@ -74,9 +77,9 @@ public class AuthMe extends JavaPlugin {
|
|||||||
private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE;
|
private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE;
|
||||||
|
|
||||||
// Version and build number values
|
// Version and build number values
|
||||||
private static String pluginVersion = "5.7.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 = "53";
|
private static String pluginBuildNumber = "44";
|
||||||
// Private instances
|
// Private instances
|
||||||
private EmailService emailService;
|
private EmailService emailService;
|
||||||
private CommandHandler commandHandler;
|
private CommandHandler commandHandler;
|
||||||
@ -139,11 +142,6 @@ public class AuthMe extends JavaPlugin {
|
|||||||
return scheduler;
|
return scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The library manager
|
|
||||||
*/
|
|
||||||
public static BukkitLibraryManager libraryManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called when the server enables the plugin.
|
* Method called when the server enables the plugin.
|
||||||
*/
|
*/
|
||||||
@ -152,7 +150,6 @@ public class AuthMe extends JavaPlugin {
|
|||||||
// Load the plugin version data from the plugin description file
|
// Load the plugin version data from the plugin description file
|
||||||
loadPluginInfo(getDescription().getVersion());
|
loadPluginInfo(getDescription().getVersion());
|
||||||
scheduler = UniversalScheduler.getScheduler(this);
|
scheduler = UniversalScheduler.getScheduler(this);
|
||||||
libraryManager = new BukkitLibraryManager(this);
|
|
||||||
|
|
||||||
// Set the Logger instance and log file path
|
// Set the Logger instance and log file path
|
||||||
ConsoleLogger.initialize(getLogger(), new File(getDataFolder(), LOG_FILENAME));
|
ConsoleLogger.initialize(getLogger(), new File(getDataFolder(), LOG_FILENAME));
|
||||||
@ -213,15 +210,14 @@ public class AuthMe extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
//detect server brand with classloader
|
//detect server brand with classloader
|
||||||
checkServerType();
|
checkServerType();
|
||||||
try {
|
Objects.requireNonNull(getCommand("register")).setTabCompleter(new TabCompleteHandler());
|
||||||
Objects.requireNonNull(getCommand("register")).setTabCompleter(new TabCompleteHandler());
|
Objects.requireNonNull(getCommand("login")).setTabCompleter(new TabCompleteHandler());
|
||||||
Objects.requireNonNull(getCommand("login")).setTabCompleter(new TabCompleteHandler());
|
|
||||||
} catch (NullPointerException ignored) {
|
|
||||||
}
|
|
||||||
logger.info("AuthMeReReloaded is enabled successfully!");
|
logger.info("AuthMeReReloaded is enabled successfully!");
|
||||||
// Purge on start if enabled
|
// Purge on start if enabled
|
||||||
PurgeService purgeService = injector.getSingleton(PurgeService.class);
|
PurgeService purgeService = injector.getSingleton(PurgeService.class);
|
||||||
purgeService.runAutoPurge();
|
purgeService.runAutoPurge();
|
||||||
|
// 注册玩家加入事件监听
|
||||||
|
// register3rdPartyListeners();
|
||||||
logger.info("GitHub: https://github.com/HaHaWTH/AuthMeReReloaded/");
|
logger.info("GitHub: https://github.com/HaHaWTH/AuthMeReReloaded/");
|
||||||
if (settings.getProperty(SecuritySettings.CHECK_FOR_UPDATES)) {
|
if (settings.getProperty(SecuritySettings.CHECK_FOR_UPDATES)) {
|
||||||
checkForUpdates();
|
checkForUpdates();
|
||||||
@ -229,6 +225,8 @@ public class AuthMe extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Migrated
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the version and build number of the plugin from the description file.
|
* Load the version and build number of the plugin from the description file.
|
||||||
*
|
*
|
||||||
@ -302,7 +300,6 @@ 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);
|
||||||
@ -346,6 +343,13 @@ public class AuthMe extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Register 3rd party listeners
|
//Register 3rd party listeners
|
||||||
|
if (settings.getProperty(SecuritySettings.GUI_CAPTCHA) && getServer().getPluginManager().getPlugin("ProtocolLib") != null) {
|
||||||
|
pluginManager.registerEvents(injector.getSingleton(GuiCaptchaHandler.class), this);
|
||||||
|
logger.info("(Beta)GUICaptcha is enabled successfully!");
|
||||||
|
logger.info("These features are still in early development, if you encountered any problem, please report.");
|
||||||
|
} else if (settings.getProperty(SecuritySettings.GUI_CAPTCHA) && getServer().getPluginManager().getPlugin("ProtocolLib") == null) {
|
||||||
|
logger.warning("ProtocolLib is not loaded, can't enable GUI Captcha.");
|
||||||
|
}
|
||||||
if (settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && getServer().getPluginManager().getPlugin("floodgate") != null) {
|
if (settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && getServer().getPluginManager().getPlugin("floodgate") != null) {
|
||||||
pluginManager.registerEvents(injector.getSingleton(BedrockAutoLoginListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(BedrockAutoLoginListener.class), this);
|
||||||
} else if (settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && (!settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) || getServer().getPluginManager().getPlugin("floodgate") == null)) {
|
} else if (settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && (!settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) || getServer().getPluginManager().getPlugin("floodgate") == null)) {
|
||||||
@ -360,7 +364,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
if (settings.getProperty(SecuritySettings.ADVANCED_SHULKER_FIX) && !isClassLoaded("org.bukkit.event.player.PlayerCommandSendEvent")) {
|
if (settings.getProperty(SecuritySettings.ADVANCED_SHULKER_FIX) && !isClassLoaded("org.bukkit.event.player.PlayerCommandSendEvent")) {
|
||||||
pluginManager.registerEvents(injector.getSingleton(AdvancedShulkerFixListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AdvancedShulkerFixListener.class), this);
|
||||||
} else if (settings.getProperty(SecuritySettings.ADVANCED_SHULKER_FIX) && isClassLoaded("org.bukkit.event.player.PlayerCommandSendEvent")) {
|
} else if (settings.getProperty(SecuritySettings.ADVANCED_SHULKER_FIX) && isClassLoaded("org.bukkit.event.player.PlayerCommandSendEvent")) {
|
||||||
logger.warning("You are running an 1.13+ minecraft server, AdvancedShulkerFix won't enable.");
|
logger.warning("You are running an 1.13+ minecraft server, advancedShulkerFix won't enable.");
|
||||||
}
|
}
|
||||||
if (settings.getProperty(SecuritySettings.PURGE_DATA_ON_QUIT)) {
|
if (settings.getProperty(SecuritySettings.PURGE_DATA_ON_QUIT)) {
|
||||||
pluginManager.registerEvents(injector.getSingleton(PurgeListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(PurgeListener.class), this);
|
||||||
@ -389,7 +393,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
if (onShutdownPlayerSaver != null) {
|
if (onShutdownPlayerSaver != null) {
|
||||||
onShutdownPlayerSaver.saveAllPlayers();
|
onShutdownPlayerSaver.saveAllPlayers();
|
||||||
}
|
}
|
||||||
if (settings != null && settings.getProperty(EmailSettings.SHUTDOWN_MAIL)) {
|
if (settings.getProperty(EmailSettings.SHUTDOWN_MAIL)){
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'.'MM'.'dd'.' HH:mm:ss");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'.'MM'.'dd'.' HH:mm:ss");
|
||||||
Date date = new Date(System.currentTimeMillis());
|
Date date = new Date(System.currentTimeMillis());
|
||||||
emailService.sendShutDown(settings.getProperty(EmailSettings.SHUTDOWN_MAIL_ADDRESS),dateFormat.format(date));
|
emailService.sendShutDown(settings.getProperty(EmailSettings.SHUTDOWN_MAIL_ADDRESS),dateFormat.format(date));
|
||||||
@ -401,7 +405,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for tasks and close data source
|
// Wait for tasks and close data source
|
||||||
new TaskCloser(database).run();
|
new TaskCloser(this, database).run();
|
||||||
|
|
||||||
// Disabled correctly
|
// Disabled correctly
|
||||||
Consumer<String> infoLogMethod = logger == null ? getLogger()::info : logger::info;
|
Consumer<String> infoLogMethod = logger == null ? getLogger()::info : logger::info;
|
||||||
@ -409,25 +413,59 @@ public class AuthMe extends JavaPlugin {
|
|||||||
ConsoleLogger.closeFileWriter();
|
ConsoleLogger.closeFileWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String owner = "HaHaWTH";
|
||||||
|
// private static final String owner_gitee = "Shixuehan114514";
|
||||||
|
private static final String repo = "AuthMeReReloaded";
|
||||||
|
|
||||||
private void checkForUpdates() {
|
private void checkForUpdates() {
|
||||||
logger.info("Checking for updates...");
|
logger.info("Checking for updates...");
|
||||||
Updater updater = new Updater(pluginBuild + pluginBuildNumber);
|
|
||||||
bukkitService.runTaskAsynchronously(() -> {
|
bukkitService.runTaskAsynchronously(() -> {
|
||||||
if (updater.isUpdateAvailable()) {
|
try {
|
||||||
String message = "New version available! Latest:" + updater.getLatestVersion() + " Current:" + pluginBuild + pluginBuildNumber;
|
// 从南通集线器获取最新版本号
|
||||||
logger.warning(message);
|
URL url = new URL("https://api.github.com/repos/" + owner + "/" + repo + "/releases/latest");
|
||||||
logger.warning("Download from here: https://modrinth.com/plugin/authmerereloaded");
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
} else {
|
conn.setConnectTimeout(10000); // 设置连接超时为10秒
|
||||||
logger.info("You are running the latest version.");
|
conn.setReadTimeout(10000); // 设置读取超时为10秒
|
||||||
|
Scanner scanner = new Scanner(conn.getInputStream());
|
||||||
|
String response = scanner.useDelimiter("\\Z").next();
|
||||||
|
scanner.close();
|
||||||
|
|
||||||
|
// 处理JSON响应
|
||||||
|
String latestVersion = response.substring(response.indexOf("tag_name") + 11);
|
||||||
|
latestVersion = latestVersion.substring(0, latestVersion.indexOf("\""));
|
||||||
|
if (isUpdateAvailable(latestVersion)) {
|
||||||
|
String message = "New version available! Latest:" + latestVersion + " Current:" + pluginBuild + pluginBuildNumber;
|
||||||
|
getLogger().log(Level.WARNING, message);
|
||||||
|
getLogger().log(Level.WARNING, "Download from here: https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest");
|
||||||
|
} else {
|
||||||
|
getLogger().log(Level.INFO, "You are running the latest version.");
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
private boolean isUpdateAvailable(String latestVersion) {
|
||||||
|
// Extract the first character and the remaining digits from the version string
|
||||||
|
char latestChar = latestVersion.charAt(0);
|
||||||
|
int latestNumber = Integer.parseInt(latestVersion.substring(1));
|
||||||
|
|
||||||
|
char currentChar = pluginBuild.charAt(0);
|
||||||
|
int currentNumber = Integer.parseInt(pluginBuildNumber);
|
||||||
|
|
||||||
|
// Compare the characters first
|
||||||
|
if (latestChar > currentChar) {
|
||||||
|
return true;
|
||||||
|
} else if (latestChar < currentChar) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// If the characters are the same, compare the numbers
|
||||||
|
return latestNumber > currentNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkServerType() {
|
private void checkServerType() {
|
||||||
if (isClassLoaded("io.papermc.paper.threadedregions.RegionizedServer")) {
|
if (isClassLoaded("com.destroystokyo.paper.PaperConfig")) {
|
||||||
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");
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import java.util.Optional;
|
|||||||
* AuthMeApi authmeApi = AuthMeApi.getInstance();
|
* AuthMeApi authmeApi = AuthMeApi.getInstance();
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class AuthMeApi {
|
public class AuthMeApi {
|
||||||
|
|
||||||
private static AuthMeApi singleton;
|
private static AuthMeApi singleton;
|
||||||
@ -266,16 +265,6 @@ public class AuthMeApi {
|
|||||||
management.forceLogin(player);
|
management.forceLogin(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Force a player to login, i.e. the player is logged in without needing his password.
|
|
||||||
*
|
|
||||||
* @param player The player to log in
|
|
||||||
* @param quiet Whether to suppress the login message
|
|
||||||
*/
|
|
||||||
public void forceLogin(Player player, boolean quiet) {
|
|
||||||
management.forceLogin(player, quiet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force a player to logout.
|
* Force a player to logout.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -7,12 +7,13 @@ 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;
|
||||||
@ -84,11 +85,12 @@ 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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
package fr.xephi.authme.command.executable.authme;
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
import fr.xephi.authme.command.PlayerCommand;
|
import fr.xephi.authme.command.PlayerCommand;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.SpawnLoader;
|
import fr.xephi.authme.settings.SpawnLoader;
|
||||||
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.util.TeleportUtils;
|
import fr.xephi.authme.util.TeleportUtils;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@ -18,17 +18,17 @@ public class FirstSpawnCommand extends PlayerCommand {
|
|||||||
private Settings settings;
|
private Settings settings;
|
||||||
@Inject
|
@Inject
|
||||||
private SpawnLoader spawnLoader;
|
private SpawnLoader spawnLoader;
|
||||||
@Inject
|
|
||||||
private BukkitService bukkitService;
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(Player player, List<String> arguments) {
|
public void runCommand(Player player, List<String> arguments) {
|
||||||
if (spawnLoader.getFirstSpawn() == null) {
|
if (spawnLoader.getFirstSpawn() == null) {
|
||||||
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
|
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
|
||||||
} else {
|
} else {
|
||||||
//String name= player.getName();
|
//String name= player.getName();
|
||||||
bukkitService.runTaskIfFolia(player, () -> {
|
if(settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
TeleportUtils.teleport(player, spawnLoader.getFirstSpawn());
|
TeleportUtils.teleport(player, spawnLoader.getFirstSpawn());
|
||||||
});
|
} else {
|
||||||
|
player.teleport(spawnLoader.getFirstSpawn());
|
||||||
|
}
|
||||||
//player.teleport(spawnLoader.getFirstSpawn());
|
//player.teleport(spawnLoader.getFirstSpawn());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
package fr.xephi.authme.command.executable.authme;
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
import fr.xephi.authme.command.PlayerCommand;
|
import fr.xephi.authme.command.PlayerCommand;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
|
||||||
import fr.xephi.authme.settings.SpawnLoader;
|
import fr.xephi.authme.settings.SpawnLoader;
|
||||||
import fr.xephi.authme.util.TeleportUtils;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -13,15 +11,13 @@ public class SpawnCommand extends PlayerCommand {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SpawnLoader spawnLoader;
|
private SpawnLoader spawnLoader;
|
||||||
@Inject
|
|
||||||
private BukkitService bukkitService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(Player player, List<String> arguments) {
|
public void runCommand(Player player, List<String> arguments) {
|
||||||
if (spawnLoader.getSpawn() == null) {
|
if (spawnLoader.getSpawn() == null) {
|
||||||
player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
|
player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
|
||||||
} else {
|
} else {
|
||||||
bukkitService.runTaskIfFolia(player, () -> TeleportUtils.teleport(player, spawnLoader.getSpawn()));
|
player.teleport(spawnLoader.getSpawn());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import fr.xephi.authme.process.Management;
|
|||||||
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.service.ValidationService.ValidationResult;
|
import fr.xephi.authme.service.ValidationService.ValidationResult;
|
||||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -43,14 +42,11 @@ public class ChangePasswordCommand extends PlayerCommand {
|
|||||||
commonService.send(player, MessageKey.NOT_LOGGED_IN);
|
commonService.send(player, MessageKey.NOT_LOGGED_IN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Check if the user has been verified or not
|
||||||
if (commonService.getProperty(SecuritySettings.CHANGE_PASSWORD_EMAIL_VERIFICATION_REQUIRED)) {
|
if (codeManager.isVerificationRequired(player)) {
|
||||||
// Check if the user has been verified or not
|
codeManager.codeExistOrGenerateNew(name);
|
||||||
if (codeManager.isVerificationRequired(player)) {
|
commonService.send(player, MessageKey.VERIFICATION_CODE_REQUIRED);
|
||||||
codeManager.codeExistOrGenerateNew(name);
|
return;
|
||||||
commonService.send(player, MessageKey.VERIFICATION_CODE_REQUIRED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String oldPassword = arguments.get(0);
|
String oldPassword = arguments.get(0);
|
||||||
|
|||||||
@ -15,7 +15,6 @@ 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;
|
||||||
@ -25,6 +24,8 @@ 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;
|
||||||
@ -45,9 +46,6 @@ 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;
|
||||||
|
|
||||||
@ -177,15 +175,20 @@ 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));
|
||||||
if (commonService.getProperty(RegistrationSettings.UNREGISTER_ON_EMAIL_VERIFICATION_FAILURE) && commonService.getProperty(RegistrationSettings.UNREGISTER_AFTER_MINUTES) > 0) {
|
Timer timer = new Timer();
|
||||||
bukkitService.runTaskLater(player, () -> {
|
timer.schedule(new TimerTask() {
|
||||||
|
@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();
|
||||||
}
|
}
|
||||||
}, 60 * 20 * commonService.getProperty(RegistrationSettings.UNREGISTER_AFTER_MINUTES));
|
}
|
||||||
}
|
}, 600000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,6 @@ import java.util.Locale;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static fr.xephi.authme.AuthMe.getScheduler;
|
|
||||||
|
|
||||||
public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
||||||
|
|
||||||
private final EmailService emailService;
|
private final EmailService emailService;
|
||||||
@ -135,19 +133,17 @@ public class VerificationCodeManager implements SettingsDependent, HasCleanup {
|
|||||||
* @param name the name of the player to generate a code for
|
* @param name the name of the player to generate a code for
|
||||||
*/
|
*/
|
||||||
private void generateCode(String name) {
|
private void generateCode(String name) {
|
||||||
getScheduler().runTaskAsynchronously(() -> {
|
DataSourceValue<String> emailResult = dataSource.getEmail(name);
|
||||||
DataSourceValue<String> emailResult = dataSource.getEmail(name);
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'年'MM'月'dd'日' HH:mm:ss");
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'-'MM'-'dd'-' HH:mm:ss");
|
Date date = new Date(System.currentTimeMillis());
|
||||||
Date date = new Date(System.currentTimeMillis());
|
if (emailResult.rowExists()) {
|
||||||
if (emailResult.rowExists()) {
|
final String email = emailResult.getValue();
|
||||||
final String email = emailResult.getValue();
|
if (!Utils.isEmailEmpty(email)) {
|
||||||
if (!Utils.isEmailEmpty(email)) {
|
String code = RandomStringUtils.generateNum(6); // 6 digits code
|
||||||
String code = RandomStringUtils.generateNum(6); // 6 digits code
|
verificationCodes.put(name.toLowerCase(Locale.ROOT), code);
|
||||||
verificationCodes.put(name.toLowerCase(Locale.ROOT), code);
|
emailService.sendVerificationMail(name, email, code, dateFormat.format(date));
|
||||||
emailService.sendVerificationMail(name, email, code, dateFormat.format(date));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -24,6 +24,7 @@ public class LimboPlayer {
|
|||||||
private final float flySpeed;
|
private final float flySpeed;
|
||||||
private MyScheduledTask timeoutTask = null;
|
private MyScheduledTask timeoutTask = null;
|
||||||
private MessageTask messageTask = null;
|
private MessageTask messageTask = null;
|
||||||
|
private MyScheduledTask inter;
|
||||||
|
|
||||||
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
|
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
|
||||||
|
|
||||||
@ -113,18 +114,19 @@ public class LimboPlayer {
|
|||||||
*
|
*
|
||||||
* @param messageTask The message task to set
|
* @param messageTask The message task to set
|
||||||
*/
|
*/
|
||||||
public void setMessageTask(MessageTask messageTask) {
|
public void setMessageTask(MessageTask messageTask, MyScheduledTask inter) {
|
||||||
if (this.messageTask != null) {
|
if (this.messageTask != null && this.inter != null) {
|
||||||
this.messageTask.cancel();
|
this.inter.cancel();
|
||||||
}
|
}
|
||||||
this.messageTask = messageTask;
|
this.messageTask = messageTask;
|
||||||
|
this.inter = inter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all tasks associated to the player.
|
* Clears all tasks associated to the player.
|
||||||
*/
|
*/
|
||||||
public void clearTasks() {
|
public void clearTasks() {
|
||||||
setMessageTask(null);
|
setMessageTask(null, null);
|
||||||
setTimeoutTask(null);
|
setTimeoutTask(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,8 +53,8 @@ class LimboPlayerTaskManager {
|
|||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
String[] joinMessage = messages.retrieveSingle(player, result.messageKey, result.args).split("\n");
|
String[] joinMessage = messages.retrieveSingle(player, result.messageKey, result.args).split("\n");
|
||||||
MessageTask messageTask = new MessageTask(player, joinMessage);
|
MessageTask messageTask = new MessageTask(player, joinMessage);
|
||||||
bukkitService.runTaskTimer(messageTask, 2 * TICKS_PER_SECOND, (long) interval * TICKS_PER_SECOND);
|
MyScheduledTask task = bukkitService.runTaskTimer(messageTask, 2 * TICKS_PER_SECOND, (long) interval * TICKS_PER_SECOND);
|
||||||
limbo.setMessageTask(messageTask);
|
limbo.setMessageTask(messageTask, task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,22 +9,18 @@ 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;
|
||||||
@ -32,10 +28,11 @@ 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 ListeningExecutorService executorService;
|
private final ListeningExecutorService executorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for CacheDataSource.
|
* Constructor for CacheDataSource.
|
||||||
@ -46,30 +43,13 @@ 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 {
|
executorService = MoreExecutors.listeningDecorator(
|
||||||
Method method = Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
|
Executors.newCachedThreadPool(new ThreadFactoryBuilder()
|
||||||
method.setAccessible(true);
|
.setDaemon(true)
|
||||||
ExecutorService ex = (ExecutorService) method.invoke(null);
|
.setNameFormat("AuthMe-CacheLoader")
|
||||||
executorService = MoreExecutors.listeningDecorator(ex);
|
.build())
|
||||||
logger.info("Using virtual threads for cache loader");
|
);
|
||||||
} catch (Exception e) {
|
|
||||||
executorService = MoreExecutors.listeningDecorator(
|
|
||||||
Executors.newCachedThreadPool(new ThreadFactoryBuilder()
|
|
||||||
.setDaemon(true)
|
|
||||||
.setNameFormat("AuthMe-CacheLoader")
|
|
||||||
.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,7 +41,6 @@ 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;
|
||||||
@ -122,7 +121,6 @@ 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,19 +145,12 @@ 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("useSSL", String.valueOf(useSsl));
|
||||||
ds.addDataSourceProperty("sslMode", mariaDbSslMode);
|
|
||||||
} else {
|
|
||||||
ds.addDataSourceProperty("useSSL", String.valueOf(useSsl));
|
|
||||||
|
|
||||||
// Disabling server certificate verification on need
|
|
||||||
if (!serverCertificateVerification) {
|
|
||||||
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Disabling server certificate verification on need
|
// Disabling server certificate verification on need
|
||||||
|
if (!serverCertificateVerification) {
|
||||||
|
ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false));
|
||||||
|
} // Disabling server certificate verification on need
|
||||||
if (allowPublicKeyRetrieval) {
|
if (allowPublicKeyRetrieval) {
|
||||||
ds.addDataSourceProperty("allowPublicKeyRetrieval", String.valueOf(true));
|
ds.addDataSourceProperty("allowPublicKeyRetrieval", String.valueOf(true));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
package fr.xephi.authme.initialization;
|
package fr.xephi.authme.initialization;
|
||||||
|
|
||||||
import com.alessiodp.libby.Library;
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.data.auth.PlayerCache;
|
import fr.xephi.authme.data.auth.PlayerCache;
|
||||||
import fr.xephi.authme.datasource.CacheDataSource;
|
import fr.xephi.authme.datasource.CacheDataSource;
|
||||||
@ -22,8 +21,6 @@ import javax.inject.Provider;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import static fr.xephi.authme.AuthMe.libraryManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the AuthMe data source.
|
* Creates the AuthMe data source.
|
||||||
*/
|
*/
|
||||||
@ -81,13 +78,6 @@ public class DataSourceProvider implements Provider<DataSource> {
|
|||||||
dataSource = new SQLite(settings, dataFolder);
|
dataSource = new SQLite(settings, dataFolder);
|
||||||
break;
|
break;
|
||||||
case H2:
|
case H2:
|
||||||
Library h2 = Library.builder()
|
|
||||||
.groupId("com.h2database")
|
|
||||||
.artifactId("h2")
|
|
||||||
.version("2.2.224")
|
|
||||||
.build();
|
|
||||||
libraryManager.addMavenCentral();
|
|
||||||
libraryManager.loadLibrary(h2);
|
|
||||||
dataSource = new H2(settings, dataFolder);
|
dataSource = new H2(settings, dataFolder);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskSchedule
|
|||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for asynchronous tasks to complete before closing the data source
|
* Waits for asynchronous tasks to complete before closing the data source
|
||||||
* so the plugin can shut down properly.
|
* so the plugin can shut down properly.
|
||||||
@ -11,15 +13,20 @@ import fr.xephi.authme.datasource.DataSource;
|
|||||||
public class TaskCloser implements Runnable {
|
public class TaskCloser implements Runnable {
|
||||||
|
|
||||||
private final TaskScheduler scheduler;
|
private final TaskScheduler scheduler;
|
||||||
|
private final Logger logger;
|
||||||
|
private final AuthMe plugin;
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
* @param plugin the plugin instance
|
||||||
* @param dataSource the data source (nullable)
|
* @param dataSource the data source (nullable)
|
||||||
*/
|
*/
|
||||||
public TaskCloser(DataSource dataSource) {
|
public TaskCloser(AuthMe plugin, DataSource dataSource) {
|
||||||
this.scheduler = AuthMe.getScheduler();
|
this.scheduler = AuthMe.getScheduler();
|
||||||
|
this.logger = plugin.getLogger();
|
||||||
|
this.plugin = plugin;
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,16 +39,14 @@ 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.MONITOR)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
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, true);
|
messages.send(player, MessageKey.BEDROCK_AUTO_LOGGED_IN);
|
||||||
messages.send(player, MessageKey.BEDROCK_AUTO_LOGGED_IN);
|
}
|
||||||
}
|
|
||||||
},20L);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
263
src/main/java/fr/xephi/authme/listener/GuiCaptchaHandler.java
Normal file
263
src/main/java/fr/xephi/authme/listener/GuiCaptchaHandler.java
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
package fr.xephi.authme.listener;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.ListenerPriority;
|
||||||
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import fr.xephi.authme.AuthMe;
|
||||||
|
import fr.xephi.authme.api.v3.AuthMeApi;
|
||||||
|
import fr.xephi.authme.events.LoginEvent;
|
||||||
|
import fr.xephi.authme.message.MessageKey;
|
||||||
|
import fr.xephi.authme.message.Messages;
|
||||||
|
import fr.xephi.authme.service.BukkitService;
|
||||||
|
import fr.xephi.authme.service.CommonService;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static fr.xephi.authme.util.PlayerUtils.getPlayerIp;
|
||||||
|
import static fr.xephi.authme.util.PlayerUtils.isNpc;
|
||||||
|
import static org.bukkit.Bukkit.getLogger;
|
||||||
|
import static org.bukkit.Bukkit.getServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class handles ALL the GUI captcha features in the plugin.
|
||||||
|
*/
|
||||||
|
public class GuiCaptchaHandler implements Listener {
|
||||||
|
//define AuthMeApi
|
||||||
|
private final AuthMeApi authmeApi = AuthMeApi.getInstance();
|
||||||
|
@Inject
|
||||||
|
private BukkitService bukkitService;
|
||||||
|
@Inject
|
||||||
|
private AuthMe plugin;
|
||||||
|
@Inject
|
||||||
|
private Messages messages;
|
||||||
|
@Inject
|
||||||
|
private CommonService service;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
|
|
||||||
|
private PacketAdapter chatPacketListener;
|
||||||
|
private PacketAdapter windowPacketListener;
|
||||||
|
|
||||||
|
//define timesLeft
|
||||||
|
private int timesLeft = 3;
|
||||||
|
//Use ConcurrentHashMap to store player and their close reason
|
||||||
|
/* We used many async tasks so there is concurrent**/
|
||||||
|
public static ConcurrentHashMap<Player, String> closeReasonMap = new ConcurrentHashMap<>();
|
||||||
|
//define randomStringSet
|
||||||
|
String randomSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz!@#%&*()_+";
|
||||||
|
String randomString = "";
|
||||||
|
Random randomItemSet = new Random();
|
||||||
|
Random howManyRandom = new Random();
|
||||||
|
private Material captchaMaterial = getRandomMaterial();
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isPacketListenersActive = false;
|
||||||
|
|
||||||
|
public GuiCaptchaHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringBuilder sb;
|
||||||
|
private final List<String> whiteList = AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_COUNTRY_WHITELIST);
|
||||||
|
|
||||||
|
private boolean isBedrockPlayer(UUID uuid) {
|
||||||
|
if (getServer().getPluginManager().getPlugin("floodgate") != null) {
|
||||||
|
return settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && settings.getProperty(SecuritySettings.GUI_CAPTCHA_BE_COMPATIBILITY) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(uuid);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initializePacketListeners() {
|
||||||
|
if (!isPacketListenersActive) {
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(windowPacketListener);
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(chatPacketListener);
|
||||||
|
isPacketListenersActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(InventoryClickEvent event) {
|
||||||
|
if (event.getWhoClicked() instanceof Player) {
|
||||||
|
Player player = (Player) event.getWhoClicked();
|
||||||
|
ItemStack currentItem = event.getCurrentItem();
|
||||||
|
if (!authmeApi.isRegistered(player.getName())) {
|
||||||
|
if (isBedrockPlayer(player.getUniqueId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentItem != null && currentItem.getType().equals(captchaMaterial)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
if (!closeReasonMap.containsKey(player)) {
|
||||||
|
closeReasonMap.put(player, "verified");
|
||||||
|
}
|
||||||
|
player.closeInventory();
|
||||||
|
messages.send(player, MessageKey.GUI_CAPTCHA_VERIFIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
bukkitService.runTaskAsynchronously(() -> {
|
||||||
|
sb = new StringBuilder();
|
||||||
|
int howLongIsRandomString = (howManyRandom.nextInt(3) + 1);
|
||||||
|
for (int i = 0; i < howLongIsRandomString; i++) {
|
||||||
|
//生成随机索引号
|
||||||
|
int index = randomItemSet.nextInt(randomSet.length());
|
||||||
|
|
||||||
|
// 从字符串中获取由索引 index 指定的字符
|
||||||
|
char randomChar = randomSet.charAt(index);
|
||||||
|
|
||||||
|
// 将字符追加到字符串生成器
|
||||||
|
sb.append(randomChar);
|
||||||
|
}
|
||||||
|
if (!whiteList.isEmpty()) {
|
||||||
|
String ip = getPlayerIp(player);
|
||||||
|
if (whiteList.contains(authmeApi.getCountryCode(ip)) && ip != null) {
|
||||||
|
if (!closeReasonMap.containsKey(player)) {
|
||||||
|
closeReasonMap.put(player, "verified:whitelist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
randomString = "";
|
||||||
|
Player playerunreg = event.getPlayer();
|
||||||
|
String name = playerunreg.getName();
|
||||||
|
if (!authmeApi.isRegistered(name) && !isNpc(playerunreg) && !closeReasonMap.containsKey(playerunreg)) {
|
||||||
|
if (isBedrockPlayer(playerunreg.getUniqueId())) {
|
||||||
|
if (!closeReasonMap.containsKey(playerunreg)) {
|
||||||
|
closeReasonMap.put(playerunreg, "verified:bedrock");
|
||||||
|
}
|
||||||
|
messages.send(playerunreg, MessageKey.GUI_CAPTCHA_VERIFIED_AUTO_BEDROCK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
randomString = sb.toString();
|
||||||
|
Random random_blockpos = new Random();
|
||||||
|
AtomicInteger random_num = new AtomicInteger(random_blockpos.nextInt(27));
|
||||||
|
Inventory menu = Bukkit.createInventory(playerunreg, 27, messages.retrieveSingle(playerunreg, MessageKey.GUI_CAPTCHA_WINDOW_NAME, randomString));
|
||||||
|
ItemStack item = new ItemStack(captchaMaterial);
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
try {
|
||||||
|
if (meta != null) {
|
||||||
|
meta.setDisplayName(messages.retrieveSingle(playerunreg, MessageKey.GUI_CAPTCHA_CLICKABLE_NAME, randomString));
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
getLogger().log(Level.WARNING, "Unexpected error occurred while setting item meta.");
|
||||||
|
}
|
||||||
|
windowPacketListener = new PacketAdapter(this.plugin, ListenerPriority.HIGHEST, PacketType.Play.Client.CLOSE_WINDOW) {
|
||||||
|
@Override
|
||||||
|
public void onPacketReceiving(PacketEvent event) {
|
||||||
|
Player packetPlayer = event.getPlayer();
|
||||||
|
if (!closeReasonMap.containsKey(packetPlayer) && !authmeApi.isRegistered(packetPlayer.getName())) {
|
||||||
|
if (timesLeft <= 0) {
|
||||||
|
bukkitService.runTask(() -> {
|
||||||
|
packetPlayer.kickPlayer(service.retrieveSingleMessage(packetPlayer, MessageKey.GUI_CAPTCHA_KICK_FAILED));
|
||||||
|
});
|
||||||
|
timesLeft = 3;
|
||||||
|
} else {
|
||||||
|
--timesLeft;
|
||||||
|
if (timesLeft <= 0) {
|
||||||
|
bukkitService.runTask(() -> {
|
||||||
|
packetPlayer.kickPlayer(service.retrieveSingleMessage(packetPlayer, MessageKey.GUI_CAPTCHA_KICK_FAILED));
|
||||||
|
});
|
||||||
|
timesLeft = 3;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messages.send(packetPlayer, MessageKey.GUI_CAPTCHA_RETRY_MESSAGE, String.valueOf(timesLeft));
|
||||||
|
event.setCancelled(true);
|
||||||
|
random_num.set(random_blockpos.nextInt(26));
|
||||||
|
bukkitService.runTask(() -> {
|
||||||
|
menu.clear();
|
||||||
|
menu.setItem(random_num.get(), item);
|
||||||
|
packetPlayer.openInventory(menu);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
chatPacketListener = new PacketAdapter(this.plugin, ListenerPriority.HIGHEST, PacketType.Play.Client.CHAT) {
|
||||||
|
@Override
|
||||||
|
public void onPacketReceiving(PacketEvent event) {
|
||||||
|
Player packetPlayer = event.getPlayer();
|
||||||
|
if (!closeReasonMap.containsKey(packetPlayer) && !authmeApi.isRegistered(packetPlayer.getName())) {
|
||||||
|
messages.send(packetPlayer, MessageKey.GUI_CAPTCHA_DENIED_MESSAGE);
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
initializePacketListeners();
|
||||||
|
//Open captcha inventory
|
||||||
|
menu.setItem(random_num.get(), item);
|
||||||
|
playerunreg.openInventory(menu);
|
||||||
|
if (settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT) > 0) {
|
||||||
|
long timeOut = settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT);
|
||||||
|
if (settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT) > settings.getProperty(RestrictionSettings.TIMEOUT)) {
|
||||||
|
bukkitService.runTask(() -> {
|
||||||
|
getLogger().warning("AuthMe detected that your GUI captcha timeout seconds(" + settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT) + ") is bigger than the Login timeout seconds(" +
|
||||||
|
settings.getProperty(RestrictionSettings.TIMEOUT) + "). To prevent issues, we will let the GUI captcha follow the Login timeout seconds, please check and modify your config.");
|
||||||
|
});
|
||||||
|
timeOut = settings.getProperty(RestrictionSettings.TIMEOUT);
|
||||||
|
}
|
||||||
|
long finalTimeOut = timeOut;
|
||||||
|
bukkitService.runTaskLater(() -> {
|
||||||
|
if (!closeReasonMap.containsKey(playerunreg) && !authmeApi.isRegistered(playerunreg.getName())) {
|
||||||
|
playerunreg.kickPlayer(service.retrieveSingleMessage(playerunreg, MessageKey.GUI_CAPTCHA_KICK_TIMEOUT));
|
||||||
|
timesLeft = 3; // Reset the attempt counter
|
||||||
|
}
|
||||||
|
}, finalTimeOut * 20L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//This prevents players from unregistering by Admins
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerAuthMeLogin(LoginEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!closeReasonMap.containsKey(player)) {
|
||||||
|
closeReasonMap.put(player, "verified:login");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Material getRandomMaterial() {
|
||||||
|
Material[] allMaterials = Material.values();
|
||||||
|
Random random = new Random();
|
||||||
|
return allMaterials[random.nextInt(allMaterials.length)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,11 +1,14 @@
|
|||||||
package fr.xephi.authme.listener;
|
package fr.xephi.authme.listener;
|
||||||
|
|
||||||
|
import fr.xephi.authme.AuthMe;
|
||||||
|
import fr.xephi.authme.api.v3.AuthMeApi;
|
||||||
import fr.xephi.authme.data.auth.PlayerCache;
|
import fr.xephi.authme.data.auth.PlayerCache;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.initialization.SettingsDependent;
|
import fr.xephi.authme.initialization.SettingsDependent;
|
||||||
import fr.xephi.authme.service.ValidationService;
|
import fr.xephi.authme.service.ValidationService;
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.util.PlayerUtils;
|
import fr.xephi.authme.util.PlayerUtils;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -18,6 +21,7 @@ import javax.inject.Inject;
|
|||||||
* Service class for the AuthMe listeners to determine whether an event should be canceled.
|
* Service class for the AuthMe listeners to determine whether an event should be canceled.
|
||||||
*/
|
*/
|
||||||
class ListenerService implements SettingsDependent {
|
class ListenerService implements SettingsDependent {
|
||||||
|
private final AuthMeApi authmeApi = AuthMeApi.getInstance();
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final PlayerCache playerCache;
|
private final PlayerCache playerCache;
|
||||||
private final ValidationService validationService;
|
private final ValidationService validationService;
|
||||||
@ -75,9 +79,19 @@ class ListenerService implements SettingsDependent {
|
|||||||
* @param player the player to verify
|
* @param player the player to verify
|
||||||
* @return true if the associated event should be canceled, false otherwise
|
* @return true if the associated event should be canceled, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public boolean shouldCancelEvent(Player player) {
|
public boolean shouldCancelEvent(Player player) {
|
||||||
|
|
||||||
return player != null && !checkAuth(player.getName()) && !PlayerUtils.isNpc(player);
|
return player != null && !checkAuth(player.getName()) && !PlayerUtils.isNpc(player);
|
||||||
}
|
}
|
||||||
|
public boolean shouldCancelInvEvent(Player player) {
|
||||||
|
try {
|
||||||
|
return !AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA) || authmeApi.isRegistered(player.getName()) || GuiCaptchaHandler.closeReasonMap.containsKey(player)/* || !player.getOpenInventory().getTitle().equals("请验证你是真人")*/;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reload(Settings settings) {
|
public void reload(Settings settings) {
|
||||||
isRegistrationForced = settings.getProperty(RegistrationSettings.FORCE);
|
isRegistrationForced = settings.getProperty(RegistrationSettings.FORCE);
|
||||||
|
|||||||
@ -75,7 +75,11 @@ public class LoginLocationFixListener implements Listener {
|
|||||||
boolean solved = false;
|
boolean solved = false;
|
||||||
for (BlockFace face : faces) {
|
for (BlockFace face : faces) {
|
||||||
if (JoinBlock.getRelative(face).getType().equals(Material.AIR) && JoinBlock.getRelative(face).getRelative(BlockFace.UP).getType().equals(Material.AIR)) {
|
if (JoinBlock.getRelative(face).getType().equals(Material.AIR) && JoinBlock.getRelative(face).getRelative(BlockFace.UP).getType().equals(Material.AIR)) {
|
||||||
TeleportUtils.teleport(player, JoinBlock.getRelative(face).getLocation().add(0.5, 0.1, 0.5));
|
if (settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
|
TeleportUtils.teleport(player, JoinBlock.getRelative(face).getLocation().add(0.5, 0.1, 0.5));
|
||||||
|
} else {
|
||||||
|
player.teleport(JoinBlock.getRelative(face).getLocation().add(0.5, 0.1, 0.5));
|
||||||
|
}
|
||||||
solved = true;
|
solved = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -103,12 +107,20 @@ public class LoginLocationFixListener implements Listener {
|
|||||||
if (JoinBlock.getRelative(BlockFace.DOWN).getType().equals(Material.LAVA)) {
|
if (JoinBlock.getRelative(BlockFace.DOWN).getType().equals(Material.LAVA)) {
|
||||||
JoinBlock.getRelative(BlockFace.DOWN).setType(Material.DIRT);
|
JoinBlock.getRelative(BlockFace.DOWN).setType(Material.DIRT);
|
||||||
}
|
}
|
||||||
TeleportUtils.teleport(player, JoinBlock.getLocation().add(0.5, 0.1, 0.5));
|
if (settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
|
TeleportUtils.teleport(player, JoinBlock.getLocation().add(0.5, 0.1, 0.5));
|
||||||
|
} else {
|
||||||
|
player.teleport(JoinBlock.getLocation().add(0.5, 0.1, 0.5));
|
||||||
|
}
|
||||||
messages.send(player, MessageKey.LOCATION_FIX_UNDERGROUND);
|
messages.send(player, MessageKey.LOCATION_FIX_UNDERGROUND);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == MaxHeight) {
|
if (i == MaxHeight) {
|
||||||
TeleportUtils.teleport(player, JoinBlock.getLocation().add(0.5, 1.1, 0.5));
|
if (settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
|
TeleportUtils.teleport(player, JoinBlock.getLocation().add(0.5, 1.1, 0.5));
|
||||||
|
} else {
|
||||||
|
player.teleport(JoinBlock.getLocation().add(0.5, 1.1, 0.5));
|
||||||
|
}
|
||||||
messages.send(player, MessageKey.LOCATION_FIX_UNDERGROUND_CANT_FIX);
|
messages.send(player, MessageKey.LOCATION_FIX_UNDERGROUND_CANT_FIX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package fr.xephi.authme.listener;
|
package fr.xephi.authme.listener;
|
||||||
|
|
||||||
|
import fr.xephi.authme.api.v3.AuthMeApi;
|
||||||
import fr.xephi.authme.data.QuickCommandsProtectionManager;
|
import fr.xephi.authme.data.QuickCommandsProtectionManager;
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
@ -16,12 +17,10 @@ import fr.xephi.authme.service.ValidationService;
|
|||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.SpawnLoader;
|
import fr.xephi.authme.settings.SpawnLoader;
|
||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.util.TeleportUtils;
|
import fr.xephi.authme.util.TeleportUtils;
|
||||||
import fr.xephi.authme.util.message.I18NUtils;
|
|
||||||
import fr.xephi.authme.util.message.MiniMessageUtils;
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
@ -65,7 +64,12 @@ import static org.bukkit.Bukkit.getServer;
|
|||||||
/**
|
/**
|
||||||
* Listener class for player events.
|
* Listener class for player events.
|
||||||
*/
|
*/
|
||||||
public class PlayerListener implements Listener {
|
public class PlayerListener implements Listener{
|
||||||
|
private final AuthMeApi authmeApi = AuthMeApi.getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Settings settings;
|
private Settings settings;
|
||||||
@Inject
|
@Inject
|
||||||
@ -95,6 +99,7 @@ public class PlayerListener implements Listener {
|
|||||||
@Inject
|
@Inject
|
||||||
private QuickCommandsProtectionManager quickCommandsProtectionManager;
|
private QuickCommandsProtectionManager quickCommandsProtectionManager;
|
||||||
|
|
||||||
|
|
||||||
// Lowest priority to apply fast protection checks
|
// Lowest priority to apply fast protection checks
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onAsyncPlayerPreLoginEventLowest(AsyncPlayerPreLoginEvent event) {
|
public void onAsyncPlayerPreLoginEventLowest(AsyncPlayerPreLoginEvent event) {
|
||||||
@ -114,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) && settings.getProperty(HooksSettings.IGNORE_BEDROCK_NAME_CHECK)) {
|
if (settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER)) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -188,6 +193,7 @@ public class PlayerListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.NORMAL)
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
|
final AuthMeApi authmeApi = AuthMeApi.getInstance();
|
||||||
if (!PlayerListener19Spigot.isPlayerSpawnLocationEventCalled()) {
|
if (!PlayerListener19Spigot.isPlayerSpawnLocationEventCalled()) {
|
||||||
teleportationService.teleportOnJoin(player);
|
teleportationService.teleportOnJoin(player);
|
||||||
}
|
}
|
||||||
@ -214,7 +220,7 @@ public class PlayerListener implements Listener {
|
|||||||
|
|
||||||
String customJoinMessage = settings.getProperty(RegistrationSettings.CUSTOM_JOIN_MESSAGE);
|
String customJoinMessage = settings.getProperty(RegistrationSettings.CUSTOM_JOIN_MESSAGE);
|
||||||
if (!customJoinMessage.isEmpty()) {
|
if (!customJoinMessage.isEmpty()) {
|
||||||
customJoinMessage = ChatColor.translateAlternateColorCodes('&', MiniMessageUtils.parseMiniMessageToLegacy(customJoinMessage));
|
customJoinMessage = ChatColor.translateAlternateColorCodes('&', customJoinMessage);
|
||||||
event.setJoinMessage(customJoinMessage
|
event.setJoinMessage(customJoinMessage
|
||||||
.replace("{PLAYERNAME}", player.getName())
|
.replace("{PLAYERNAME}", player.getName())
|
||||||
.replace("{DISPLAYNAME}", player.getDisplayName())
|
.replace("{DISPLAYNAME}", player.getDisplayName())
|
||||||
@ -249,11 +255,6 @@ public class PlayerListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove data from locale map when player quit
|
|
||||||
if (settings.getProperty(PluginSettings.I18N_MESSAGES)) {
|
|
||||||
I18NUtils.removeLocale(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (antiBotService.wasPlayerKicked(player.getName())) {
|
if (antiBotService.wasPlayerKicked(player.getName())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -374,9 +375,17 @@ public class PlayerListener implements Listener {
|
|||||||
Location spawn = spawnLoader.getSpawnLocation(player);
|
Location spawn = spawnLoader.getSpawnLocation(player);
|
||||||
if (spawn != null && spawn.getWorld() != null) {
|
if (spawn != null && spawn.getWorld() != null) {
|
||||||
if (!player.getWorld().equals(spawn.getWorld())) {
|
if (!player.getWorld().equals(spawn.getWorld())) {
|
||||||
TeleportUtils.teleport(player,spawn);
|
if(settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
|
TeleportUtils.teleport(player,spawn);
|
||||||
|
} else {
|
||||||
|
player.teleport(spawn);
|
||||||
|
}
|
||||||
} else if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) {
|
} else if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) {
|
||||||
TeleportUtils.teleport(player,spawn);
|
if(settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
|
TeleportUtils.teleport(player,spawn);
|
||||||
|
} else {
|
||||||
|
player.teleport(spawn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -495,33 +504,21 @@ public class PlayerListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private boolean isInventoryWhitelisted(InventoryView inventory) {
|
private boolean isInventoryWhitelisted(InventoryView inventory) {
|
||||||
if (inventory == null) {
|
if (inventory == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Set<String> whitelist = settings.getProperty(RestrictionSettings.UNRESTRICTED_INVENTORIES);
|
Set<String> whitelist = settings.getProperty(RestrictionSettings.UNRESTRICTED_INVENTORIES);
|
||||||
if (whitelist.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//append a string for String whitelist
|
//append a string for String whitelist
|
||||||
String invName = ChatColor.stripColor(inventory.getTitle()).toLowerCase(Locale.ROOT);
|
return whitelist.contains(ChatColor.stripColor(inventory.getTitle()).toLowerCase(Locale.ROOT));
|
||||||
if (settings.getProperty(RestrictionSettings.STRICT_UNRESTRICTED_INVENTORIES_CHECK)) {
|
|
||||||
return whitelist.contains(invName);
|
|
||||||
}
|
|
||||||
for (String wl : whitelist) {
|
|
||||||
if (invName.contains(wl)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||||
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
|
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
|
||||||
final HumanEntity player = event.getPlayer();
|
final HumanEntity player = event.getPlayer();
|
||||||
|
Player ply = (Player) event.getPlayer();
|
||||||
if (listenerService.shouldCancelEvent(player)
|
if (listenerService.shouldCancelEvent(player)
|
||||||
&& !isInventoryWhitelisted(event.getView())) {
|
&& !isInventoryWhitelisted(event.getView()) && listenerService.shouldCancelInvEvent(ply)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -539,4 +536,12 @@ public class PlayerListener implements Listener {
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// @EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
// public void onSwitchHand(PlayerSwapHandItemsEvent event) {
|
||||||
|
// Player player = event.getPlayer();
|
||||||
|
// if (!player.isSneaking() || !player.hasPermission("keybindings.use"))
|
||||||
|
// return;
|
||||||
|
// event.setCancelled(true);
|
||||||
|
// Bukkit.dispatchCommand(event.getPlayer(), "help");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
package fr.xephi.authme.listener;
|
package fr.xephi.authme.listener;
|
||||||
|
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
|
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||||
|
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -22,4 +26,12 @@ public class PlayerListenerHigherThan18 implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onSwitchHand(PlayerSwapHandItemsEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (player.isSneaking() && player.hasPermission("keybindings.use") && settings.getProperty(PluginSettings.MENU_UNREGISTER_COMPATIBILITY)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
Bukkit.dispatchCommand(event.getPlayer(), "help");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,15 +52,11 @@ 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) {
|
||||||
|
|||||||
@ -53,9 +53,6 @@ public class ServerListener implements Listener {
|
|||||||
} else if ("ProtocolLib".equalsIgnoreCase(pluginName)) {
|
} else if ("ProtocolLib".equalsIgnoreCase(pluginName)) {
|
||||||
protocolLibService.disable();
|
protocolLibService.disable();
|
||||||
logger.warning("ProtocolLib has been disabled, unhooking packet adapters!");
|
logger.warning("ProtocolLib has been disabled, unhooking packet adapters!");
|
||||||
} else if ("PlaceholderAPI".equalsIgnoreCase(pluginName)) {
|
|
||||||
pluginHookService.unhookPlaceholderApi();
|
|
||||||
logger.info("PlaceholderAPI has been disabled: unhooking placeholders");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +74,6 @@ public class ServerListener implements Listener {
|
|||||||
spawnLoader.loadCmiSpawn();
|
spawnLoader.loadCmiSpawn();
|
||||||
} else if ("ProtocolLib".equalsIgnoreCase(pluginName)) {
|
} else if ("ProtocolLib".equalsIgnoreCase(pluginName)) {
|
||||||
protocolLibService.setup();
|
protocolLibService.setup();
|
||||||
} else if ("PlaceholderAPI".equalsIgnoreCase(pluginName)) {
|
|
||||||
pluginHookService.tryHookToPlaceholderApi();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
package fr.xephi.authme.listener.protocollib;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.ListenerPriority;
|
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import fr.xephi.authme.AuthMe;
|
|
||||||
import fr.xephi.authme.util.message.I18NUtils;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
class I18NGetLocalePacketAdapter extends PacketAdapter {
|
|
||||||
|
|
||||||
I18NGetLocalePacketAdapter(AuthMe plugin) {
|
|
||||||
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.SETTINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
|
||||||
if (event.getPacketType() == PacketType.Play.Client.SETTINGS) {
|
|
||||||
String locale = event.getPacket().getStrings().read(0).toLowerCase();
|
|
||||||
UUID uuid = event.getPlayer().getUniqueId();
|
|
||||||
|
|
||||||
I18NUtils.addLocale(uuid, locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unregister() {
|
|
||||||
ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -9,9 +9,7 @@ import fr.xephi.authme.initialization.SettingsDependent;
|
|||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
import fr.xephi.authme.util.Utils;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -24,12 +22,10 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
/* Packet Adapters */
|
/* Packet Adapters */
|
||||||
private InventoryPacketAdapter inventoryPacketAdapter;
|
private InventoryPacketAdapter inventoryPacketAdapter;
|
||||||
private TabCompletePacketAdapter tabCompletePacketAdapter;
|
private TabCompletePacketAdapter tabCompletePacketAdapter;
|
||||||
private I18NGetLocalePacketAdapter i18nGetLocalePacketAdapter;
|
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
private boolean protectInvBeforeLogin;
|
private boolean protectInvBeforeLogin;
|
||||||
private boolean denyTabCompleteBeforeLogin;
|
private boolean denyTabCompleteBeforeLogin;
|
||||||
private boolean i18nMessagesSending;
|
|
||||||
|
|
||||||
/* Service */
|
/* Service */
|
||||||
private boolean isEnabled;
|
private boolean isEnabled;
|
||||||
@ -62,10 +58,6 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
logger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it...");
|
logger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i18nMessagesSending) {
|
|
||||||
logger.warning("WARNING! The i18n Messages feature requires ProtocolLib on lower version (< 1.15.2)! Disabling it...");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isEnabled = false;
|
this.isEnabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,16 +84,6 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
tabCompletePacketAdapter = null;
|
tabCompletePacketAdapter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i18nMessagesSending) {
|
|
||||||
if (i18nGetLocalePacketAdapter == null) {
|
|
||||||
i18nGetLocalePacketAdapter = new I18NGetLocalePacketAdapter(plugin);
|
|
||||||
i18nGetLocalePacketAdapter.register();
|
|
||||||
}
|
|
||||||
} else if (i18nGetLocalePacketAdapter != null) {
|
|
||||||
i18nGetLocalePacketAdapter.unregister();
|
|
||||||
i18nGetLocalePacketAdapter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isEnabled = true;
|
this.isEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,10 +101,6 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
tabCompletePacketAdapter.unregister();
|
tabCompletePacketAdapter.unregister();
|
||||||
tabCompletePacketAdapter = null;
|
tabCompletePacketAdapter = null;
|
||||||
}
|
}
|
||||||
if (i18nGetLocalePacketAdapter != null) {
|
|
||||||
i18nGetLocalePacketAdapter.unregister();
|
|
||||||
i18nGetLocalePacketAdapter = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,7 +120,6 @@ public class ProtocolLibService implements SettingsDependent {
|
|||||||
|
|
||||||
this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
||||||
this.denyTabCompleteBeforeLogin = settings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN);
|
this.denyTabCompleteBeforeLogin = settings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN);
|
||||||
this.i18nMessagesSending = settings.getProperty(PluginSettings.I18N_MESSAGES) && Utils.MAJOR_VERSION <= 15;
|
|
||||||
|
|
||||||
//it was true and will be deactivated now, so we need to restore the inventory for every player
|
//it was true and will be deactivated now, so we need to restore the inventory for every player
|
||||||
if (oldProtectInventory && !protectInvBeforeLogin && inventoryPacketAdapter != null) {
|
if (oldProtectInventory && !protectInvBeforeLogin && inventoryPacketAdapter != null) {
|
||||||
|
|||||||
@ -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 shutdown:", e);
|
logger.logException("Failed to create email for recovery code:", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,15 +8,12 @@ import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||||
import fr.xephi.authme.util.FileUtils;
|
import fr.xephi.authme.util.FileUtils;
|
||||||
import fr.xephi.authme.util.message.I18NUtils;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
|
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
|
||||||
|
|
||||||
@ -36,7 +33,6 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
|
|||||||
|
|
||||||
private String filename;
|
private String filename;
|
||||||
private FileConfiguration configuration;
|
private FileConfiguration configuration;
|
||||||
private Map<String, FileConfiguration> i18nConfiguration;
|
|
||||||
private final String defaultFile;
|
private final String defaultFile;
|
||||||
|
|
||||||
protected AbstractMessageFileHandler() {
|
protected AbstractMessageFileHandler() {
|
||||||
@ -50,7 +46,6 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
|
|||||||
filename = createFilePath(language);
|
filename = createFilePath(language);
|
||||||
File messagesFile = initializeFile(filename);
|
File messagesFile = initializeFile(filename);
|
||||||
configuration = YamlConfiguration.loadConfiguration(messagesFile);
|
configuration = YamlConfiguration.loadConfiguration(messagesFile);
|
||||||
i18nConfiguration = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getLanguage() {
|
protected String getLanguage() {
|
||||||
@ -88,24 +83,6 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
|
|||||||
: message;
|
: message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the i18n message for the given key and given locale.
|
|
||||||
*
|
|
||||||
* @param key the key to retrieve the message for
|
|
||||||
* @param locale the locale that player client setting uses
|
|
||||||
* @return the message
|
|
||||||
*/
|
|
||||||
public String getMessageByLocale(String key, String locale) {
|
|
||||||
if (locale == null || !settings.getProperty(PluginSettings.I18N_MESSAGES)) {
|
|
||||||
return getMessage(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
String message = getI18nConfiguration(locale).getString(key);
|
|
||||||
return message == null
|
|
||||||
? "Error retrieving message '" + key + "'"
|
|
||||||
: message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message for the given key only if it exists,
|
* Returns the message for the given key only if it exists,
|
||||||
* i.e. without falling back to the default file.
|
* i.e. without falling back to the default file.
|
||||||
@ -117,27 +94,6 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
|
|||||||
return configuration.getString(key);
|
return configuration.getString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileConfiguration getI18nConfiguration(String locale) {
|
|
||||||
if (i18nConfiguration == null) {
|
|
||||||
i18nConfiguration = new ConcurrentHashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
locale = I18NUtils.localeToCode(locale, settings);
|
|
||||||
|
|
||||||
if (i18nConfiguration.containsKey(locale)) {
|
|
||||||
return i18nConfiguration.get(locale);
|
|
||||||
} else {
|
|
||||||
// Sync with reload();
|
|
||||||
String i18nFilename = createFilePath(locale);
|
|
||||||
File i18nMessagesFile = initializeFile(i18nFilename);
|
|
||||||
FileConfiguration config = YamlConfiguration.loadConfiguration(i18nMessagesFile);
|
|
||||||
|
|
||||||
i18nConfiguration.put(locale, config);
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the path to the messages file for the given language code.
|
* Creates the path to the messages file for the given language code.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -29,6 +29,46 @@ public enum MessageKey {
|
|||||||
*/
|
*/
|
||||||
BEDROCK_AUTO_LOGGED_IN("bedrock_auto_login.success"),
|
BEDROCK_AUTO_LOGGED_IN("bedrock_auto_login.success"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* %random Verification
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_WINDOW_NAME("gui_captcha.captcha_window_name", "%random"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* %random I am human
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_CLICKABLE_NAME("gui_captcha.captcha_clickable_name", "%random"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verification failed, you have %times retries left
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_RETRY_MESSAGE("gui_captcha.message_on_retry", "%times"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bedrock verification success!
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_VERIFIED_AUTO_BEDROCK("gui_captcha.bedrock_auto_verify_success"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Please be verified before chatting!
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_DENIED_MESSAGE("gui_captcha.denied_message_sending"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verification timed out!
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_KICK_TIMEOUT("gui_captcha.kick_on_timeout"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Please complete the verification!
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_KICK_FAILED("gui_captcha.kick_on_failed"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verification success!
|
||||||
|
*/
|
||||||
|
GUI_CAPTCHA_VERIFIED("gui_captcha.success"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In order to use this command you must be authenticated!
|
* In order to use this command you must be authenticated!
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -5,8 +5,6 @@ import fr.xephi.authme.ConsoleLogger;
|
|||||||
import fr.xephi.authme.mail.EmailService;
|
import fr.xephi.authme.mail.EmailService;
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
import fr.xephi.authme.util.expiring.Duration;
|
import fr.xephi.authme.util.expiring.Duration;
|
||||||
import fr.xephi.authme.util.message.I18NUtils;
|
|
||||||
import fr.xephi.authme.util.message.MiniMessageUtils;
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -122,16 +120,13 @@ public class Messages {
|
|||||||
* @return The message from the file
|
* @return The message from the file
|
||||||
*/
|
*/
|
||||||
private String retrieveMessage(MessageKey key, CommandSender sender) {
|
private String retrieveMessage(MessageKey key, CommandSender sender) {
|
||||||
String locale = sender instanceof Player
|
String message = messagesFileHandler.getMessage(key.getKey());
|
||||||
? I18NUtils.getLocale((Player) sender)
|
|
||||||
: null;
|
|
||||||
String message = messagesFileHandler.getMessageByLocale(key.getKey(), locale);
|
|
||||||
String displayName = sender.getName();
|
String displayName = sender.getName();
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
displayName = ((Player) sender).getDisplayName();
|
displayName = ((Player) sender).getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ChatColor.translateAlternateColorCodes('&', MiniMessageUtils.parseMiniMessageToLegacy(message))
|
return ChatColor.translateAlternateColorCodes('&', message)
|
||||||
.replace(NEWLINE_TAG, "\n")
|
.replace(NEWLINE_TAG, "\n")
|
||||||
.replace(USERNAME_TAG, sender.getName())
|
.replace(USERNAME_TAG, sender.getName())
|
||||||
.replace(DISPLAYNAME_TAG, displayName);
|
.replace(DISPLAYNAME_TAG, displayName);
|
||||||
@ -147,7 +142,7 @@ public class Messages {
|
|||||||
private String retrieveMessage(MessageKey key, String name) {
|
private String retrieveMessage(MessageKey key, String name) {
|
||||||
String message = messagesFileHandler.getMessage(key.getKey());
|
String message = messagesFileHandler.getMessage(key.getKey());
|
||||||
|
|
||||||
return ChatColor.translateAlternateColorCodes('&', MiniMessageUtils.parseMiniMessageToLegacy(message))
|
return ChatColor.translateAlternateColorCodes('&', message)
|
||||||
.replace(NEWLINE_TAG, "\n")
|
.replace(NEWLINE_TAG, "\n")
|
||||||
.replace(USERNAME_TAG, name)
|
.replace(USERNAME_TAG, name)
|
||||||
.replace(DISPLAYNAME_TAG, name);
|
.replace(DISPLAYNAME_TAG, name);
|
||||||
|
|||||||
@ -149,6 +149,7 @@ public class MessageUpdater {
|
|||||||
.put("verification", "Verification code")
|
.put("verification", "Verification code")
|
||||||
.put("time", "Time units")
|
.put("time", "Time units")
|
||||||
.put("two_factor", "Two-factor authentication")
|
.put("two_factor", "Two-factor authentication")
|
||||||
|
.put("gui_captcha", "3rd party features: GUI Captcha")
|
||||||
.put("bedrock_auto_login", "3rd party features: Bedrock Auto Login")
|
.put("bedrock_auto_login", "3rd party features: Bedrock Auto Login")
|
||||||
.put("login_location_fix", "3rd party features: Login Location Fix")
|
.put("login_location_fix", "3rd party features: Login Location Fix")
|
||||||
.put("double_login_fix", "3rd party features: Double Login Fix")
|
.put("double_login_fix", "3rd party features: Double Login Fix")
|
||||||
@ -170,7 +171,7 @@ public class MessageUpdater {
|
|||||||
|
|
||||||
// Create ConfigurationData instance
|
// Create ConfigurationData instance
|
||||||
Map<String, List<String>> commentsMap = comments.entrySet().stream()
|
Map<String, List<String>> commentsMap = comments.entrySet().stream()
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> singletonList(e.getValue())));
|
.collect(Collectors.toMap(e -> e.getKey(), e -> singletonList(e.getValue())));
|
||||||
return new MessageKeyConfigurationData(builder, commentsMap);
|
return new MessageKeyConfigurationData(builder, commentsMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,9 +17,6 @@ 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;
|
||||||
@ -29,6 +26,8 @@ import fr.xephi.authme.util.PlayerUtils;
|
|||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -46,9 +45,6 @@ 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;
|
||||||
|
|
||||||
@ -79,9 +75,6 @@ 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;
|
||||||
|
|
||||||
@ -135,10 +128,6 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
|
|
||||||
// Session logic
|
// Session logic
|
||||||
if (sessionService.canResumeSession(player)) {
|
if (sessionService.canResumeSession(player)) {
|
||||||
if (velocitySender.isEnabled()) {
|
|
||||||
bukkitService.scheduleSyncDelayedTask(() ->
|
|
||||||
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), service.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
|
||||||
}
|
|
||||||
service.send(player, MessageKey.SESSION_RECONNECTION);
|
service.send(player, MessageKey.SESSION_RECONNECTION);
|
||||||
// Run commands
|
// Run commands
|
||||||
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
|
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
|
||||||
@ -163,11 +152,7 @@ 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), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
|
||||||
}
|
|
||||||
if (velocitySender.isEnabled()) {
|
|
||||||
bukkitService.scheduleSyncDelayedTask(() ->
|
|
||||||
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -206,7 +191,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout;
|
int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout;
|
||||||
|
|
||||||
// AuthMeReReloaded - Fix potion apply on Folia
|
// AuthMeReReloaded - Fix potion apply on Folia
|
||||||
bukkitService.runTaskIfFolia(player, () -> player.addPotionEffect(bukkitService.createBlindnessEffect(blindTimeOut)));
|
bukkitService.runTaskIfFolia(player,() -> player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2)));
|
||||||
}
|
}
|
||||||
commandManager.runCommandsOnJoin(player);
|
commandManager.runCommandsOnJoin(player);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -26,8 +26,6 @@ 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.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;
|
||||||
@ -83,12 +81,9 @@ 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() {
|
||||||
}
|
}
|
||||||
@ -117,7 +112,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
|||||||
*
|
*
|
||||||
* @param player the player to log in
|
* @param player the player to log in
|
||||||
*/
|
*/
|
||||||
public synchronized void forceLogin(Player player) {
|
public void forceLogin(Player player) {
|
||||||
PlayerAuth auth = getPlayerAuth(player);
|
PlayerAuth auth = getPlayerAuth(player);
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
performLogin(player, auth);
|
performLogin(player, auth);
|
||||||
@ -311,7 +306,7 @@ 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), settings.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
|
||||||
}
|
}
|
||||||
|
|
||||||
// As the scheduling executes the Task most likely after the current
|
// As the scheduling executes the Task most likely after the current
|
||||||
|
|||||||
@ -14,10 +14,7 @@ import fr.xephi.authme.service.CommonService;
|
|||||||
import fr.xephi.authme.service.JoinMessageService;
|
import fr.xephi.authme.service.JoinMessageService;
|
||||||
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.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.HooksSettings;
|
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.potion.PotionEffectType;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
@ -33,9 +30,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private VelocitySender velocitySender;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private LimboService limboService;
|
private LimboService limboService;
|
||||||
|
|
||||||
@ -108,13 +102,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
|||||||
player.removePotionEffect(PotionEffectType.BLINDNESS);
|
player.removePotionEffect(PotionEffectType.BLINDNESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthMeVelocity start - send on player login
|
|
||||||
if (velocitySender.isEnabled()) {
|
|
||||||
bukkitService.scheduleSyncDelayedTask(() ->
|
|
||||||
velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), commonService.getProperty(HooksSettings.PROXY_SEND_DELAY));
|
|
||||||
}
|
|
||||||
// AuthMeVelocity end
|
|
||||||
|
|
||||||
// The Login event now fires (as intended) after everything is processed
|
// The Login event now fires (as intended) after everything is processed
|
||||||
bukkitService.callEvent(new LoginEvent(player));
|
bukkitService.callEvent(new LoginEvent(player));
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,7 @@ 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.settings.properties.RestrictionSettings;
|
||||||
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;
|
||||||
@ -43,8 +42,6 @@ public class AsynchronousLogout implements AsynchronousProcess {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private BungeeSender bungeeSender;
|
private BungeeSender bungeeSender;
|
||||||
@Inject
|
|
||||||
private VelocitySender velocitySender;
|
|
||||||
|
|
||||||
AsynchronousLogout() {
|
AsynchronousLogout() {
|
||||||
}
|
}
|
||||||
@ -64,18 +61,17 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,8 @@ 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;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
|
|||||||
// Apply Blindness effect
|
// Apply Blindness effect
|
||||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||||
int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||||
player.addPotionEffect(bukkitService.createBlindnessEffect(timeout));
|
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set player's data to unauthenticated
|
// Set player's data to unauthenticated
|
||||||
|
|||||||
@ -12,6 +12,7 @@ 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;
|
||||||
@ -67,16 +68,13 @@ 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()
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package fr.xephi.authme.process.quit;
|
package fr.xephi.authme.process.quit;
|
||||||
|
|
||||||
import com.github.Anon8281.universalScheduler.UniversalScheduler;
|
|
||||||
import fr.xephi.authme.data.limbo.LimboService;
|
import fr.xephi.authme.data.limbo.LimboService;
|
||||||
import fr.xephi.authme.process.SynchronousProcess;
|
import fr.xephi.authme.process.SynchronousProcess;
|
||||||
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
||||||
@ -28,9 +27,7 @@ public class ProcessSyncPlayerQuit implements SynchronousProcess {
|
|||||||
commandManager.runCommandsOnLogout(player);
|
commandManager.runCommandsOnLogout(player);
|
||||||
} else {
|
} else {
|
||||||
limboService.restoreData(player);
|
limboService.restoreData(player);
|
||||||
if (!UniversalScheduler.isFolia) { // AuthMeReReloaded - Fix #146 (Very stupid solution, but works)
|
player.saveData(); // #1238: Speed is sometimes not restored properly
|
||||||
// player.saveData(); // #1238: Speed is sometimes not restored properly
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
player.leaveVehicle();
|
player.leaveVehicle();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 synchronized <P extends RegistrationParameters> void register(RegistrationMethod<P> variant, P parameters) {
|
public <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,8 +8,6 @@ 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;
|
||||||
|
|
||||||
@ -30,8 +28,6 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private LimboService limboService;
|
private LimboService limboService;
|
||||||
@Inject
|
|
||||||
private VelocitySender velocitySender;
|
|
||||||
|
|
||||||
ProcessSyncEmailRegister() {
|
ProcessSyncEmailRegister() {
|
||||||
}
|
}
|
||||||
@ -44,7 +40,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,8 +9,6 @@ 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;
|
||||||
@ -29,9 +27,6 @@ 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;
|
||||||
|
|
||||||
@ -71,7 +66,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));
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import static fr.xephi.authme.process.register.executors.PlayerAuthBuilderHelper
|
|||||||
class PasswordRegisterExecutor extends AbstractPasswordRegisterExecutor<PasswordRegisterParams> {
|
class PasswordRegisterExecutor extends AbstractPasswordRegisterExecutor<PasswordRegisterParams> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized PlayerAuth createPlayerAuthObject(PasswordRegisterParams params) {
|
public PlayerAuth createPlayerAuthObject(PasswordRegisterParams params) {
|
||||||
return createPlayerAuth(params.getPlayer(), params.getHashedPassword(), params.getEmail());
|
return createPlayerAuth(params.getPlayer(), params.getHashedPassword(), params.getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,13 +16,13 @@ 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;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -56,9 +56,6 @@ 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;
|
||||||
|
|
||||||
@ -79,7 +76,6 @@ 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);
|
||||||
@ -101,8 +97,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);
|
||||||
if (player != null) 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 {
|
||||||
@ -148,7 +144,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
|||||||
private void applyBlindEffect(Player player) {
|
private void applyBlindEffect(Player player) {
|
||||||
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
|
||||||
int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
|
||||||
bukkitService.runTaskIfFolia(player, () -> player.addPotionEffect(bukkitService.createBlindnessEffect(timeout)));
|
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,6 @@ public enum HashAlgorithm {
|
|||||||
WORDPRESS(fr.xephi.authme.security.crypts.Wordpress.class),
|
WORDPRESS(fr.xephi.authme.security.crypts.Wordpress.class),
|
||||||
XAUTH(fr.xephi.authme.security.crypts.XAuth.class),
|
XAUTH(fr.xephi.authme.security.crypts.XAuth.class),
|
||||||
XFBCRYPT(fr.xephi.authme.security.crypts.XfBCrypt.class),
|
XFBCRYPT(fr.xephi.authme.security.crypts.XfBCrypt.class),
|
||||||
NOCRYPT(fr.xephi.authme.security.crypts.NoCrypt.class),
|
|
||||||
CUSTOM(null),
|
CUSTOM(null),
|
||||||
|
|
||||||
@Deprecated DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class),
|
@Deprecated DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class),
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
package fr.xephi.authme.security.crypts;
|
|
||||||
|
|
||||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
|
||||||
import fr.xephi.authme.security.crypts.description.Usage;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@Recommendation(Usage.DEPRECATED)
|
|
||||||
public class NoCrypt extends UnsaltedMethod {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String computeHash(String password) {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package fr.xephi.authme.service;
|
package fr.xephi.authme.service;
|
||||||
|
|
||||||
import com.github.Anon8281.universalScheduler.UniversalRunnable;
|
import com.github.Anon8281.universalScheduler.UniversalRunnable;
|
||||||
import com.github.Anon8281.universalScheduler.UniversalScheduler;
|
|
||||||
import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask;
|
import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask;
|
||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.initialization.SettingsDependent;
|
import fr.xephi.authme.initialization.SettingsDependent;
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||||
|
import fr.xephi.authme.util.Utils;
|
||||||
import org.bukkit.BanEntry;
|
import org.bukkit.BanEntry;
|
||||||
import org.bukkit.BanList;
|
import org.bukkit.BanList;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -18,8 +18,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -40,7 +38,7 @@ public class BukkitService implements SettingsDependent {
|
|||||||
/** Number of ticks per minute. */
|
/** Number of ticks per minute. */
|
||||||
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
|
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
|
||||||
/** Whether the server is running Folia. */
|
/** Whether the server is running Folia. */
|
||||||
private static final boolean isFolia = UniversalScheduler.isFolia;
|
private static final boolean IS_FOLIA = Utils.isClassLoaded("io.papermc.paper.threadedregions.RegionizedServer");
|
||||||
private final AuthMe authMe;
|
private final AuthMe authMe;
|
||||||
private boolean useAsyncTasks;
|
private boolean useAsyncTasks;
|
||||||
|
|
||||||
@ -58,7 +56,7 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @param task Task to be executed
|
* @param task Task to be executed
|
||||||
*/
|
*/
|
||||||
public void scheduleSyncDelayedTask(Runnable task) {
|
public void scheduleSyncDelayedTask(Runnable task) {
|
||||||
runTask(task);
|
getScheduler().runTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,11 +68,7 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @param delay Delay in server ticks before executing task
|
* @param delay Delay in server ticks before executing task
|
||||||
*/
|
*/
|
||||||
public void scheduleSyncDelayedTask(Runnable task, long delay) {
|
public void scheduleSyncDelayedTask(Runnable task, long delay) {
|
||||||
if (isFolia) {
|
getScheduler().runTaskLater(task, delay);
|
||||||
runTaskLater(task, delay);
|
|
||||||
} else {
|
|
||||||
Bukkit.getScheduler().runTaskLater(authMe, task, delay); // We must do this to keep compatibility
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,19 +94,11 @@ 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 (isFolia) {
|
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 (isFolia) {
|
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) {
|
||||||
@ -124,7 +110,7 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @param task the task to be run
|
* @param task the task to be run
|
||||||
*/
|
*/
|
||||||
public void runTaskIfFolia(Runnable task) {
|
public void runTaskIfFolia(Runnable task) {
|
||||||
if (isFolia) {
|
if (IS_FOLIA) {
|
||||||
runTask(task);
|
runTask(task);
|
||||||
} else {
|
} else {
|
||||||
task.run();
|
task.run();
|
||||||
@ -136,7 +122,7 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @param task the task to be run
|
* @param task the task to be run
|
||||||
*/
|
*/
|
||||||
public void runTaskIfFolia(Entity entity, Runnable task) {
|
public void runTaskIfFolia(Entity entity, Runnable task) {
|
||||||
if (isFolia) {
|
if (IS_FOLIA) {
|
||||||
runTask(entity, task);
|
runTask(entity, task);
|
||||||
} else {
|
} else {
|
||||||
task.run();
|
task.run();
|
||||||
@ -148,13 +134,15 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @param task the task to be run
|
* @param task the task to be run
|
||||||
*/
|
*/
|
||||||
public void runTaskIfFolia(Location location, Runnable task) {
|
public void runTaskIfFolia(Location location, Runnable task) {
|
||||||
if (isFolia) {
|
if (IS_FOLIA) {
|
||||||
runTask(location, task);
|
runTask(location, task);
|
||||||
} else {
|
} else {
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a task that will run after the specified number of server
|
* Returns a task that will run after the specified number of server
|
||||||
* ticks.
|
* ticks.
|
||||||
@ -169,10 +157,6 @@ 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.
|
||||||
@ -198,11 +182,7 @@ public class BukkitService implements SettingsDependent {
|
|||||||
* @throws IllegalArgumentException if task is null
|
* @throws IllegalArgumentException if task is null
|
||||||
*/
|
*/
|
||||||
public void runTaskAsynchronously(Runnable task) {
|
public void runTaskAsynchronously(Runnable task) {
|
||||||
if (isFolia) {
|
getScheduler().runTaskAsynchronously(task);
|
||||||
getScheduler().runTaskAsynchronously(task);
|
|
||||||
} else {
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(authMe, task);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -329,16 +309,6 @@ public class BukkitService implements SettingsDependent {
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a PotionEffect with blindness for the given duration in ticks.
|
|
||||||
*
|
|
||||||
* @param timeoutInTicks duration of the effect in ticks
|
|
||||||
* @return blindness potion effect
|
|
||||||
*/
|
|
||||||
public PotionEffect createBlindnessEffect(int timeoutInTicks) {
|
|
||||||
return new PotionEffect(PotionEffectType.BLINDNESS, timeoutInTicks, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the world with the given name.
|
* Gets the world with the given name.
|
||||||
*
|
*
|
||||||
@ -385,21 +355,6 @@ 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) {
|
|
||||||
if (player != null) {
|
|
||||||
player.sendPluginMessage(authMe, "authmevelocity:main", bytes);
|
|
||||||
} else {
|
|
||||||
Bukkit.getServer().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.
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class GeoIpService {
|
|||||||
private volatile boolean downloading;
|
private volatile boolean downloading;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GeoIpService(@DataFolder File dataFolder) {
|
GeoIpService(@DataFolder File dataFolder){
|
||||||
this.dataFile = dataFolder.toPath().resolve(DATABASE_FILE);
|
this.dataFile = dataFolder.toPath().resolve(DATABASE_FILE);
|
||||||
|
|
||||||
// Fires download of recent data or the initialization of the look up service
|
// Fires download of recent data or the initialization of the look up service
|
||||||
|
|||||||
@ -6,8 +6,6 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
|||||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
import fr.xephi.authme.service.hook.papi.AuthMeExpansion;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -28,8 +26,6 @@ public class PluginHookService {
|
|||||||
private Essentials essentials;
|
private Essentials essentials;
|
||||||
private Plugin cmi;
|
private Plugin cmi;
|
||||||
private MultiverseCore multiverse;
|
private MultiverseCore multiverse;
|
||||||
private PlaceholderAPIPlugin placeholderApi;
|
|
||||||
private AuthMeExpansion authMeExpansion;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -42,7 +38,6 @@ public class PluginHookService {
|
|||||||
tryHookToEssentials();
|
tryHookToEssentials();
|
||||||
tryHookToCmi();
|
tryHookToCmi();
|
||||||
tryHookToMultiverse();
|
tryHookToMultiverse();
|
||||||
tryHookToPlaceholderApi();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,20 +133,6 @@ public class PluginHookService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to create a hook into PlaceholderAPI.
|
|
||||||
*/
|
|
||||||
public void tryHookToPlaceholderApi() {
|
|
||||||
try {
|
|
||||||
placeholderApi = getPlugin(pluginManager, "PlaceholderAPI", PlaceholderAPIPlugin.class);
|
|
||||||
authMeExpansion = new AuthMeExpansion();
|
|
||||||
authMeExpansion.register();
|
|
||||||
} catch (Exception | NoClassDefFoundError ignored) {
|
|
||||||
placeholderApi = null;
|
|
||||||
authMeExpansion = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to create a hook into CMI.
|
* Attempts to create a hook into CMI.
|
||||||
*/
|
*/
|
||||||
@ -199,16 +180,6 @@ public class PluginHookService {
|
|||||||
multiverse = null;
|
multiverse = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unhooks from PlaceholderAPI.
|
|
||||||
*/
|
|
||||||
public void unhookPlaceholderApi() {
|
|
||||||
if (placeholderApi != null) {
|
|
||||||
authMeExpansion.unregister();
|
|
||||||
placeholderApi = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------
|
// ------
|
||||||
// Helpers
|
// Helpers
|
||||||
// ------
|
// ------
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.SpawnLoader;
|
import fr.xephi.authme.settings.SpawnLoader;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.util.TeleportUtils;
|
import fr.xephi.authme.util.TeleportUtils;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -143,9 +144,7 @@ public class TeleportationService implements Reloadable {
|
|||||||
} else if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)) {
|
} else if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)) {
|
||||||
if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
|
||||||
Location location = buildLocationFromAuth(player, auth);
|
Location location = buildLocationFromAuth(player, auth);
|
||||||
Location playerLoc = player.getLocation();
|
if (location.equals(player.getLocation())) return;
|
||||||
if (location.getX() == playerLoc.getX() && location.getY() == playerLoc.getY() && location.getZ() == playerLoc.getZ()
|
|
||||||
&& location.getWorld() == playerLoc.getWorld()) return;
|
|
||||||
logger.debug("Teleporting `{0}` after login, based on the player auth", player.getName());
|
logger.debug("Teleporting `{0}` after login, based on the player auth", player.getName());
|
||||||
teleportBackFromSpawn(player, location);
|
teleportBackFromSpawn(player, location);
|
||||||
} else if (limbo != null && limbo.getLocation() != null) {
|
} else if (limbo != null && limbo.getLocation() != null) {
|
||||||
@ -188,8 +187,10 @@ public class TeleportationService implements Reloadable {
|
|||||||
private void performTeleportation(final Player player, final AbstractTeleportEvent event) {
|
private void performTeleportation(final Player player, final AbstractTeleportEvent event) {
|
||||||
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
|
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
|
||||||
bukkitService.callEvent(event);
|
bukkitService.callEvent(event);
|
||||||
if (player.isOnline() && isEventValid(event)) {
|
if (player.isOnline() && isEventValid(event) && settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
|
||||||
TeleportUtils.teleport(player, event.getTo());
|
TeleportUtils.teleport(player, event.getTo());
|
||||||
|
} else if (player.isOnline() && isEventValid(event)) {
|
||||||
|
player.teleport(event.getTo());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -272,9 +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("Error occurred while checking password online, check your connection.\nWhen this error shows, the player's password won't be check");
|
logger.warning("验证密码时出现错误,这可能是由于网络问题,如果无法解决,请关闭HaveIBeenPwned检查");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
package fr.xephi.authme.service.hook.papi;
|
|
||||||
|
|
||||||
import fr.xephi.authme.AuthMe;
|
|
||||||
import fr.xephi.authme.api.v3.AuthMeApi;
|
|
||||||
import fr.xephi.authme.settings.Settings;
|
|
||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AuthMe PlaceholderAPI expansion class.
|
|
||||||
* @author Kobe 8
|
|
||||||
*/
|
|
||||||
public class AuthMeExpansion extends PlaceholderExpansion {
|
|
||||||
private final Settings settings = AuthMe.settings;
|
|
||||||
@Override
|
|
||||||
public @NotNull String getIdentifier() {
|
|
||||||
return "authme";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getAuthor() {
|
|
||||||
return "HaHaWTH";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getVersion() {
|
|
||||||
return AuthMe.getPluginVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean persist() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onRequest(OfflinePlayer player, @NotNull String params) {
|
|
||||||
if (!settings.getProperty(HooksSettings.PLACEHOLDER_API)) return null;
|
|
||||||
AuthMeApi authMeApi = AuthMeApi.getInstance();
|
|
||||||
if (authMeApi == null) return null;
|
|
||||||
if (params.equalsIgnoreCase("version")) {
|
|
||||||
return getVersion();
|
|
||||||
}
|
|
||||||
if (params.equalsIgnoreCase("is_registered")) {
|
|
||||||
if (player != null) {
|
|
||||||
Player onlinePlayer = player.getPlayer();
|
|
||||||
if (onlinePlayer != null) {
|
|
||||||
return String.valueOf(authMeApi.isRegistered(onlinePlayer.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (params.equalsIgnoreCase("is_authenticated")) {
|
|
||||||
if (player != null) {
|
|
||||||
Player onlinePlayer = player.getPlayer();
|
|
||||||
if (onlinePlayer != null) {
|
|
||||||
return String.valueOf(authMeApi.isAuthenticated(onlinePlayer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (params.equalsIgnoreCase("last_login_time")) {
|
|
||||||
if (player != null) {
|
|
||||||
Player onlinePlayer = player.getPlayer();
|
|
||||||
if (onlinePlayer != null) {
|
|
||||||
return authMeApi.getLastLoginTime(onlinePlayer.getName()).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package fr.xephi.authme.service.velocity;
|
|
||||||
|
|
||||||
public enum VMessageType {
|
|
||||||
LOGIN, REGISTER, LOGOUT, FORCE_UNREGISTER, UNREGISTER
|
|
||||||
}
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
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.VELOCITY)) {
|
&& !settings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||||
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!");
|
||||||
|
|||||||
@ -129,9 +129,9 @@ public class CommandManager implements Reloadable {
|
|||||||
if (predicate.test(cmd)) {
|
if (predicate.test(cmd)) {
|
||||||
long delay = cmd.getDelay();
|
long delay = cmd.getDelay();
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
bukkitService.runTaskLater(player, () -> dispatchCommand(player, cmd), delay);
|
bukkitService.scheduleSyncDelayedTask(() -> dispatchCommand(player, cmd), delay);
|
||||||
} else {
|
} else {
|
||||||
bukkitService.runTaskIfFolia(player, () -> dispatchCommand(player, cmd));
|
dispatchCommand(player, cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,19 @@ 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,10 +19,6 @@ 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");
|
||||||
@ -31,17 +27,7 @@ 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({"Replacement of Mysql's useSsl (for MariaDB only).",
|
@Comment("Connect to MySQL database over SSL")
|
||||||
"- 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);
|
||||||
|
|
||||||
@ -49,13 +35,12 @@ public final class DatabaseSettings implements SettingsHolder {
|
|||||||
"We would not recommend to set this option to false.",
|
"We would not recommend to set this option to false.",
|
||||||
"Set this option to false at your own risk if and only if you know what you're doing"})
|
"Set this option to false at your own risk if and only if you know what you're doing"})
|
||||||
public static final Property<Boolean> MYSQL_CHECK_SERVER_CERTIFICATE =
|
public static final Property<Boolean> MYSQL_CHECK_SERVER_CERTIFICATE =
|
||||||
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 );
|
||||||
|
|
||||||
@Comment("Username to connect to the MySQL database")
|
@Comment("Username to connect to the MySQL database")
|
||||||
public static final Property<String> MYSQL_USERNAME =
|
public static final Property<String> MYSQL_USERNAME =
|
||||||
|
|||||||
@ -15,33 +15,16 @@ public final class HooksSettings implements SettingsHolder {
|
|||||||
public static final Property<Boolean> MULTIVERSE =
|
public static final Property<Boolean> MULTIVERSE =
|
||||||
newProperty("Hooks.multiverse", true);
|
newProperty("Hooks.multiverse", true);
|
||||||
|
|
||||||
@Comment("Do we need to hook with PlaceholderAPI for AuthMe placeholders?")
|
|
||||||
public static final Property<Boolean> PLACEHOLDER_API =
|
|
||||||
newProperty("Hooks.placeholderapi", false);
|
|
||||||
|
|
||||||
@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({"How many ticks should we wait before sending login info to proxy?",
|
@Comment({"Allow FloodGatePlayer Join Without checkIsValidName()",
|
||||||
"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 =
|
||||||
|
|||||||
@ -5,32 +5,16 @@ import ch.jalu.configme.SettingsHolder;
|
|||||||
import ch.jalu.configme.properties.Property;
|
import ch.jalu.configme.properties.Property;
|
||||||
import fr.xephi.authme.output.LogLevel;
|
import fr.xephi.authme.output.LogLevel;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty;
|
|
||||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||||
|
|
||||||
public final class PluginSettings implements SettingsHolder {
|
public final class PluginSettings implements SettingsHolder {
|
||||||
|
|
||||||
@Comment({
|
@Comment({
|
||||||
"Send i18n messages to player based on their client settings, this option will override `settings.messagesLanguage`",
|
"Should we execute /help command when unregistered players press Shift+F?",
|
||||||
"(Requires ProtocolLib)",
|
"This keeps compatibility with some menu plugins",
|
||||||
"This will not affect language of AuthMe help command."
|
"If you are using TrMenu, don't enable this because TrMenu already implemented this."
|
||||||
})
|
})
|
||||||
public static final Property<Boolean> I18N_MESSAGES =
|
public static final Property<Boolean> MENU_UNREGISTER_COMPATIBILITY =
|
||||||
newProperty("3rdPartyFeature.features.i18nMessages.enabled", false);
|
newProperty("3rdPartyFeature.compatibility.menuPlugins", false);
|
||||||
|
|
||||||
@Comment({"Redirect locale code to certain AuthMe language code as you want",
|
|
||||||
"Minecraft locale list: https://minecraft.wiki/w/Language",
|
|
||||||
"AuthMe language code: https://github.com/HaHaWTH/AuthMeReReloaded/blob/master/docs/translations.md",
|
|
||||||
"For example, if you want to show Russian messages to player using language Tatar(tt_ru),",
|
|
||||||
"and show Chinese Simplified messages to player using language Classical Chinese(lzh), then:",
|
|
||||||
"locale-code-redirect:",
|
|
||||||
"- 'tt_ru:ru'",
|
|
||||||
"- 'lzh:zhcn'"})
|
|
||||||
public static final Property<Set<String>> I18N_CODE_REDIRECT =
|
|
||||||
newLowercaseStringSetProperty("3rdPartyFeature.features.i18nMessages.locale-code-redirect",
|
|
||||||
"tt_ru:ru", "lzh:zhcn");
|
|
||||||
|
|
||||||
@Comment({
|
@Comment({
|
||||||
"Do you want to enable the session feature?",
|
"Do you want to enable the session feature?",
|
||||||
@ -52,8 +36,7 @@ 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");
|
||||||
|
|||||||
@ -58,7 +58,7 @@ public final class ProtectionSettings implements SettingsHolder {
|
|||||||
|
|
||||||
@Comment("Kicks the player that issued a command before the defined time after the join process")
|
@Comment("Kicks the player that issued a command before the defined time after the join process")
|
||||||
public static final Property<Integer> QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS =
|
public static final Property<Integer> QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS =
|
||||||
newProperty("Protection.quickCommands.denyCommandsBeforeMilliseconds", 1000);
|
newProperty("Protection.quickCommands.denyCommandsBeforeMilliseconds", 3000);
|
||||||
|
|
||||||
private ProtectionSettings() {
|
private ProtectionSettings() {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,16 +46,6 @@ 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"})
|
||||||
|
|||||||
@ -173,7 +173,7 @@ public final class RestrictionSettings implements SettingsHolder {
|
|||||||
|
|
||||||
@Comment("Regex syntax for allowed chars in email.")
|
@Comment("Regex syntax for allowed chars in email.")
|
||||||
public static final Property<String> ALLOWED_EMAIL_REGEX =
|
public static final Property<String> ALLOWED_EMAIL_REGEX =
|
||||||
newProperty("settings.restrictions.allowedEmailCharacters", "^([a-zA-Z0-9_.+-]+)@([a-zA-Z0-9-]+)\\.([a-zA-Z]{2,})$");
|
newProperty("settings.restrictions.allowedEmailCharacters", "^[A-Za-z0-9_]{4,15}@(qq|outlook|163|gmail|icloud)\\.com$");
|
||||||
|
|
||||||
|
|
||||||
@Comment("Force survival gamemode when player joins?")
|
@Comment("Force survival gamemode when player joins?")
|
||||||
@ -205,10 +205,6 @@ public final class RestrictionSettings implements SettingsHolder {
|
|||||||
public static final Property<Set<String>> UNRESTRICTED_INVENTORIES =
|
public static final Property<Set<String>> UNRESTRICTED_INVENTORIES =
|
||||||
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedInventories");
|
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedInventories");
|
||||||
|
|
||||||
@Comment("Should we check unrestricted inventories strictly? (Original behavior)")
|
|
||||||
public static final Property<Boolean> STRICT_UNRESTRICTED_INVENTORIES_CHECK =
|
|
||||||
newProperty("settings.unrestrictions.StrictUnrestrictedInventoriesCheck", true);
|
|
||||||
|
|
||||||
|
|
||||||
private RestrictionSettings() {
|
private RestrictionSettings() {
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,10 @@ import ch.jalu.configme.properties.Property;
|
|||||||
import fr.xephi.authme.security.HashAlgorithm;
|
import fr.xephi.authme.security.HashAlgorithm;
|
||||||
import fr.xephi.authme.settings.EnumSetProperty;
|
import fr.xephi.authme.settings.EnumSetProperty;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
|
||||||
import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty;
|
import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty;
|
||||||
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
|
||||||
|
|
||||||
@ -19,6 +21,11 @@ public final class SecuritySettings implements SettingsHolder {
|
|||||||
public static final Property<Boolean> STOP_SERVER_ON_PROBLEM =
|
public static final Property<Boolean> STOP_SERVER_ON_PROBLEM =
|
||||||
newProperty("Security.SQLProblem.stopServer", false);
|
newProperty("Security.SQLProblem.stopServer", false);
|
||||||
|
|
||||||
|
@Comment({"Should send GUI captcha by country code whitelist?",
|
||||||
|
"If the country of the player is in this list, the captcha won't be sent."})
|
||||||
|
public static final Property<List<String>> GUI_CAPTCHA_COUNTRY_WHITELIST =
|
||||||
|
newListProperty("3rdPartyFeature.features.captcha.whiteList");
|
||||||
|
|
||||||
@Comment({"Should we let Bedrock players login automatically?",
|
@Comment({"Should we let Bedrock players login automatically?",
|
||||||
"(Requires hookFloodgate to be true & floodgate loaded)",
|
"(Requires hookFloodgate to be true & floodgate loaded)",
|
||||||
"(**THIS IS SAFE DO NOT WORRY**)"})
|
"(**THIS IS SAFE DO NOT WORRY**)"})
|
||||||
@ -41,6 +48,25 @@ public final class SecuritySettings implements SettingsHolder {
|
|||||||
public static final Property<Boolean> ADVANCED_SHULKER_FIX =
|
public static final Property<Boolean> ADVANCED_SHULKER_FIX =
|
||||||
newProperty("3rdPartyFeature.fixes.advancedShulkerFix", false);
|
newProperty("3rdPartyFeature.fixes.advancedShulkerFix", false);
|
||||||
|
|
||||||
|
@Comment({"Choose the best teleport method by server brand?",
|
||||||
|
"(Enable this if you are using Paper)"})
|
||||||
|
public static final Property<Boolean> SMART_ASYNC_TELEPORT =
|
||||||
|
newProperty("3rdPartyFeature.optimizes.smartAsyncTeleport", true);
|
||||||
|
|
||||||
|
@Comment("Send a GUI captcha to unregistered players?(Requires ProtocolLib)")
|
||||||
|
public static final Property<Boolean> GUI_CAPTCHA =
|
||||||
|
newProperty("3rdPartyFeature.features.captcha.guiCaptcha", false);
|
||||||
|
|
||||||
|
@Comment({"Should we kick the players when they don't finish the GUI captcha in seconds?",
|
||||||
|
"(less than or equals 0 is disabled)"})
|
||||||
|
public static final Property<Integer> GUI_CAPTCHA_TIMEOUT =
|
||||||
|
newProperty("3rdPartyFeature.features.captcha.timeOut", 0);
|
||||||
|
|
||||||
|
@Comment({"Should we ignore floodgate players when sending GUI captcha?",
|
||||||
|
"(Requires floodgate and hookFloodgate: true)"})
|
||||||
|
public static final Property<Boolean> GUI_CAPTCHA_BE_COMPATIBILITY =
|
||||||
|
newProperty("3rdPartyFeature.features.captcha.ignoreBedrock", false);
|
||||||
|
|
||||||
@Comment("Should we fix the location when players logged in the portal?")
|
@Comment("Should we fix the location when players logged in the portal?")
|
||||||
public static final Property<Boolean> LOGIN_LOC_FIX_SUB_PORTAL =
|
public static final Property<Boolean> LOGIN_LOC_FIX_SUB_PORTAL =
|
||||||
newProperty("3rdPartyFeature.fixes.loginLocationFix.fixPortalStuck", false);
|
newProperty("3rdPartyFeature.fixes.loginLocationFix.fixPortalStuck", false);
|
||||||
@ -62,11 +88,6 @@ public final class SecuritySettings implements SettingsHolder {
|
|||||||
public static final Property<Integer> HAVE_I_BEEN_PWNED_LIMIT =
|
public static final Property<Integer> HAVE_I_BEEN_PWNED_LIMIT =
|
||||||
newProperty("Security.account.haveIBeenPwned.limit", 0);
|
newProperty("Security.account.haveIBeenPwned.limit", 0);
|
||||||
|
|
||||||
@Comment({"Require email verification when changing password if email feature enabled.",
|
|
||||||
"Original behavior is true"})
|
|
||||||
public static final Property<Boolean> CHANGE_PASSWORD_EMAIL_VERIFICATION_REQUIRED =
|
|
||||||
newProperty("Security.account.emailVerification.required", true);
|
|
||||||
|
|
||||||
@Comment("Enable captcha when a player uses wrong password too many times")
|
@Comment("Enable captcha when a player uses wrong password too many times")
|
||||||
public static final Property<Boolean> ENABLE_LOGIN_FAILURE_CAPTCHA =
|
public static final Property<Boolean> ENABLE_LOGIN_FAILURE_CAPTCHA =
|
||||||
newProperty("Security.captcha.useCaptcha", false);
|
newProperty("Security.captcha.useCaptcha", false);
|
||||||
@ -106,7 +127,7 @@ public final class SecuritySettings implements SettingsHolder {
|
|||||||
@Comment({
|
@Comment({
|
||||||
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
|
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
|
||||||
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
|
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
|
||||||
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, NOCRYPT, CUSTOM (for developers only). See full list at",
|
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, CUSTOM (for developers only). See full list at",
|
||||||
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md",
|
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md",
|
||||||
"If you use ARGON2, check that you have the argon2 c library on your system"
|
"If you use ARGON2, check that you have the argon2 c library on your system"
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
package fr.xephi.authme.task;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
public class Updater {
|
|
||||||
private final String currentVersion;
|
|
||||||
private String latestVersion;
|
|
||||||
private static boolean isUpdateAvailable = false;
|
|
||||||
private static final String owner = "HaHaWTH";
|
|
||||||
private static final String repo = "AuthMeReReloaded";
|
|
||||||
private static final String UPDATE_URL = "https://api.github.com/repos/" + owner + "/" + repo + "/releases/latest";
|
|
||||||
|
|
||||||
public Updater(String currentVersion) {
|
|
||||||
this.currentVersion = currentVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if there is an update available
|
|
||||||
* Note: This method will perform a network request!
|
|
||||||
*
|
|
||||||
* @return true if there is an update available, false otherwise
|
|
||||||
*/
|
|
||||||
public boolean isUpdateAvailable() {
|
|
||||||
URI uri = URI.create(UPDATE_URL);
|
|
||||||
try {
|
|
||||||
URL url = uri.toURL();
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
||||||
conn.setConnectTimeout(10000);
|
|
||||||
conn.setReadTimeout(10000);
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
conn.setRequestProperty("Accept", "application/vnd.github+json");
|
|
||||||
try (InputStreamReader reader = new InputStreamReader(conn.getInputStream())) {
|
|
||||||
JsonObject jsonObject = new JsonParser().parse(reader).getAsJsonObject();
|
|
||||||
String latest = jsonObject.get("tag_name").getAsString();
|
|
||||||
latestVersion = latest;
|
|
||||||
isUpdateAvailable = !currentVersion.equals(latest);
|
|
||||||
reader.close();
|
|
||||||
return isUpdateAvailable;
|
|
||||||
}
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
this.latestVersion = null;
|
|
||||||
isUpdateAvailable = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLatestVersion() {
|
|
||||||
return latestVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCurrentVersion() {
|
|
||||||
return currentVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there is an update available, false otherwise
|
|
||||||
* Must be called after {@link Updater#isUpdateAvailable()}
|
|
||||||
*
|
|
||||||
* @return A boolean indicating whether there is an update available
|
|
||||||
*/
|
|
||||||
public static boolean hasUpdate() {
|
|
||||||
return isUpdateAvailable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,7 +10,6 @@ public final class PlayerUtils {
|
|||||||
// Utility class
|
// Utility class
|
||||||
private PlayerUtils() {
|
private PlayerUtils() {
|
||||||
}
|
}
|
||||||
private static final boolean isLeavesServer = Utils.isClassLoaded("top.leavesmc.leaves.LeavesConfig") || Utils.isClassLoaded("org.leavesmc.leaves.LeavesConfig");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IP of the given player.
|
* Returns the IP of the given player.
|
||||||
@ -29,11 +28,7 @@ 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 (isLeavesServer) {
|
return player.hasMetadata("NPC") || player.getAddress() == null;
|
||||||
return player.hasMetadata("NPC") || player.getAddress() == null;
|
|
||||||
} else {
|
|
||||||
return player.hasMetadata("NPC");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,24 +3,24 @@ package fr.xephi.authme.util;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.invoke.MethodType;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a utility class for handling async teleportation of players in game.
|
* This class is a utility class for handling async teleportation of players in game.
|
||||||
*/
|
*/
|
||||||
public class TeleportUtils {
|
public class TeleportUtils {
|
||||||
private static MethodHandle teleportAsyncMethodHandle;
|
private static Method teleportAsyncMethod;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {//Detect Paper class
|
||||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
Class<?> paperClass = Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||||
teleportAsyncMethodHandle = lookup.findVirtual(Player.class, "teleportAsync", MethodType.methodType(CompletableFuture.class, Location.class));
|
teleportAsyncMethod = Player.class.getMethod("teleportAsync", Location.class);
|
||||||
} catch (NoSuchMethodException | IllegalAccessException e) {
|
teleportAsyncMethod.setAccessible(true);
|
||||||
teleportAsyncMethodHandle = null;
|
// if detected,use teleportAsync()
|
||||||
// if not, set method handle to null
|
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||||
|
teleportAsyncMethod = null;
|
||||||
|
//if not, set method to null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,10 +31,10 @@ public class TeleportUtils {
|
|||||||
* @param location Where should the player be teleported
|
* @param location Where should the player be teleported
|
||||||
*/
|
*/
|
||||||
public static void teleport(Player player, Location location) {
|
public static void teleport(Player player, Location location) {
|
||||||
if (teleportAsyncMethodHandle != null) {
|
if (teleportAsyncMethod != null) {
|
||||||
try {
|
try {
|
||||||
teleportAsyncMethodHandle.invoke(player, location);
|
teleportAsyncMethod.invoke(player, location);
|
||||||
} catch (Throwable throwable) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
player.teleport(location);
|
player.teleport(location);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package fr.xephi.authme.util;
|
|||||||
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
@ -108,12 +107,4 @@ public final class Utils {
|
|||||||
public static boolean isEmailEmpty(String email) {
|
public static boolean isEmailEmpty(String email) {
|
||||||
return StringUtils.isBlank(email) || "your@email.com".equalsIgnoreCase(email);
|
return StringUtils.isBlank(email) || "your@email.com".equalsIgnoreCase(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String[] serverVersion = Bukkit.getServer().getBukkitVersion()
|
|
||||||
.substring(0, Bukkit.getServer().getBukkitVersion().indexOf("-"))
|
|
||||||
.split("\\.");
|
|
||||||
|
|
||||||
private final static int FIRST_VERSION = Integer.parseInt(serverVersion[0]);
|
|
||||||
public final static int MAJOR_VERSION = Integer.parseInt(serverVersion[1]);
|
|
||||||
public final static int MINOR_VERSION = serverVersion.length == 3 ? Integer.parseInt(serverVersion[2]) : 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,102 +0,0 @@
|
|||||||
package fr.xephi.authme.util.message;
|
|
||||||
|
|
||||||
import fr.xephi.authme.settings.Settings;
|
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
|
||||||
import fr.xephi.authme.util.Utils;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class I18NUtils {
|
|
||||||
|
|
||||||
private static Map<UUID, String> PLAYER_LOCALE = new ConcurrentHashMap<>();
|
|
||||||
private static final Map<String, String> LOCALE_MAP = new HashMap<>();
|
|
||||||
private static final List<String> LOCALE_LIST = Arrays.asList(
|
|
||||||
"en", "bg", "de", "eo", "es", "et", "eu", "fi", "fr", "gl", "hu", "id", "it", "ja", "ko", "lt", "nl", "pl",
|
|
||||||
"pt", "ro", "ru", "sk", "sr", "tr", "uk"
|
|
||||||
);
|
|
||||||
|
|
||||||
static {
|
|
||||||
LOCALE_MAP.put("pt_br", "br");
|
|
||||||
LOCALE_MAP.put("cs_cz", "cz");
|
|
||||||
LOCALE_MAP.put("nds_de", "de");
|
|
||||||
LOCALE_MAP.put("sxu", "de");
|
|
||||||
LOCALE_MAP.put("swg", "de");
|
|
||||||
LOCALE_MAP.put("rpr", "ru");
|
|
||||||
LOCALE_MAP.put("sl_si", "si");
|
|
||||||
LOCALE_MAP.put("vi_vn", "vn");
|
|
||||||
LOCALE_MAP.put("lzh", "zhcn");
|
|
||||||
LOCALE_MAP.put("zh_cn", "zhcn");
|
|
||||||
LOCALE_MAP.put("zh_hk", "zhhk");
|
|
||||||
LOCALE_MAP.put("zh_tw", "zhtw");
|
|
||||||
//LOCALE_MAP.put("zhmc", "zhmc");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the locale that player uses.
|
|
||||||
*
|
|
||||||
* @param player The player
|
|
||||||
*/
|
|
||||||
public static String getLocale(Player player) {
|
|
||||||
if (Utils.MAJOR_VERSION > 15) {
|
|
||||||
return player.getLocale().toLowerCase();
|
|
||||||
} else if (PLAYER_LOCALE.containsKey(player.getUniqueId())) {
|
|
||||||
return PLAYER_LOCALE.get(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addLocale(UUID uuid, String locale) {
|
|
||||||
if (PLAYER_LOCALE == null) {
|
|
||||||
PLAYER_LOCALE = new ConcurrentHashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
PLAYER_LOCALE.put(uuid, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeLocale(UUID uuid) {
|
|
||||||
PLAYER_LOCALE.remove(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the AuthMe messages file language code, by given locale and settings.
|
|
||||||
* Dreeam - Hard mapping, based on mc1.20.6, 5/29/2024
|
|
||||||
*
|
|
||||||
* @param locale The locale that player client setting uses.
|
|
||||||
* @param settings The AuthMe settings, for default/fallback language usage.
|
|
||||||
*/
|
|
||||||
public static String localeToCode(String locale, Settings settings) {
|
|
||||||
// Certain locale code to AuthMe language code redirect
|
|
||||||
if (!settings.getProperty(PluginSettings.I18N_CODE_REDIRECT).isEmpty()) {
|
|
||||||
for (String raw : settings.getProperty(PluginSettings.I18N_CODE_REDIRECT)) {
|
|
||||||
String[] split = raw.split(":");
|
|
||||||
|
|
||||||
if (split.length == 2 && locale.equalsIgnoreCase(split[0])) {
|
|
||||||
return split[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match certain locale code
|
|
||||||
if (LOCALE_MAP.containsKey(locale)) {
|
|
||||||
return LOCALE_MAP.get(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (locale.contains("_")) {
|
|
||||||
locale = locale.substring(0, locale.indexOf("_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match locale code with "_"
|
|
||||||
if (LOCALE_LIST.contains(locale)) {
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
return settings.getProperty(PluginSettings.MESSAGES_LANGUAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package fr.xephi.authme.util.message;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
|
|
||||||
public class MiniMessageUtils {
|
|
||||||
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a MiniMessage string into a legacy string.
|
|
||||||
*
|
|
||||||
* @param message The message to parse.
|
|
||||||
* @return The parsed message.
|
|
||||||
*/
|
|
||||||
public static String parseMiniMessageToLegacy(String message) {
|
|
||||||
Component component = miniMessage.deserialize(message);
|
|
||||||
return LegacyComponentSerializer.legacyAmpersand().serialize(component);
|
|
||||||
}
|
|
||||||
private MiniMessageUtils() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@ -104,7 +104,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<p style="color:#b0adc5;">© 2024 HomoCraft. All rights reserved.</p>
|
<p style="color:#b0adc5;">© 2024 HomoCraft. All rights reserved.</p>
|
||||||
<a href="1919810.com" target="_blank"
|
<a href="1919810.com" target="_blank"
|
||||||
style="text-decoration: none; font-size: 16px">example.com</a>
|
style="text-decoration: none; font-size: 16px">wdsj.in</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@ -9,7 +9,7 @@ registration:
|
|||||||
name_taken: '&cПотребителското име е заетo!'
|
name_taken: '&cПотребителското име е заетo!'
|
||||||
register_request: '&3Моля регистрирайте се с: /register парола парола.'
|
register_request: '&3Моля регистрирайте се с: /register парола парола.'
|
||||||
command_usage: '&cКоманда: /register парола парола'
|
command_usage: '&cКоманда: /register парола парола'
|
||||||
reg_only: '&4Само регистрирани потребители могат да влизат в сървъра! Моля посетете https://example.com, за да се регистрирате!'
|
reg_only: '&4Само регистрирани потребители могат да влизат в сървъра! Моля посетете http://example.com, за да се регистрирате!'
|
||||||
success: '&2Успешна регистрация!'
|
success: '&2Успешна регистрация!'
|
||||||
kicked_admin_registered: 'Вие бяхте регистриран от администратора, моля да влезете отново!'
|
kicked_admin_registered: 'Вие бяхте регистриран от администратора, моля да влезете отново!'
|
||||||
|
|
||||||
@ -20,7 +20,6 @@ password:
|
|||||||
unsafe_password: '&cИзбраната парола не е безопасна, моля изберете друга парола.'
|
unsafe_password: '&cИзбраната парола не е безопасна, моля изберете друга парола.'
|
||||||
forbidden_characters: '&4Паролата съдържа непозволени символи. Позволени символи: %valid_chars'
|
forbidden_characters: '&4Паролата съдържа непозволени символи. Позволени символи: %valid_chars'
|
||||||
wrong_length: '&cПаролата е твърде къса или прекалено дълга! Моля опитайте с друга парола.'
|
wrong_length: '&cПаролата е твърде къса или прекалено дълга! Моля опитайте с друга парола.'
|
||||||
pwned_password: '&cИзбраната парола не е сигурна. Тя е използвана %pwned_count пъти вече! Моля, използвайте силна парола...'
|
|
||||||
|
|
||||||
# Login
|
# Login
|
||||||
login:
|
login:
|
||||||
@ -41,7 +40,7 @@ error:
|
|||||||
max_registration: '&cВие сте достигнали максималният брой регистрации (%reg_count/%max_acc %reg_names)!'
|
max_registration: '&cВие сте достигнали максималният брой регистрации (%reg_count/%max_acc %reg_names)!'
|
||||||
logged_in: '&cВече сте влезли!'
|
logged_in: '&cВече сте влезли!'
|
||||||
kick_for_vip: '&3VIP потребител влезе докато сървъра беше пълен, вие бяхте изгонен!'
|
kick_for_vip: '&3VIP потребител влезе докато сървъра беше пълен, вие бяхте изгонен!'
|
||||||
kick_unresolved_hostname: '&cВъзникна грешка: неразрешено име на играч!'
|
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||||
tempban_max_logins: '&cВие бяхте баннат временно, понеже сте си сгрешили паролата прекалено много пъти.'
|
tempban_max_logins: '&cВие бяхте баннат временно, понеже сте си сгрешили паролата прекалено много пъти.'
|
||||||
|
|
||||||
# AntiBot
|
# AntiBot
|
||||||
@ -58,7 +57,6 @@ unregister:
|
|||||||
# Other messages
|
# Other messages
|
||||||
misc:
|
misc:
|
||||||
account_not_activated: '&cВашият акаунт все още не е актириван, моля провете своят email адрес!'
|
account_not_activated: '&cВашият акаунт все още не е актириван, моля провете своят email адрес!'
|
||||||
not_activated: '&cАкаунтът не е активиран, моля регистрирайте се и го активирайте преди да опитате отново.'
|
|
||||||
password_changed: '&2Паротала е променена успешно!'
|
password_changed: '&2Паротала е променена успешно!'
|
||||||
logout: '&2Излязохте успешно!'
|
logout: '&2Излязохте успешно!'
|
||||||
reload: '&2Конфигурацията и база данните бяха презаредени правилно!'
|
reload: '&2Конфигурацията и база данните бяха презаредени правилно!'
|
||||||
@ -157,17 +155,3 @@ two_factor:
|
|||||||
not_enabled_error: 'Защитата със секретен код не е включена за Вашият акаунт. Моля изпълнете команда /2fa add'
|
not_enabled_error: 'Защитата със секретен код не е включена за Вашият акаунт. Моля изпълнете команда /2fa add'
|
||||||
removed_success: 'Успешно изключихте защитата със секретен код от Вашият акаунт!'
|
removed_success: 'Успешно изключихте защитата със секретен код от Вашият акаунт!'
|
||||||
invalid_code: 'Невалиден код!'
|
invalid_code: 'Невалиден код!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
|
||||||
bedrock_auto_login:
|
|
||||||
success: '&aУспешно автоматично влизане за Bedrock!'
|
|
||||||
|
|
||||||
# 3rd party features: Login Location Fix
|
|
||||||
login_location_fix:
|
|
||||||
fix_portal: '&aЗаседнали сте в портал по време на влизане.'
|
|
||||||
fix_underground: '&aЗаседнали сте под земята по време на влизане.'
|
|
||||||
cannot_fix_underground: '&aЗаседнали сте под земята по време на влизане, но не можем да го поправим.'
|
|
||||||
|
|
||||||
# 3rd party features: Double Login Fix
|
|
||||||
double_login_fix:
|
|
||||||
fix_message: '&cБяхте изключени поради двойно влизане.'
|
|
||||||
|
|||||||
@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
# Registro
|
# Registro
|
||||||
registration:
|
registration:
|
||||||
disabled: '&cRegistrar-se está desativado neste servidor!'
|
|
||||||
name_taken: '&cVocê já registrou este nome de usuário!'
|
|
||||||
register_request: '&3Por favor, registre-se com o comando "/register <senha> <senha>"'
|
register_request: '&3Por favor, registre-se com o comando "/register <senha> <senha>"'
|
||||||
command_usage: '&cUse: /register <senha> <senha>'
|
command_usage: '&cUse: /register <senha> <senha>'
|
||||||
reg_only: '&4Somente usuários registrados podem entrar no servidor! Por favor visite www.seusite.com para se registrar!'
|
reg_only: '&4Somente usuários registrados podem entrar no servidor! Por favor visite www.seusite.com para se registrar!'
|
||||||
success: '&2Registrado com sucesso!'
|
success: '&2Registrado com sucesso!'
|
||||||
kicked_admin_registered: 'Um administrador registrou você. Por favor, faça login novamente'
|
kicked_admin_registered: 'Um administrador registrou você. Por favor, faça login novamente'
|
||||||
|
disabled: '&cRegistrar-se está desativado neste servidor!'
|
||||||
|
name_taken: '&cVocê já registrou este nome de usuário!'
|
||||||
|
|
||||||
# Erros de senha ao registrar-se
|
# Erros de senha ao registrar-se
|
||||||
password:
|
password:
|
||||||
@ -23,7 +23,6 @@ password:
|
|||||||
unsafe_password: '&cA senha escolhida não é segura. Por favor, escolha outra senha...'
|
unsafe_password: '&cA senha escolhida não é segura. Por favor, escolha outra senha...'
|
||||||
forbidden_characters: '&Sua senha contém caracteres inválidos. Caracteres permitidos: %valid_chars'
|
forbidden_characters: '&Sua senha contém caracteres inválidos. Caracteres permitidos: %valid_chars'
|
||||||
wrong_length: '&cSua senha é muito curta ou muito longa! Por favor, escolha outra senha...'
|
wrong_length: '&cSua senha é muito curta ou muito longa! Por favor, escolha outra senha...'
|
||||||
pwned_password: '&cSua senha escolhida não é segura. Ela foi usada %pwned_count vezes já! Por favor, use uma senha forte...'
|
|
||||||
|
|
||||||
# Login
|
# Login
|
||||||
login:
|
login:
|
||||||
@ -35,17 +34,17 @@ login:
|
|||||||
|
|
||||||
# Erros
|
# Erros
|
||||||
error:
|
error:
|
||||||
|
unregistered_user: '&cEste usuário não está registrado!'
|
||||||
denied_command: '&cPara utilizar este comando é necessário estar logado!'
|
denied_command: '&cPara utilizar este comando é necessário estar logado!'
|
||||||
denied_chat: '&cPara utilizar o chat é necessário estar logado!'
|
denied_chat: '&cPara utilizar o chat é necessário estar logado!'
|
||||||
unregistered_user: '&cEste usuário não está registrado!'
|
|
||||||
not_logged_in: '&cVocê não está logado!'
|
not_logged_in: '&cVocê não está logado!'
|
||||||
|
tempban_max_logins: '&cVocê foi temporariamente banido por tentar fazer login muitas vezes.'
|
||||||
|
max_registration: '&cVocê excedeu o número máximo de registros (%reg_count/%max_acc %reg_names) para o seu IP!'
|
||||||
no_permission: '&4Você não tem permissão para executar esta ação!'
|
no_permission: '&4Você não tem permissão para executar esta ação!'
|
||||||
unexpected_error: '&4Ocorreu um erro inesperado. Por favor contate um administrador!'
|
unexpected_error: '&4Ocorreu um erro inesperado. Por favor contate um administrador!'
|
||||||
max_registration: '&cVocê excedeu o número máximo de registros (%reg_count/%max_acc %reg_names) para o seu IP!'
|
|
||||||
logged_in: '&cVocê já está logado!'
|
|
||||||
kick_for_vip: '&3Um jogador VIP juntou-se ao servidor enquanto ele estava cheio!'
|
kick_for_vip: '&3Um jogador VIP juntou-se ao servidor enquanto ele estava cheio!'
|
||||||
|
logged_in: '&cVocê já está logado!'
|
||||||
kick_unresolved_hostname: '&cErro: hostname do jogador não resolvido!'
|
kick_unresolved_hostname: '&cErro: hostname do jogador não resolvido!'
|
||||||
tempban_max_logins: '&cVocê foi temporariamente banido por tentar fazer login muitas vezes.'
|
|
||||||
|
|
||||||
# AntiBot
|
# AntiBot
|
||||||
antibot:
|
antibot:
|
||||||
@ -60,14 +59,13 @@ unregister:
|
|||||||
|
|
||||||
# Outras mensagens
|
# Outras mensagens
|
||||||
misc:
|
misc:
|
||||||
|
accounts_owned_self: 'Você tem %count contas:'
|
||||||
|
accounts_owned_other: 'O jogador %name tem %count contas:'
|
||||||
account_not_activated: '&cA sua conta ainda não está ativada. Por favor, verifique seus e-mails!'
|
account_not_activated: '&cA sua conta ainda não está ativada. Por favor, verifique seus e-mails!'
|
||||||
not_activated: '&cConta não ativada, por favor registre e ative antes de tentar novamente.'
|
|
||||||
password_changed: '&2Senha alterada com sucesso!'
|
password_changed: '&2Senha alterada com sucesso!'
|
||||||
logout: '&2Desconectado com sucesso!'
|
logout: '&2Desconectado com sucesso!'
|
||||||
reload: '&2A configuração e o banco de dados foram recarregados corretamente!'
|
reload: '&2A configuração e o banco de dados foram recarregados corretamente!'
|
||||||
usage_change_password: '&cUse: /changepassword <senhaVelha> <senhaNova>'
|
usage_change_password: '&cUse: /changepassword <senhaVelha> <senhaNova>'
|
||||||
accounts_owned_self: 'Você tem %count contas:'
|
|
||||||
accounts_owned_other: 'O jogador %name tem %count contas:'
|
|
||||||
|
|
||||||
# Mensagens de sessão
|
# Mensagens de sessão
|
||||||
session:
|
session:
|
||||||
@ -76,36 +74,36 @@ session:
|
|||||||
|
|
||||||
# Mensagens de erro ao entrar
|
# Mensagens de erro ao entrar
|
||||||
on_join_validation:
|
on_join_validation:
|
||||||
same_ip_online: 'Um jogador com o mesmo IP já está no servidor!'
|
|
||||||
same_nick_online: '&4Alguém com o mesmo nome de usuário já está jogando no servidor!'
|
|
||||||
name_length: '&4Seu nome de usuário ou é muito curto ou é muito longo!'
|
name_length: '&4Seu nome de usuário ou é muito curto ou é muito longo!'
|
||||||
characters_in_name: '&4Seu nome de usuário contém caracteres inválidos. Caracteres permitidos: %valid_chars'
|
characters_in_name: '&4Seu nome de usuário contém caracteres inválidos. Caracteres permitidos: %valid_chars'
|
||||||
kick_full_server: '&4O servidor está cheio, tente novamente mais tarde!'
|
|
||||||
country_banned: '&4O seu país está banido deste servidor!'
|
country_banned: '&4O seu país está banido deste servidor!'
|
||||||
not_owner_error: 'Você não é o proprietário da conta. Por favor, escolha outro nome!'
|
not_owner_error: 'Você não é o proprietário da conta. Por favor, escolha outro nome!'
|
||||||
|
kick_full_server: '&4O servidor está cheio, tente novamente mais tarde!'
|
||||||
|
same_nick_online: '&4Alguém com o mesmo nome de usuário já está jogando no servidor!'
|
||||||
invalid_name_case: 'Você deve entrar usando o nome de usuário %valid, não %invalid.'
|
invalid_name_case: 'Você deve entrar usando o nome de usuário %valid, não %invalid.'
|
||||||
|
same_ip_online: 'Um jogador com o mesmo IP já está no servidor!'
|
||||||
quick_command: 'Você usou o comando muito rápido! Por favor, entre no servidor e aguarde antes de usar um comando novamente.'
|
quick_command: 'Você usou o comando muito rápido! Por favor, entre no servidor e aguarde antes de usar um comando novamente.'
|
||||||
|
|
||||||
# E-mail
|
# E-mail
|
||||||
email:
|
email:
|
||||||
add_email_request: '&3Por favor, adicione seu e-mail para a sua conta com o comando "/email add <seuEmail> <seuEmail>"'
|
|
||||||
usage_email_add: '&cUse: /email add <email> <email>'
|
usage_email_add: '&cUse: /email add <email> <email>'
|
||||||
usage_email_change: '&cUse: /email change <emailAntigo> <novoEmail>'
|
usage_email_change: '&cUse: /email change <emailAntigo> <novoEmail>'
|
||||||
new_email_invalid: '&cE-mail novo inválido, tente novamente!'
|
new_email_invalid: '&cE-mail novo inválido, tente novamente!'
|
||||||
old_email_invalid: '&cE-mail antigo inválido, tente novamente!'
|
old_email_invalid: '&cE-mail antigo inválido, tente novamente!'
|
||||||
invalid: '&E-mail inválido, tente novamente!'
|
invalid: '&E-mail inválido, tente novamente!'
|
||||||
added: '&2E-mail adicionado com sucesso!'
|
added: '&2E-mail adicionado com sucesso!'
|
||||||
add_not_allowed: '&cAdicionar um e-mail não é permitido.'
|
|
||||||
request_confirmation: '&cPor favor, confirme o seu endereço de e-mail!'
|
request_confirmation: '&cPor favor, confirme o seu endereço de e-mail!'
|
||||||
changed: '&2E-mail alterado com sucesso!'
|
changed: '&2E-mail alterado com sucesso!'
|
||||||
change_not_allowed: '&cAlterar o e-mail não é permitido.'
|
|
||||||
email_show: '&2O seu endereço de e-mail atual é: &f%email'
|
email_show: '&2O seu endereço de e-mail atual é: &f%email'
|
||||||
no_email_for_account: '&2Você atualmente não têm endereço de e-mail associado a esta conta.'
|
|
||||||
already_used: '&4O endereço de e-mail já está sendo usado'
|
|
||||||
incomplete_settings: 'Erro: Nem todas as configurações necessárias estão definidas para o envio de e-mails. Entre em contato com um administrador.'
|
incomplete_settings: 'Erro: Nem todas as configurações necessárias estão definidas para o envio de e-mails. Entre em contato com um administrador.'
|
||||||
|
already_used: '&4O endereço de e-mail já está sendo usado'
|
||||||
send_failure: '&cO e-mail não pôde ser enviado, reporte isso a um administrador!'
|
send_failure: '&cO e-mail não pôde ser enviado, reporte isso a um administrador!'
|
||||||
|
no_email_for_account: '&2Você atualmente não têm endereço de e-mail associado a esta conta.'
|
||||||
|
add_email_request: '&3Por favor, adicione seu e-mail para a sua conta com o comando "/email add <seuEmail> <seuEmail>"'
|
||||||
change_password_expired: 'Você não pode mais usar esse comando de recuperação de senha!'
|
change_password_expired: 'Você não pode mais usar esse comando de recuperação de senha!'
|
||||||
email_cooldown_error: '&cUm e-mail já foi enviado, espere %time antes de enviar novamente!'
|
email_cooldown_error: '&cUm e-mail já foi enviado, espere %time antes de enviar novamente!'
|
||||||
|
add_not_allowed: '&cAdicionar um e-mail não é permitido.'
|
||||||
|
change_not_allowed: '&cAlterar o e-mail não é permitido.'
|
||||||
|
|
||||||
# Recuperação de senha por e-mail
|
# Recuperação de senha por e-mail
|
||||||
recovery:
|
recovery:
|
||||||
@ -137,17 +135,6 @@ verification:
|
|||||||
code_expired: '&3O seu código expirou! Execute outro comando sensível para gerar um outro código.'
|
code_expired: '&3O seu código expirou! Execute outro comando sensível para gerar um outro código.'
|
||||||
email_needed: '&3Para verificar sua identidade, você precisa vincular um e-mail à sua conta!'
|
email_needed: '&3Para verificar sua identidade, você precisa vincular um e-mail à sua conta!'
|
||||||
|
|
||||||
# Unidades de tempo
|
|
||||||
time:
|
|
||||||
second: 'segundo'
|
|
||||||
seconds: 'segundos'
|
|
||||||
minute: 'minuto'
|
|
||||||
minutes: 'minutos'
|
|
||||||
hour: 'hora'
|
|
||||||
hours: 'horas'
|
|
||||||
day: 'dia'
|
|
||||||
days: 'dias'
|
|
||||||
|
|
||||||
# Verificação em duas etapas
|
# Verificação em duas etapas
|
||||||
two_factor:
|
two_factor:
|
||||||
code_created: '&2O seu código secreto é %code. Você pode verificá-lo aqui %url'
|
code_created: '&2O seu código secreto é %code. Você pode verificá-lo aqui %url'
|
||||||
@ -161,16 +148,13 @@ two_factor:
|
|||||||
removed_success: 'Verificação em duas etapas desativada com sucesso!'
|
removed_success: 'Verificação em duas etapas desativada com sucesso!'
|
||||||
invalid_code: 'Código inválido!'
|
invalid_code: 'Código inválido!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
# Unidades de tempo
|
||||||
bedrock_auto_login:
|
time:
|
||||||
success: '&aLogin automático Bedrock bem-sucedido!'
|
second: 'segundo'
|
||||||
|
seconds: 'segundos'
|
||||||
# 3rd party features: Login Location Fix
|
minute: 'minuto'
|
||||||
login_location_fix:
|
minutes: 'minutos'
|
||||||
fix_portal: '&aVocê está preso no portal durante o login.'
|
hour: 'hora'
|
||||||
fix_underground: '&aVocê está preso no subsolo durante o login.'
|
hours: 'horas'
|
||||||
cannot_fix_underground: '&aVocê está preso no subsolo durante o login, mas não podemos corrigir.'
|
day: 'dia'
|
||||||
|
days: 'dias'
|
||||||
# 3rd party features: Double Login Fix
|
|
||||||
double_login_fix:
|
|
||||||
fix_message: '&cVocê foi desconectado devido a login duplo.'
|
|
||||||
|
|||||||
@ -19,8 +19,7 @@ password:
|
|||||||
name_in_password: '&cNemůžeš použít své jméno jako heslo, prosím, zvol si jiné heslo...'
|
name_in_password: '&cNemůžeš použít své jméno jako heslo, prosím, zvol si jiné heslo...'
|
||||||
unsafe_password: '&cToto heslo není bezpečné, prosím, zvol si jiné heslo...'
|
unsafe_password: '&cToto heslo není bezpečné, prosím, zvol si jiné heslo...'
|
||||||
forbidden_characters: '&4Tvoje heslo obsahuje nepovolené znaky. Přípustné znaky jsou: %valid_chars'
|
forbidden_characters: '&4Tvoje heslo obsahuje nepovolené znaky. Přípustné znaky jsou: %valid_chars'
|
||||||
wrong_length: '&cTvoje heslo nedosahuje minimální délky.'
|
wrong_length: '&cTvoje heslo nedosahuje minimální délky (4).'
|
||||||
pwned_password: '&cZvolené heslo není bezpečné. Bylo použito již %pwned_count krát! Prosím, použijte silné heslo...'
|
|
||||||
|
|
||||||
# Login
|
# Login
|
||||||
login:
|
login:
|
||||||
@ -58,7 +57,6 @@ unregister:
|
|||||||
# Other messages
|
# Other messages
|
||||||
misc:
|
misc:
|
||||||
account_not_activated: '&cTvůj účet ještě není aktivovaný, zkontroluj svůj E-mail.'
|
account_not_activated: '&cTvůj účet ještě není aktivovaný, zkontroluj svůj E-mail.'
|
||||||
not_activated: '&cÚčet není aktivován, prosím zaregistrujte se a aktivujte ho před dalším pokusem.'
|
|
||||||
password_changed: '&cHeslo změněno!'
|
password_changed: '&cHeslo změněno!'
|
||||||
logout: '&cÚspěšně jsi se odhlásil.'
|
logout: '&cÚspěšně jsi se odhlásil.'
|
||||||
reload: '&cZnovu načtení nastavení AuthMe proběhlo úspěšně.'
|
reload: '&cZnovu načtení nastavení AuthMe proběhlo úspěšně.'
|
||||||
@ -157,17 +155,3 @@ two_factor:
|
|||||||
not_enabled_error: 'Dvoufaktorové ověření není zapnuté na tvém účtu. Můžeš ho zapnout použitím příkazu /2fa add'
|
not_enabled_error: 'Dvoufaktorové ověření není zapnuté na tvém účtu. Můžeš ho zapnout použitím příkazu /2fa add'
|
||||||
removed_success: 'Dvoufaktorovka byla úspěšně odebrána z tvého účtu'
|
removed_success: 'Dvoufaktorovka byla úspěšně odebrána z tvého účtu'
|
||||||
invalid_code: 'Nesprávný kód!'
|
invalid_code: 'Nesprávný kód!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
|
||||||
bedrock_auto_login:
|
|
||||||
success: '&aAutomatické přihlášení Bedrock úspěšné!'
|
|
||||||
|
|
||||||
# 3rd party features: Login Location Fix
|
|
||||||
login_location_fix:
|
|
||||||
fix_portal: '&aPři přihlášení jste uvízli v portálu.'
|
|
||||||
fix_underground: '&aPři přihlášení jste uvízli pod zemí.'
|
|
||||||
cannot_fix_underground: '&aPři přihlášení jste uvízli pod zemí, ale nemůžeme to opravit.'
|
|
||||||
|
|
||||||
# 3rd party features: Double Login Fix
|
|
||||||
double_login_fix:
|
|
||||||
fix_message: '&cByli jste odpojeni kvůli dvojímu přihlášení.'
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ registration:
|
|||||||
name_taken: '&cDieser Benutzername ist schon vergeben'
|
name_taken: '&cDieser Benutzername ist schon vergeben'
|
||||||
register_request: '&3Bitte registriere dich mit "/register <passwort> <passwortBestätigen>"'
|
register_request: '&3Bitte registriere dich mit "/register <passwort> <passwortBestätigen>"'
|
||||||
command_usage: '&cBenutze: /register <passwort> <passwortBestätigen>'
|
command_usage: '&cBenutze: /register <passwort> <passwortBestätigen>'
|
||||||
reg_only: '&4Nur für registrierte Spieler! Bitte besuche https://example.com um dich zu registrieren.'
|
reg_only: '&4Nur für registrierte Spieler! Bitte besuche http://example.com um dich zu registrieren.'
|
||||||
success: '&2Erfolgreich registriert!'
|
success: '&2Erfolgreich registriert!'
|
||||||
kicked_admin_registered: 'Ein Administrator hat dich bereits registriert; bitte logge dich erneut ein.'
|
kicked_admin_registered: 'Ein Administrator hat dich bereits registriert; bitte logge dich erneut ein.'
|
||||||
|
|
||||||
@ -20,7 +20,6 @@ password:
|
|||||||
unsafe_password: '&cPasswort unsicher! Bitte wähle ein anderes.'
|
unsafe_password: '&cPasswort unsicher! Bitte wähle ein anderes.'
|
||||||
forbidden_characters: '&4Dein Passwort enthält unerlaubte Zeichen. Zulässige Zeichen: %valid_chars'
|
forbidden_characters: '&4Dein Passwort enthält unerlaubte Zeichen. Zulässige Zeichen: %valid_chars'
|
||||||
wrong_length: '&cDein Passwort ist zu kurz oder zu lang!'
|
wrong_length: '&cDein Passwort ist zu kurz oder zu lang!'
|
||||||
pwned_password: '&cIhr gewähltes Passwort ist nicht sicher. Es wurde bereits %pwned_count Mal verwendet! Bitte verwenden Sie ein starkes Passwort...'
|
|
||||||
|
|
||||||
# Login
|
# Login
|
||||||
login:
|
login:
|
||||||
@ -41,7 +40,7 @@ error:
|
|||||||
max_registration: '&cDu hast die maximale Anzahl an Accounts erreicht (%reg_count/%max_acc %reg_names).'
|
max_registration: '&cDu hast die maximale Anzahl an Accounts erreicht (%reg_count/%max_acc %reg_names).'
|
||||||
logged_in: '&cBereits eingeloggt!'
|
logged_in: '&cBereits eingeloggt!'
|
||||||
kick_for_vip: '&3Ein VIP-Spieler hat den vollen Server betreten!'
|
kick_for_vip: '&3Ein VIP-Spieler hat den vollen Server betreten!'
|
||||||
kick_unresolved_hostname: '&cEin Fehler ist aufgetreten: nicht auflösbarer Spieler-Hostname!'
|
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||||
tempban_max_logins: '&cDu bist wegen zu vielen fehlgeschlagenen Login-Versuchen temporär gebannt!'
|
tempban_max_logins: '&cDu bist wegen zu vielen fehlgeschlagenen Login-Versuchen temporär gebannt!'
|
||||||
|
|
||||||
# AntiBot
|
# AntiBot
|
||||||
@ -58,7 +57,6 @@ unregister:
|
|||||||
# Other messages
|
# Other messages
|
||||||
misc:
|
misc:
|
||||||
account_not_activated: '&cDein Account wurde noch nicht aktiviert. Bitte prüfe deine E-Mails!'
|
account_not_activated: '&cDein Account wurde noch nicht aktiviert. Bitte prüfe deine E-Mails!'
|
||||||
not_activated: '&cKonto nicht aktiviert, bitte registrieren und aktivieren Sie es, bevor Sie es erneut versuchen.'
|
|
||||||
password_changed: '&2Passwort geändert!'
|
password_changed: '&2Passwort geändert!'
|
||||||
logout: '&2Erfolgreich ausgeloggt'
|
logout: '&2Erfolgreich ausgeloggt'
|
||||||
reload: '&2Konfiguration und Datenbank wurden erfolgreich neu geladen.'
|
reload: '&2Konfiguration und Datenbank wurden erfolgreich neu geladen.'
|
||||||
@ -157,17 +155,3 @@ two_factor:
|
|||||||
not_enabled_error: 'Die Zwei-Faktor-Authentifizierung ist für dein Konto nicht aktiviert. Benutze /2fa add'
|
not_enabled_error: 'Die Zwei-Faktor-Authentifizierung ist für dein Konto nicht aktiviert. Benutze /2fa add'
|
||||||
removed_success: 'Die Zwei-Faktor-Authentifizierung wurde erfolgreich von deinem Konto entfernt'
|
removed_success: 'Die Zwei-Faktor-Authentifizierung wurde erfolgreich von deinem Konto entfernt'
|
||||||
invalid_code: 'Ungültiger Code!'
|
invalid_code: 'Ungültiger Code!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
|
||||||
bedrock_auto_login:
|
|
||||||
success: '&aBedrock Auto-Login erfolgreich!'
|
|
||||||
|
|
||||||
# 3rd party features: Login Location Fix
|
|
||||||
login_location_fix:
|
|
||||||
fix_portal: '&aSie stecken während des Logins im Portal fest.'
|
|
||||||
fix_underground: '&aSie stecken während des Logins unter der Erde fest.'
|
|
||||||
cannot_fix_underground: '&aSie stecken während des Logins unter der Erde fest, aber wir können es nicht beheben.'
|
|
||||||
|
|
||||||
# 3rd party features: Double Login Fix
|
|
||||||
double_login_fix:
|
|
||||||
fix_message: '&cSie wurden wegen doppeltem Login getrennt.'
|
|
||||||
|
|||||||
@ -5,13 +5,13 @@
|
|||||||
|
|
||||||
# Registration
|
# Registration
|
||||||
registration:
|
registration:
|
||||||
disabled: '&cIn-game registration is disabled!'
|
|
||||||
name_taken: '&cYou already have registered this username!'
|
|
||||||
register_request: '&3Please, register to the server with the command: /register <password> <ConfirmPassword>'
|
register_request: '&3Please, register to the server with the command: /register <password> <ConfirmPassword>'
|
||||||
command_usage: '&cUsage: /register <password> <ConfirmPassword>'
|
command_usage: '&cUsage: /register <password> <ConfirmPassword>'
|
||||||
reg_only: '&4Only registered users can join the server! Please visit https://example.com to register yourself!'
|
reg_only: '&4Only registered users can join the server! Please visit http://example.com to register yourself!'
|
||||||
success: '&2Successfully registered!'
|
|
||||||
kicked_admin_registered: 'An admin just registered you; please log in again.'
|
kicked_admin_registered: 'An admin just registered you; please log in again.'
|
||||||
|
success: '&2Successfully registered!'
|
||||||
|
disabled: '&cIn-game registration is disabled!'
|
||||||
|
name_taken: '&cYou already have registered this username!'
|
||||||
|
|
||||||
# Password errors on registration
|
# Password errors on registration
|
||||||
password:
|
password:
|
||||||
@ -32,17 +32,17 @@ login:
|
|||||||
|
|
||||||
# Errors
|
# Errors
|
||||||
error:
|
error:
|
||||||
|
unregistered_user: '&cThis user isn''t registered!'
|
||||||
denied_command: '&cIn order to use this command you must be authenticated!'
|
denied_command: '&cIn order to use this command you must be authenticated!'
|
||||||
denied_chat: '&cIn order to chat you must be authenticated!'
|
denied_chat: '&cIn order to chat you must be authenticated!'
|
||||||
unregistered_user: '&cThis user isn''t registered!'
|
|
||||||
not_logged_in: '&cYou''re not logged in!'
|
not_logged_in: '&cYou''re not logged in!'
|
||||||
|
tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.'
|
||||||
|
max_registration: '&cYou have exceeded the maximum number of registrations (%reg_count/%max_acc %reg_names) for your connection!'
|
||||||
no_permission: '&4You don''t have the permission to perform this action!'
|
no_permission: '&4You don''t have the permission to perform this action!'
|
||||||
unexpected_error: '&4An unexpected error occurred, please contact an administrator!'
|
unexpected_error: '&4An unexpected error occurred, please contact an administrator!'
|
||||||
max_registration: '&cYou have exceeded the maximum number of registrations (%reg_count/%max_acc %reg_names) for your connection!'
|
|
||||||
logged_in: '&cYou''re already logged in!'
|
|
||||||
kick_for_vip: '&3A VIP player has joined the server when it was full!'
|
kick_for_vip: '&3A VIP player has joined the server when it was full!'
|
||||||
|
logged_in: '&cYou''re already logged in!'
|
||||||
kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||||
tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.'
|
|
||||||
|
|
||||||
# AntiBot
|
# AntiBot
|
||||||
antibot:
|
antibot:
|
||||||
@ -50,21 +50,19 @@ antibot:
|
|||||||
auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
|
auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
|
||||||
auto_disabled: '&2[AntiBotService] AntiBot disabled after %m minutes!'
|
auto_disabled: '&2[AntiBotService] AntiBot disabled after %m minutes!'
|
||||||
|
|
||||||
# Unregister
|
|
||||||
unregister:
|
unregister:
|
||||||
success: '&cSuccessfully unregistered!'
|
success: '&cSuccessfully unregistered!'
|
||||||
command_usage: '&cUsage: /unregister <password>'
|
command_usage: '&cUsage: /unregister <password>'
|
||||||
|
|
||||||
# Other messages
|
# Other messages
|
||||||
misc:
|
misc:
|
||||||
|
accounts_owned_self: 'You own %count accounts:'
|
||||||
|
accounts_owned_other: 'The player %name has %count accounts:'
|
||||||
account_not_activated: '&cYour account isn''t activated yet, please check your emails!'
|
account_not_activated: '&cYour account isn''t activated yet, please check your emails!'
|
||||||
not_activated: '&cAccount not activated, please register and activate it before trying again.'
|
|
||||||
password_changed: '&2Password changed successfully!'
|
password_changed: '&2Password changed successfully!'
|
||||||
logout: '&2Logged out successfully!'
|
logout: '&2Logged out successfully!'
|
||||||
reload: '&2Configuration and database have been reloaded correctly!'
|
reload: '&2Configuration and database have been reloaded correctly!'
|
||||||
usage_change_password: '&cUsage: /changepassword <oldPassword> <newPassword>'
|
usage_change_password: '&cUsage: /changepassword <oldPassword> <newPassword>'
|
||||||
accounts_owned_self: 'You own %count accounts:'
|
|
||||||
accounts_owned_other: 'The player %name has %count accounts:'
|
|
||||||
|
|
||||||
# Session messages
|
# Session messages
|
||||||
session:
|
session:
|
||||||
@ -73,36 +71,36 @@ session:
|
|||||||
|
|
||||||
# Error messages when joining
|
# Error messages when joining
|
||||||
on_join_validation:
|
on_join_validation:
|
||||||
same_ip_online: 'A player with the same IP is already in game!'
|
|
||||||
same_nick_online: '&4The same username is already playing on the server!'
|
|
||||||
name_length: '&4Your username is either too short or too long!'
|
name_length: '&4Your username is either too short or too long!'
|
||||||
characters_in_name: '&4Your username contains illegal characters. Allowed chars: %valid_chars'
|
characters_in_name: '&4Your username contains illegal characters. Allowed chars: %valid_chars'
|
||||||
kick_full_server: '&4The server is full, try again later!'
|
|
||||||
country_banned: '&4Your country is banned from this server!'
|
country_banned: '&4Your country is banned from this server!'
|
||||||
not_owner_error: 'You are not the owner of this account. Please choose another name!'
|
not_owner_error: 'You are not the owner of this account. Please choose another name!'
|
||||||
|
kick_full_server: '&4The server is full, try again later!'
|
||||||
|
same_nick_online: '&4The same username is already playing on the server!'
|
||||||
invalid_name_case: 'You should join using username %valid, not %invalid.'
|
invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||||
|
same_ip_online: 'A player with the same IP is already in game!'
|
||||||
quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.'
|
quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.'
|
||||||
|
|
||||||
# Email
|
# Email
|
||||||
email:
|
email:
|
||||||
add_email_request: '&3Please add your email to your account with the command: /email add <yourEmail> <confirmEmail>'
|
|
||||||
usage_email_add: '&cUsage: /email add <email> <confirmEmail>'
|
usage_email_add: '&cUsage: /email add <email> <confirmEmail>'
|
||||||
usage_email_change: '&cUsage: /email change <oldEmail> <newEmail>'
|
usage_email_change: '&cUsage: /email change <oldEmail> <newEmail>'
|
||||||
new_email_invalid: '&cInvalid new email, try again!'
|
new_email_invalid: '&cInvalid new email, try again!'
|
||||||
old_email_invalid: '&cInvalid old email, try again!'
|
old_email_invalid: '&cInvalid old email, try again!'
|
||||||
invalid: '&cInvalid email address, try again!'
|
invalid: '&cInvalid email address, try again!'
|
||||||
added: '&2Email address successfully added to your account!'
|
added: '&2Email address successfully added to your account!'
|
||||||
add_not_allowed: '&cAdding email was not allowed.'
|
|
||||||
request_confirmation: '&cPlease confirm your email address!'
|
request_confirmation: '&cPlease confirm your email address!'
|
||||||
changed: '&2Email address changed correctly!'
|
changed: '&2Email address changed correctly!'
|
||||||
change_not_allowed: '&cChanging email was not allowed.'
|
|
||||||
email_show: '&2Your current email address is: &f%email'
|
email_show: '&2Your current email address is: &f%email'
|
||||||
no_email_for_account: '&2You currently don''t have email address associated with this account.'
|
|
||||||
already_used: '&4The email address is already being used'
|
|
||||||
incomplete_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
|
incomplete_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
|
||||||
|
already_used: '&4The email address is already being used'
|
||||||
send_failure: 'The email could not be sent. Please contact an administrator.'
|
send_failure: 'The email could not be sent. Please contact an administrator.'
|
||||||
|
no_email_for_account: '&2You currently don''t have email address associated with this account.'
|
||||||
|
add_email_request: '&3Please add your email to your account with the command: /email add <yourEmail> <confirmEmail>'
|
||||||
change_password_expired: 'You cannot change your password using this command anymore.'
|
change_password_expired: 'You cannot change your password using this command anymore.'
|
||||||
email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.'
|
email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.'
|
||||||
|
add_not_allowed: '&cAdding email was not allowed.'
|
||||||
|
change_not_allowed: '&cChanging email was not allowed.'
|
||||||
|
|
||||||
# Password recovery by email
|
# Password recovery by email
|
||||||
recovery:
|
recovery:
|
||||||
@ -134,17 +132,6 @@ verification:
|
|||||||
code_expired: '&3Your code has expired! Execute another sensitive command to get a new code!'
|
code_expired: '&3Your code has expired! Execute another sensitive command to get a new code!'
|
||||||
email_needed: '&3To verify your identity you need to link an email address with your account!!'
|
email_needed: '&3To verify your identity you need to link an email address with your account!!'
|
||||||
|
|
||||||
# Time units
|
|
||||||
time:
|
|
||||||
second: 'second'
|
|
||||||
seconds: 'seconds'
|
|
||||||
minute: 'minute'
|
|
||||||
minutes: 'minutes'
|
|
||||||
hour: 'hour'
|
|
||||||
hours: 'hours'
|
|
||||||
day: 'day'
|
|
||||||
days: 'days'
|
|
||||||
|
|
||||||
# Two-factor authentication
|
# Two-factor authentication
|
||||||
two_factor:
|
two_factor:
|
||||||
code_created: '&2Your secret code is %code. You can scan it from here %url'
|
code_created: '&2Your secret code is %code. You can scan it from here %url'
|
||||||
@ -158,15 +145,37 @@ two_factor:
|
|||||||
removed_success: 'Successfully removed two-factor auth from your account'
|
removed_success: 'Successfully removed two-factor auth from your account'
|
||||||
invalid_code: 'Invalid code!'
|
invalid_code: 'Invalid code!'
|
||||||
|
|
||||||
|
# Time units
|
||||||
|
time:
|
||||||
|
second: 'second'
|
||||||
|
seconds: 'seconds'
|
||||||
|
minute: 'minute'
|
||||||
|
minutes: 'minutes'
|
||||||
|
hour: 'hour'
|
||||||
|
hours: 'hours'
|
||||||
|
day: 'day'
|
||||||
|
days: 'days'
|
||||||
|
|
||||||
|
# 3rd party features: GUI Captcha
|
||||||
|
gui_captcha:
|
||||||
|
success: '&aVerification success!'
|
||||||
|
bedrock_auto_verify_success: '&aBedrock verification success!'
|
||||||
|
captcha_window_name: '%random Verification'
|
||||||
|
captcha_clickable_name: '%random I am human'
|
||||||
|
message_on_retry: '&cVerification failed, you have %times retries left'
|
||||||
|
denied_message_sending: '&cPlease be verified before chatting!'
|
||||||
|
kick_on_failed: '&cPlease complete the verification!'
|
||||||
|
kick_on_timeout: '&cVerification timed out!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
# 3rd party features: Bedrock Auto Login
|
||||||
bedrock_auto_login:
|
bedrock_auto_login:
|
||||||
success: '&aBedrock auto login success!'
|
success: '&aBedrock auto login success!'
|
||||||
|
|
||||||
# 3rd party features: Login Location Fix
|
# 3rd party features: Login Location Fix
|
||||||
login_location_fix:
|
login_location_fix:
|
||||||
fix_portal: '&aYou are stuck in portal during login.'
|
fix_portal: '&aYou are stuck in portal during Login.'
|
||||||
fix_underground: '&aYou are stuck underground during login.'
|
fix_underground: '&aYou are stuck underground during Login.'
|
||||||
cannot_fix_underground: '&aYou are stuck underground during login, but we cant fix it.'
|
cannot_fix_underground: '&aYou are stuck underground during Login, but we cant fix it.'
|
||||||
|
|
||||||
# 3rd party features: Double Login Fix
|
# 3rd party features: Double Login Fix
|
||||||
double_login_fix:
|
double_login_fix:
|
||||||
|
|||||||
@ -9,7 +9,7 @@ registration:
|
|||||||
name_taken: '&cVi jam registris tiun uzantnomon!'
|
name_taken: '&cVi jam registris tiun uzantnomon!'
|
||||||
register_request: '&3Bonvolu registri al la servilo per la komando: /register <pasvorto> <konfirmiPasvorto>'
|
register_request: '&3Bonvolu registri al la servilo per la komando: /register <pasvorto> <konfirmiPasvorto>'
|
||||||
command_usage: '&cUzado: /register <pasvorto> <konfirmiPasvorto>'
|
command_usage: '&cUzado: /register <pasvorto> <konfirmiPasvorto>'
|
||||||
reg_only: '&4Nur registritaj uzantoj povas aliĝi la servilon! Bonvolu viziti https://example.com registri vin mem!'
|
reg_only: '&4Nur registritaj uzantoj povas aliĝi la servilon! Bonvolu viziti http://example.com registri vin mem!'
|
||||||
success: '&2Sukcese registris!'
|
success: '&2Sukcese registris!'
|
||||||
kicked_admin_registered: 'Administranto ĵus registrita vin; bonvolu ensaluti denove'
|
kicked_admin_registered: 'Administranto ĵus registrita vin; bonvolu ensaluti denove'
|
||||||
|
|
||||||
@ -20,7 +20,6 @@ password:
|
|||||||
unsafe_password: '&cLa elektita pasvorto estas danĝere, bonvolu elekti alian...'
|
unsafe_password: '&cLa elektita pasvorto estas danĝere, bonvolu elekti alian...'
|
||||||
forbidden_characters: '&4Via pasvorto enhavas kontraŭleĝan karakteroj. Permesita signoj: %valid_chars'
|
forbidden_characters: '&4Via pasvorto enhavas kontraŭleĝan karakteroj. Permesita signoj: %valid_chars'
|
||||||
wrong_length: '&cVia pasvorto estas tro mallonga aŭ tro longa! Bonvolu provi alian pasvorton!'
|
wrong_length: '&cVia pasvorto estas tro mallonga aŭ tro longa! Bonvolu provi alian pasvorton!'
|
||||||
pwned_password: '&cVia elektita pasvorto ne estas sekura. Ĝi estis uzita %pwned_count fojojn jam! Bonvolu uzi fortan pasvorton...'
|
|
||||||
|
|
||||||
# Login
|
# Login
|
||||||
login:
|
login:
|
||||||
@ -41,7 +40,7 @@ error:
|
|||||||
max_registration: 'Vi superis la maksimuman nombron de enregistroj (%reg_count/%max_acc %reg_names) pro via ligo!'
|
max_registration: 'Vi superis la maksimuman nombron de enregistroj (%reg_count/%max_acc %reg_names) pro via ligo!'
|
||||||
logged_in: '&cVi jam estas ensalutinta!'
|
logged_in: '&cVi jam estas ensalutinta!'
|
||||||
kick_for_vip: '&3VIP ludanto aliĝis al la servilo kiam ĝi pleniĝis!'
|
kick_for_vip: '&3VIP ludanto aliĝis al la servilo kiam ĝi pleniĝis!'
|
||||||
kick_unresolved_hostname: '&cEraro okazis: neatingebla ludanta gastiga nomo!'
|
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||||
tempban_max_logins: '&cVi estis portempe malpermesita por ne ensaluti tro multajn fojojn.'
|
tempban_max_logins: '&cVi estis portempe malpermesita por ne ensaluti tro multajn fojojn.'
|
||||||
|
|
||||||
# AntiBot
|
# AntiBot
|
||||||
@ -58,7 +57,6 @@ unregister:
|
|||||||
# Other messages
|
# Other messages
|
||||||
misc:
|
misc:
|
||||||
account_not_activated: '&cVia konto ne aktivigis tamen, bonvolu kontroli viajn retpoŝtojn!'
|
account_not_activated: '&cVia konto ne aktivigis tamen, bonvolu kontroli viajn retpoŝtojn!'
|
||||||
not_activated: '&cKonto ne aktivigita, bonvolu registriĝi kaj aktivigi ĝin antaŭ ol provi denove.'
|
|
||||||
password_changed: '&2Pasvorto sukcese ŝanĝita!'
|
password_changed: '&2Pasvorto sukcese ŝanĝita!'
|
||||||
logout: '&2Elsalutita sukcese!'
|
logout: '&2Elsalutita sukcese!'
|
||||||
reload: '&2Agordo kaj datumbazo estis larditaj korekte!'
|
reload: '&2Agordo kaj datumbazo estis larditaj korekte!'
|
||||||
@ -81,7 +79,7 @@ on_join_validation:
|
|||||||
country_banned: '&4Via lando estas malpermesitaj de tiu servilo!'
|
country_banned: '&4Via lando estas malpermesitaj de tiu servilo!'
|
||||||
not_owner_error: 'Vi ne estas la posedanto de tiu konto. Bonvolu elekti alian nomon!'
|
not_owner_error: 'Vi ne estas la posedanto de tiu konto. Bonvolu elekti alian nomon!'
|
||||||
invalid_name_case: 'Vi devus aliĝi uzante uzantnomon %valid, ne %invalid.'
|
invalid_name_case: 'Vi devus aliĝi uzante uzantnomon %valid, ne %invalid.'
|
||||||
quick_command: 'Vi uzis komandon tro rapide! Bonvolu, re-aliĝi al la servilo kaj atendi pli longe antaŭ ol uzi iun ajn komandon.'
|
# TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.'
|
||||||
|
|
||||||
# Email
|
# Email
|
||||||
email:
|
email:
|
||||||
@ -92,10 +90,10 @@ email:
|
|||||||
old_email_invalid: '&cNevalida malnovaj retpoŝto, provu denove!'
|
old_email_invalid: '&cNevalida malnovaj retpoŝto, provu denove!'
|
||||||
invalid: '&cNevalida retadreso, provu denove!'
|
invalid: '&cNevalida retadreso, provu denove!'
|
||||||
added: '&2Retpoŝtadreso sukcese aldonitaj al via konto!'
|
added: '&2Retpoŝtadreso sukcese aldonitaj al via konto!'
|
||||||
add_not_allowed: '&cAldoni retpoŝton ne estis permesita.'
|
# TODO add_not_allowed: '&cAdding email was not allowed'
|
||||||
request_confirmation: '&cBonvolu konfirmi vian retadreson!'
|
request_confirmation: '&cBonvolu konfirmi vian retadreson!'
|
||||||
changed: '&2Retpoŝtadreso ŝanĝis ĝuste!'
|
changed: '&2Retpoŝtadreso ŝanĝis ĝuste!'
|
||||||
change_not_allowed: '&cŜanĝi retpoŝton ne estis permesita.'
|
# TODO change_not_allowed: '&cChanging email was not allowed'
|
||||||
email_show: '&2Via nuna retadreso estas: &f%email'
|
email_show: '&2Via nuna retadreso estas: &f%email'
|
||||||
no_email_for_account: '&2Vi aktuale ne havas retadreson asociita kun ĉi tiu konto.'
|
no_email_for_account: '&2Vi aktuale ne havas retadreson asociita kun ĉi tiu konto.'
|
||||||
already_used: '&4La retpoŝto jam estas uzata'
|
already_used: '&4La retpoŝto jam estas uzata'
|
||||||
@ -121,18 +119,18 @@ captcha:
|
|||||||
usage_captcha: '&3Ensaluti vi devas solvi captcha kodo, bonvolu uzi la komando: /captcha %captcha_code'
|
usage_captcha: '&3Ensaluti vi devas solvi captcha kodo, bonvolu uzi la komando: /captcha %captcha_code'
|
||||||
wrong_captcha: '&cMalĝusta captcha, bonvolu tajpi "/captcha %captcha_code" en la babilejo!'
|
wrong_captcha: '&cMalĝusta captcha, bonvolu tajpi "/captcha %captcha_code" en la babilejo!'
|
||||||
valid_captcha: '&2Captcha kodo solvita ĝuste!'
|
valid_captcha: '&2Captcha kodo solvita ĝuste!'
|
||||||
captcha_for_registration: 'Por registri vi devas unue solvi kapĉon, bonvolu uzi la komandon: /captcha %captcha_code'
|
# TODO captcha_for_registration: 'To register you have to solve a captcha first, please use the command: /captcha %captcha_code'
|
||||||
register_captcha_valid: '&2Valida kapĉo! Vi nun povas registri per /register'
|
# TODO register_captcha_valid: '&2Valid captcha! You may now register with /register'
|
||||||
|
|
||||||
# Verification code
|
# Verification code
|
||||||
verification:
|
verification:
|
||||||
code_required: '&3Tiu ĉi komando estas sentema kaj postulas retpoŝtan kontrolon! Kontrolu vian leterkeston kaj sekvu la instrukciojn en la retpoŝto.'
|
# TODO code_required: '&3This command is sensitive and requires an email verification! Check your inbox and follow the email''s instructions.'
|
||||||
command_usage: '&cUzado: /verification <code>'
|
# TODO command_usage: '&cUsage: /verification <code>'
|
||||||
incorrect_code: '&cMalĝusta kodo, bonvolu tajpi "/verification <code>" en la babilejo, uzante la kodon, kiun vi ricevis per retpoŝto'
|
# TODO incorrect_code: '&cIncorrect code, please type "/verification <code>" into the chat, using the code you received by email'
|
||||||
success: '&2Via identeco estis kontrolita! Vi nun povas ekzekuti ĉiujn komandojn dum la aktuala sesio!'
|
# TODO success: '&2Your identity has been verified! You can now execute all commands within the current session!'
|
||||||
already_verified: '&2Vi jam povas ekzekuti ĉiujn sentemajn komandojn dum la aktuala sesio!'
|
# TODO already_verified: '&2You can already execute every sensitive command within the current session!'
|
||||||
code_expired: '&3Via kodo eksvalidiĝis! Ekzekutu alian senteman komandon por ricevi novan kodon!'
|
# TODO code_expired: '&3Your code has expired! Execute another sensitive command to get a new code!'
|
||||||
email_needed: '&3Por kontroli vian identecon vi devas ligi retpoŝtan adreson kun via konto!'
|
# TODO email_needed: '&3To verify your identity you need to link an email address with your account!!'
|
||||||
|
|
||||||
# Time units
|
# Time units
|
||||||
time:
|
time:
|
||||||
@ -148,26 +146,12 @@ time:
|
|||||||
# Two-factor authentication
|
# Two-factor authentication
|
||||||
two_factor:
|
two_factor:
|
||||||
code_created: '&2Via sekreta kodo estas %code. Vi povas skani ĝin de tie %url'
|
code_created: '&2Via sekreta kodo estas %code. Vi povas skani ĝin de tie %url'
|
||||||
confirmation_required: 'Bonvolu konfirmi vian kodon per /2fa confirm <code>'
|
# TODO confirmation_required: 'Please confirm your code with /2fa confirm <code>'
|
||||||
code_required: 'Bonvolu sendi vian du-faktoran aŭtentikigan kodon per /2fa code <code>'
|
# TODO code_required: 'Please submit your two-factor authentication code with /2fa code <code>'
|
||||||
already_enabled: 'Du-faktora aŭtentikigo jam estas ebligita por via konto!'
|
# TODO already_enabled: 'Two-factor authentication is already enabled for your account!'
|
||||||
enable_error_no_code: 'Neniu 2fa ŝlosilo estis generita por vi aŭ ĝi eksvalidiĝis. Bonvolu kuri /2fa add'
|
# TODO enable_error_no_code: 'No 2fa key has been generated for you or it has expired. Please run /2fa add'
|
||||||
enable_success: 'Sukcese ebligis du-faktoran aŭtentikigon por via konto'
|
# TODO enable_success: 'Successfully enabled two-factor authentication for your account'
|
||||||
enable_error_wrong_code: 'Malĝusta kodo aŭ kodo eksvalidiĝis. Bonvolu kuri /2fa add'
|
# TODO enable_error_wrong_code: 'Wrong code or code has expired. Please run /2fa add'
|
||||||
not_enabled_error: 'Du-faktora aŭtentikigo ne estas ebligita por via konto. Kuru /2fa add'
|
# TODO not_enabled_error: 'Two-factor authentication is not enabled for your account. Run /2fa add'
|
||||||
removed_success: 'Sukcese forigis du-faktoran aŭtentikigon de via konto'
|
# TODO removed_success: 'Successfully removed two-factor auth from your account'
|
||||||
invalid_code: 'Nevalida kodo!'
|
# TODO invalid_code: 'Invalid code!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
|
||||||
bedrock_auto_login:
|
|
||||||
success: '&aSukcesa Bedrock-aŭtomata ensaluto!'
|
|
||||||
|
|
||||||
# 3rd party features: Login Location Fix
|
|
||||||
login_location_fix:
|
|
||||||
fix_portal: '&aVi estas blokita en portalo dum ensaluto.'
|
|
||||||
fix_underground: '&aVi estas blokita subtere dum ensaluto.'
|
|
||||||
cannot_fix_underground: '&aVi estas blokita subtere dum ensaluto, sed ni ne povas ripari ĝin.'
|
|
||||||
|
|
||||||
# 3rd party features: Double Login Fix
|
|
||||||
double_login_fix:
|
|
||||||
fix_message: '&cVi estis malkonektita pro duobla ensaluto.'
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ registration:
|
|||||||
name_taken: '&cUsuario ya registrado'
|
name_taken: '&cUsuario ya registrado'
|
||||||
register_request: '&cPor favor, regístrate con "/register <contraseña> <confirmarContraseña">'
|
register_request: '&cPor favor, regístrate con "/register <contraseña> <confirmarContraseña">'
|
||||||
command_usage: '&cUso: /register Contraseña ConfirmarContraseña'
|
command_usage: '&cUso: /register Contraseña ConfirmarContraseña'
|
||||||
reg_only: '&f¡Sólo para jugadores registrados! Por favor visita https://www.example.com/ para registrarte'
|
reg_only: '&f¡Sólo para jugadores registrados! Por favor visita http://www.example.com/ para registrarte'
|
||||||
success: '&c¡Registrado correctamente!'
|
success: '&c¡Registrado correctamente!'
|
||||||
kicked_admin_registered: 'Un administrador te acaba de registrar; entra en la cuenta de nuevo'
|
kicked_admin_registered: 'Un administrador te acaba de registrar; entra en la cuenta de nuevo'
|
||||||
|
|
||||||
@ -21,7 +21,6 @@ password:
|
|||||||
unsafe_password: '&cLa contraseña elegida no es segura, por favor elija otra...'
|
unsafe_password: '&cLa contraseña elegida no es segura, por favor elija otra...'
|
||||||
forbidden_characters: '&cTu contraseña tiene carácteres no admitidos, los cuales son: %valid_chars'
|
forbidden_characters: '&cTu contraseña tiene carácteres no admitidos, los cuales son: %valid_chars'
|
||||||
wrong_length: '&fTu contraseña es muy larga o muy corta'
|
wrong_length: '&fTu contraseña es muy larga o muy corta'
|
||||||
pwned_password: '&cLa contraseña elegida no es segura. ¡Se ha usado %pwned_count veces ya! Por favor, use una contraseña fuerte...'
|
|
||||||
|
|
||||||
# Login
|
# Login
|
||||||
login:
|
login:
|
||||||
@ -42,7 +41,7 @@ error:
|
|||||||
max_registration: '&fHas excedido la cantidad máxima de registros para tu cuenta'
|
max_registration: '&fHas excedido la cantidad máxima de registros para tu cuenta'
|
||||||
logged_in: '&c¡Ya has iniciado sesión!'
|
logged_in: '&c¡Ya has iniciado sesión!'
|
||||||
kick_for_vip: '&c¡Un jugador VIP ha ingresado al servidor lleno!'
|
kick_for_vip: '&c¡Un jugador VIP ha ingresado al servidor lleno!'
|
||||||
kick_unresolved_hostname: '&cSe produjo un error: nombre de host del jugador no resuelto!'
|
# TODO kick_unresolved_hostname: '&cAn error occurred: unresolved player hostname!'
|
||||||
tempban_max_logins: '&cHas sido expulsado temporalmente por intentar iniciar sesión demasiadas veces.'
|
tempban_max_logins: '&cHas sido expulsado temporalmente por intentar iniciar sesión demasiadas veces.'
|
||||||
|
|
||||||
# AntiBot
|
# AntiBot
|
||||||
@ -59,7 +58,6 @@ unregister:
|
|||||||
# Other messages
|
# Other messages
|
||||||
misc:
|
misc:
|
||||||
account_not_activated: '&fTu cuenta no está activada aún, ¡revisa tu correo!'
|
account_not_activated: '&fTu cuenta no está activada aún, ¡revisa tu correo!'
|
||||||
not_activated: '&cCuenta no activada, por favor regístrese y actívela antes de intentarlo de nuevo.'
|
|
||||||
password_changed: '&c¡Contraseña cambiada!'
|
password_changed: '&c¡Contraseña cambiada!'
|
||||||
logout: '&cDesconectado correctamente.'
|
logout: '&cDesconectado correctamente.'
|
||||||
reload: '&fLa configuración y la base de datos han sido recargados'
|
reload: '&fLa configuración y la base de datos han sido recargados'
|
||||||
@ -158,17 +156,3 @@ two_factor:
|
|||||||
not_enabled_error: 'La autenticación de dos factores no está habilitada para tu cuenta. Por favor usa /2fa add'
|
not_enabled_error: 'La autenticación de dos factores no está habilitada para tu cuenta. Por favor usa /2fa add'
|
||||||
removed_success: 'Se ha eliminado correctamente la autenticación de dos factores de tu cuenta'
|
removed_success: 'Se ha eliminado correctamente la autenticación de dos factores de tu cuenta'
|
||||||
invalid_code: '¡Código incorrecto!'
|
invalid_code: '¡Código incorrecto!'
|
||||||
|
|
||||||
# 3rd party features: Bedrock Auto Login
|
|
||||||
bedrock_auto_login:
|
|
||||||
success: '&a¡Inicio de sesión automático de Bedrock exitoso!'
|
|
||||||
|
|
||||||
# 3rd party features: Login Location Fix
|
|
||||||
login_location_fix:
|
|
||||||
fix_portal: '&aEstás atascado en el portal durante el inicio de sesión.'
|
|
||||||
fix_underground: '&aEstás atascado bajo tierra durante el inicio de sesión.'
|
|
||||||
cannot_fix_underground: '&aEstás atascado bajo tierra durante el inicio de sesión, pero no podemos solucionarlo.'
|
|
||||||
|
|
||||||
# 3rd party features: Double Login Fix
|
|
||||||
double_login_fix:
|
|
||||||
fix_message: '&cHas sido desconectado debido a un inicio de sesión doble.'
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user