Compare commits

...

55 Commits

Author SHA1 Message Date
DGun Otto 3cffd16ff2 Merge pull request #123 from HaHaWTH/mp-1
Sync to multipaper
2024-04-14 19:39:17 +08:00
DGun Otto 3d1392f0e1 Merge branch 'multipaper' into mp-1 2024-04-14 19:39:03 +08:00
HaHaWTH 548be5042d Merge remote-tracking branch 'origin/master' 2024-04-07 12:37:57 +08:00
HaHaWTH e9fd7fd80f B47 release 2024-04-07 12:37:34 +08:00
DGun Otto e44cd3edc6 Merge pull request #124 from HaHaWTH/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.3.1
Bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1
2024-04-05 13:16:21 +08:00
dependabot[bot] 219a7a3493 Bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1
Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.0 to 3.3.1.
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.0...maven-source-plugin-3.3.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-source-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-05 04:57:38 +00:00
DGun Otto 6876a6dd9f Update workflows 2024-04-04 14:51:02 +08:00
DGun Otto d04a69f481 Update workflows 2024-04-04 13:26:41 +08:00
DGun Otto dfa8317706 Update workflows 2024-04-04 13:21:27 +08:00
HaHaWTH 555514f7dd Add warning for H2 database 2024-04-03 19:02:19 +08:00
HaHaWTH 74633937bc Revert stupid changes made by the original upstream 2024-04-03 16:40:37 +08:00
HaHaWTH 948736b5ea Merge upstream pull request #2777 2024-04-03 16:11:06 +08:00
HaHaWTH 5e54b8b105 Update build 2024-04-03 13:55:42 +08:00
DGun Otto 0d818dd00f Merge pull request #121 from HaHaWTH/dependabot/maven/org.jacoco-jacoco-maven-plugin-0.8.12
Bump org.jacoco:jacoco-maven-plugin from 0.8.11 to 0.8.12
2024-04-03 13:07:47 +08:00
dependabot[bot] 22586e601f Bump org.jacoco:jacoco-maven-plugin from 0.8.11 to 0.8.12
Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.11 to 0.8.12.
- [Release notes](https://github.com/jacoco/jacoco/releases)
- [Commits](https://github.com/jacoco/jacoco/compare/v0.8.11...v0.8.12)

---
updated-dependencies:
- dependency-name: org.jacoco:jacoco-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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