Compare commits

..

73 Commits

Author SHA1 Message Date
HaHaWTH 1c25908a04 Bump to Alpha 4 2023-09-30 10:12:43 +08:00
HaHaWTH 84a8137955 Bug Fix 2023-09-30 10:10:25 +08:00
HaHaWTH 038d4c1850 logic improvement 2023-09-30 09:55:26 +08:00
理塘丁真 0ffe2c2fc9 Deleted useless code 2023-09-30 09:04:55 +08:00
HaHaWTH 401933038d It works! 2023-09-30 09:02:47 +08:00
HaHaWTH 5cf88f308a Patch 2023-09-29 21:06:54 +08:00
HaHaWTH 29df796c48 Code Format 2023-09-29 17:36:06 +08:00
HaHaWTH 79af85667e Actually fix purge 2023-09-29 17:18:10 +08:00
HaHaWTH 57237f6dfa Fixes 2023-09-29 16:33:12 +08:00
HaHaWTH fc86e3ef78 Fix typo 2023-09-29 16:22:42 +08:00
HaHaWTH 846b7f67e5 Fix typo 2023-09-29 16:18:55 +08:00
HaHaWTH ffe3f5d24a Fix typo 2023-09-29 16:17:00 +08:00
HaHaWTH 2db1a15c72 Fix config path 2023-09-29 16:14:51 +08:00
HaHaWTH 95342ae054 Add features to delete bot join data 2023-09-29 16:13:48 +08:00
HaHaWTH 6800356f10 Small tweaks 2023-09-29 15:29:44 +08:00
HaHaWTH 95b5d88197 Fix typo 2023-09-29 15:26:10 +08:00
HaHaWTH 9f6f55d8e8 Fix config description 2023-09-29 15:24:26 +08:00
HaHaWTH d1ebcfeef0 Fix 2023-09-29 15:22:16 +08:00
HaHaWTH 5305bf0bfd Fix 2023-09-29 15:09:32 +08:00
HaHaWTH 78c5ab5d8a Add banner color switch option & advanced banners 2023-09-29 15:02:18 +08:00
HaHaWTH 836c568fef Update GeoLite2-Country database 2023-09-29 12:12:41 +08:00
HaHaWTH 7cbd1ebae7 Fix config path 2023-09-29 11:39:57 +08:00
HaHaWTH a35a277b32 Add useless banners & Code cleanup 2023-09-29 11:34:53 +08:00
HaHaWTH 971f0f7683 Update README 2023-09-23 18:58:08 +08:00
HaHaWTH d2718c1934 Bump ProtocolLib to 5.1.0 & EssentialsX to 2.20.1 2023-09-23 18:47:12 +08:00
HaHaWTH 0cdd2b20d6 Code Improvement 2023-09-23 18:42:23 +08:00
HaHaWTH 66b2bf8436 Code Improvement 2023-09-23 18:40:18 +08:00
HaHaWTH cf01767ad3 Revert changes 2023-09-23 18:29:17 +08:00
HaHaWTH fdefdb88cc Implement translation (2) 2023-09-23 18:17:12 +08:00
HaHaWTH 4bcc992b7f Implement translation (1) 2023-09-23 18:12:52 +08:00
HaHaWTH 35aba2207b TODO 2023-09-21 22:07:27 +08:00
HaHaWTH ce2ee9e0fb Fix config typo 2023-09-21 21:49:35 +08:00
HaHaWTH 9093ad2d9f Prepare for b23 2023-09-20 02:32:53 +08:00
HaHaWTH 08ed6504f2 Cleanup 2023-09-20 02:29:24 +08:00
HaHaWTH 9f70748b55 Useless code cleanup 2023-09-20 02:26:48 +08:00
HaHaWTH 3f6a7ce48f Sync repo files to b22 2023-09-20 02:15:22 +08:00
HaHaWTH ed320196fe Remove all files 2023-09-20 02:10:19 +08:00
DGun Otto 62f27f8231 Merge pull request #25 from HaHaWTH/dependabot/maven/org.slf4j-slf4j-simple-2.0.9
Bump org.slf4j:slf4j-simple from 2.0.7 to 2.0.9
2023-09-16 22:51:34 +08:00
dependabot[bot] c3485903c5 Bump org.slf4j:slf4j-simple from 2.0.7 to 2.0.9
Bumps org.slf4j:slf4j-simple from 2.0.7 to 2.0.9.

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-simple
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 04:14:09 +00:00
dependabot[bot] 5f3089b61b Merge pull request #21 from HaHaWTH/dependabot/maven/org.mariadb.jdbc-mariadb-java-client-3.2.0 2023-09-03 10:11:12 +00:00
dependabot[bot] e8f42ab669 Merge pull request #20 from HaHaWTH/dependabot/maven/org.xerial-sqlite-jdbc-3.42.0.1 2023-08-28 12:25:51 +00:00
dependabot[bot] e3ff584bf4 Bump org.mariadb.jdbc:mariadb-java-client from 3.1.4 to 3.2.0
Bumps [org.mariadb.jdbc:mariadb-java-client](https://github.com/mariadb-corporation/mariadb-connector-j) from 3.1.4 to 3.2.0.
- [Release notes](https://github.com/mariadb-corporation/mariadb-connector-j/releases)
- [Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.1.4...3.2.0)

---
updated-dependencies:
- dependency-name: org.mariadb.jdbc:mariadb-java-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 04:23:57 +00:00
dependabot[bot] a9116a2f28 Bump org.xerial:sqlite-jdbc from 3.42.0.0 to 3.42.0.1
Bumps [org.xerial:sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.42.0.0 to 3.42.0.1.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.42.0.0...3.42.0.1)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 04:23:39 +00:00
DGun Otto ddd8c44396 Merge pull request #17 from HaHaWTH/dependabot/maven/net.essentialsx-EssentialsX-2.20.1
Bump net.essentialsx:EssentialsX from 2.20.0 to 2.20.1
2023-08-07 21:09:11 +08:00
dependabot[bot] 6edcfa993e Bump net.essentialsx:EssentialsX from 2.20.0 to 2.20.1
Bumps [net.essentialsx:EssentialsX](https://github.com/EssentialsX/Essentials) from 2.20.0 to 2.20.1.
- [Release notes](https://github.com/EssentialsX/Essentials/releases)
- [Commits](https://github.com/EssentialsX/Essentials/compare/2.20.0...2.20.1)

---
updated-dependencies:
- dependency-name: net.essentialsx:EssentialsX
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-07 04:56:34 +00:00
dependabot[bot] e63764e2cf Merge pull request #16 from HaHaWTH/dependabot/maven/org.checkerframework-checker-qual-3.37.0 2023-08-03 17:42:49 +00:00
dependabot[bot] 63540088c9 Bump org.checkerframework:checker-qual from 3.36.0 to 3.37.0
Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.36.0 to 3.37.0.
- [Release notes](https://github.com/typetools/checker-framework/releases)
- [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.36.0...checker-framework-3.37.0)

---
updated-dependencies:
- dependency-name: org.checkerframework:checker-qual
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-02 04:45:13 +00:00
dependabot[bot] 8e760e504e Merge pull request #11 from HaHaWTH/dependabot/maven/org.mockito-mockito-core-5.4.0 2023-07-21 15:14:39 +00:00
dependabot[bot] bf3553df68 Merge pull request #12 from HaHaWTH/dependabot/maven/org.checkerframework-checker-qual-3.36.0 2023-07-21 15:14:14 +00:00
dependabot[bot] 44e4937d16 Merge pull request #7 from HaHaWTH/dependabot/maven/org.postgresql-postgresql-42.6.0 2023-07-21 15:13:13 +00:00
dependabot[bot] 280bb2bdcc Merge pull request #9 from HaHaWTH/dependabot/maven/org.slf4j-slf4j-simple-2.0.7 2023-07-19 06:47:48 +00:00
dependabot[bot] c0da109dea Merge pull request #15 from HaHaWTH/dependabot/maven/com.mysql-mysql-connector-j-8.1.0 2023-07-19 06:45:16 +00:00
dependabot[bot] b455d0a200 Bump mysql-connector-j from 8.0.33 to 8.1.0
Bumps [mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.0.33 to 8.1.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.33...8.1.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-19 04:59:36 +00:00
DGun Otto 2f9d11e1d5 Merge pull request #10 from HaHaWTH/dependabot/maven/com.h2database-h2-2.2.220
Bump h2 from 2.1.214 to 2.2.220
2023-07-14 23:38:08 +08:00
DGun Otto ab85429b4c Merge pull request #6 from HaHaWTH/dependabot/maven/org.xerial-sqlite-jdbc-3.42.0.0
Bump sqlite-jdbc from 3.40.1.0 to 3.42.0.0
2023-07-14 23:37:46 +08:00
DGun Otto 145dbd46f0 Merge pull request #8 from HaHaWTH/dependabot/maven/org.mariadb.jdbc-mariadb-java-client-3.1.4
Bump mariadb-java-client from 3.1.2 to 3.1.4
2023-07-14 23:37:35 +08:00
DGun Otto 8e451b0642 Merge pull request #13 from HaHaWTH/dependabot/maven/org.jacoco-jacoco-maven-plugin-0.8.10
Bump jacoco-maven-plugin from 0.8.8 to 0.8.10
2023-07-14 23:37:22 +08:00
DGun Otto b12070a517 Merge pull request #14 from HaHaWTH/dependabot/maven/net.essentialsx-EssentialsX-2.20.0
Bump EssentialsX from 2.19.7 to 2.20.0
2023-07-14 23:37:04 +08:00
dependabot[bot] 3950b3034c Bump EssentialsX from 2.19.7 to 2.20.0
Bumps [EssentialsX](https://github.com/EssentialsX/Essentials) from 2.19.7 to 2.20.0.
- [Release notes](https://github.com/EssentialsX/Essentials/releases)
- [Commits](https://github.com/EssentialsX/Essentials/compare/2.19.7...2.20.0)

---
updated-dependencies:
- dependency-name: net.essentialsx:EssentialsX
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:53:38 +00:00
dependabot[bot] 47ae657c80 Bump jacoco-maven-plugin from 0.8.8 to 0.8.10
Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.8 to 0.8.10.
- [Release notes](https://github.com/jacoco/jacoco/releases)
- [Commits](https://github.com/jacoco/jacoco/compare/v0.8.8...v0.8.10)

---
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>
2023-07-14 13:52:58 +00:00
dependabot[bot] 87ef1ab8ed Bump checker-qual from 3.32.0 to 3.36.0
Bumps [checker-qual](https://github.com/typetools/checker-framework) from 3.32.0 to 3.36.0.
- [Release notes](https://github.com/typetools/checker-framework/releases)
- [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.32.0...checker-framework-3.36.0)

---
updated-dependencies:
- dependency-name: org.checkerframework:checker-qual
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:52:34 +00:00
dependabot[bot] a6bd4f59cb Bump mockito-core from 5.2.0 to 5.4.0
Bumps [mockito-core](https://github.com/mockito/mockito) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v5.2.0...v5.4.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-core
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:52:23 +00:00
dependabot[bot] ac610ad552 Bump h2 from 2.1.214 to 2.2.220
Bumps [h2](https://github.com/h2database/h2database) from 2.1.214 to 2.2.220.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.1.214...version-2.2.220)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:52:02 +00:00
dependabot[bot] d9204afdc9 Bump slf4j-simple from 2.0.5 to 2.0.7
Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 2.0.5 to 2.0.7.
- [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.5...v_2.0.7)

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-simple
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:51:54 +00:00
dependabot[bot] 69abbc308a Bump mariadb-java-client from 3.1.2 to 3.1.4
Bumps [mariadb-java-client](https://github.com/mariadb-corporation/mariadb-connector-j) from 3.1.2 to 3.1.4.
- [Release notes](https://github.com/mariadb-corporation/mariadb-connector-j/releases)
- [Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.1.2...3.1.4)

---
updated-dependencies:
- dependency-name: org.mariadb.jdbc:mariadb-java-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:51:45 +00:00
dependabot[bot] 06f2b0c49e Bump postgresql from 42.5.4 to 42.6.0
Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.5.4 to 42.6.0.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.5.4...REL42.6.0)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:49:44 +00:00
dependabot[bot] 47b0e6e744 Bump sqlite-jdbc from 3.40.1.0 to 3.42.0.0
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.40.1.0 to 3.42.0.0.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.40.1.0...3.42.0.0)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 13:49:34 +00:00
DGun Otto 4533f52016 Merge pull request #5 from HaHaWTH/oscs_fix_cin6hi8au51v1r8mnpgg
请升级com.mysql:mysql-connector-j组件版本以解决1个安全漏洞
2023-07-12 16:54:32 +08:00
HaHaWTH ae36036874 fix vuln 2023-07-12 16:48:23 +08:00
DGun Otto 6f19a5442f Update README.md 2023-07-12 00:40:44 +08:00
DGun Otto 3019e33945 Update README.md 2023-07-12 00:37:53 +08:00
HaHaWTH 7e49e26735 reupload files 2023-07-11 20:45:01 +08:00
HaHaWTH b014da245d Del all files 2023-07-11 20:42:24 +08:00
91 changed files with 911 additions and 384 deletions
-34
View File
@@ -1,34 +0,0 @@
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path
name: Maven Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml
env:
GITHUB_TOKEN: ${{ github.token }}
-1
View File
@@ -21,4 +21,3 @@ jobs:
cache: 'maven'
- name: 使用Maven构建
run: mvn -V -B clean package --file pom.xml
+1 -1
View File
@@ -24,7 +24,7 @@ hs_err_pid*
# Include the project's code style settings file
!.idea/codeStyleSettings.xml
/target/class/
# File-based project format:
*.ipr
*.iws
+3
View File
@@ -0,0 +1,3 @@
# 默认忽略的文件
/shelf/
/workspace.xml
+14 -18
View File
@@ -1,21 +1,17 @@
# AuthMeReReloaded
**"A Fork of Authme that contains many bug fixes!"**
**请前往Releases下载最新版本**(**Download the latest version from Releases**)
**"A fork of the best authentication plugin for the Bukkit modding API!"**
![Graph](https://bstats.org/signatures/bukkit/AuthMeReloaded-Fork.svg)
Changes to the original AuthMe(相较于原版AuthMe的变化):
1.Memory improvement
2.Fixed GeoIP database
3.Hook floodgate
4.Choose the best performance method by server brand
5.Anti ghost player
6.GUI captcha for unregistered players
7.Block unsafe passwords by querying API
8.Self hash check to prevent jar virus infection(abandoned)
9.Updater
**Known Folia issue**
1.If the teleport distance too far away,the player may be frozen
**Detailed Changes:**
1. Improved mail sending logic & support more emails
2. Shutdown mail sending(When server is closed, email you)
3. Old bug fixes
4. Anti Ghost Player(Doubled login bug)
5. Use the best performance method by server brand
6. Bedrock Compatibility(Floodgate needed)
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. More......
-1
View File
@@ -1 +0,0 @@
d91307767d8526ac84a3055ac0e773e91f88d452b4b0031f7ecfed721ac6b641
-1
View File
@@ -1 +0,0 @@
d0aab9856defbd8ef31a9cd7257c5b5761e61a7e39807708c81decf82f599323
-1
View File
@@ -1 +0,0 @@
176a6c6ea03ad8cc37d1d11c3e3608d8b59c09f9f923eae287e8192731642ec8
-1
View File
@@ -1 +0,0 @@
61b1a691490d78af1028a442143f649d432618b92c5a9a7031eb4f94817d768b
-1
View File
@@ -1 +0,0 @@
222eb5ecb4c58f279b8e2f75d38a45495ceb875f249ae3217e3f2a36e50b7d39
-1
View File
@@ -1 +0,0 @@
da53060e21d7135e479a6a6a6fd090b8f41e1423742b94e4dbb1a9230b5621fd
View File
-1
View File
@@ -1 +0,0 @@
423084f2a50c27f62d1b5c85a95e78b9bc3df49d5bd9cefd6fe1aa9227b856c1
-1
View File
@@ -1 +0,0 @@
410df26b12703b82987b9d739c19211346418f1c954d214827805c13b5f82c98
-1
View File
@@ -1 +0,0 @@
20569ebc44a9847da0946de5a3bf2cd2b7855dffb03abc9d29204afcaa64b8bb
-1
View File
@@ -1 +0,0 @@
51a067778ad9b0938d57fd4e2975e0f8dce4914ee060efd0fd6755a8810da4f3
+13 -13
View File
@@ -6,10 +6,10 @@
<groupId>fr.xephi</groupId>
<artifactId>authme</artifactId>
<version>5.6.0-SNAPSHOT</version>
<version>5.6.0-FORK</version>
<name>AuthMeReloaded</name>
<description>The first authentication plugin for the Bukkit API!</description>
<name>AuthMeReReloaded</name>
<description>Fork of the first authentication plugin for the Bukkit API!</description>
<inceptionYear>2013</inceptionYear>
<url>https://github.com/AuthMe/AuthMeReloaded</url>
@@ -67,7 +67,7 @@
<maven.minimumVersion>3.6.3</maven.minimumVersion>
<!-- Dependencies versions -->
<spigot.version>1.19.2-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.20.1-R0.1-SNAPSHOT</spigot.version>
<!-- Versioning properties -->
<project.outputName>AuthMe</project.outputName>
@@ -324,7 +324,7 @@
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.finalNameBase}-legacy</finalName>
<finalName>${project.finalNameBase}-Spigot-Universal</finalName>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
@@ -706,7 +706,7 @@
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.32</version>
<version>8.0.33</version>
<optional>true</optional>
</dependency>
<dependency>
@@ -757,7 +757,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
<version>31.1-jre</version>
<optional>true</optional>
<exclusions>
<exclusion>
@@ -770,7 +770,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
<version>2.10.1</version>
<optional>true</optional>
</dependency>
@@ -780,7 +780,7 @@
<dependency>
<groupId>ch.jalu</groupId>
<artifactId>configme</artifactId>
<version>1.3.0</version>
<version>1.3.1</version>
<optional>true</optional>
<exclusions>
<exclusion>
@@ -794,7 +794,7 @@
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.0</version>
<version>3.0.1</version>
<optional>true</optional>
</dependency>
@@ -802,7 +802,7 @@
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>4.8.0</version>
<version>5.1.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -945,7 +945,7 @@
<dependency>
<groupId>net.essentialsx</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.19.7</version>
<version>2.20.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -1068,7 +1068,7 @@
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.39.3.0</version>
<version>3.40.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
+186 -16
View File
@@ -9,6 +9,11 @@ import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.DataSourceProvider;
import fr.xephi.authme.initialization.OnShutdownPlayerSaver;
import fr.xephi.authme.initialization.OnStartupTasks;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import fr.xephi.authme.initialization.SettingsProvider;
import fr.xephi.authme.initialization.TaskCloser;
import fr.xephi.authme.listener.BlockListener;
@@ -17,6 +22,8 @@ import fr.xephi.authme.listener.PlayerListener;
import fr.xephi.authme.listener.PlayerListener111;
import fr.xephi.authme.listener.PlayerListener19;
import fr.xephi.authme.listener.PlayerListener19Spigot;
import fr.xephi.authme.listener.DoubleLoginFixListener;
import fr.xephi.authme.listener.GuiCaptchaHandler;
import fr.xephi.authme.listener.ServerListener;
import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.output.ConsoleLoggerFactory;
@@ -33,19 +40,23 @@ import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.task.CleanupTask;
import fr.xephi.authme.task.purge.PurgeService;
import fr.xephi.authme.util.ExceptionUtils;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import javax.inject.Inject;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.Scanner;
import java.util.function.Consumer;
import java.util.logging.Level;
import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE;
import static fr.xephi.authme.util.Utils.isClassLoaded;
@@ -61,25 +72,27 @@ public class AuthMe extends JavaPlugin {
private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE;
// Version and build number values
private static String pluginVersion = "5.6.0";
private static String pluginBuildNumber = "Custom";
private static String pluginVersion = "5.6.0-Fork";
private static final String pluginBuild = "b";
private static String pluginBuildNumber = "23";
protected final Boolean SHAEnabled = false;
// Private instances
private EmailService emailService;
private CommandHandler commandHandler;
private Settings settings;
@Inject
public static Settings settings;
private DataSource database;
private BukkitService bukkitService;
private Injector injector;
private BackupService backupService;
private ConsoleLogger logger;
public static ConsoleLogger logger;
/**
* Constructor.
*/
public AuthMe() {
}
/**
* Get the plugin's name.
*
@@ -107,6 +120,7 @@ public class AuthMe extends JavaPlugin {
return pluginBuildNumber;
}
/**
* Method called when the server enables the plugin.
*/
@@ -118,6 +132,8 @@ public class AuthMe extends JavaPlugin {
// Set the Logger instance and log file path
ConsoleLogger.initialize(getLogger(), new File(getDataFolder(), LOG_FILENAME));
logger = ConsoleLoggerFactory.get(AuthMe.class);
logger.info("You are running an unofficial fork version of AuthMe!");
// Check server version
if (!isClassLoaded("org.spigotmc.event.player.PlayerSpawnLocationEvent")
@@ -146,7 +162,7 @@ public class AuthMe extends JavaPlugin {
th.printStackTrace();
} else {
logger.logException("File '" + yamlParseException.getFile() + "' contains invalid YAML. "
+ "Please run its contents through https://yamllint.com", yamlParseException);
+ "Please run its contents through http://yamllint.com", yamlParseException);
}
stopOrUnload();
return;
@@ -158,26 +174,65 @@ public class AuthMe extends JavaPlugin {
// Schedule clean up task
CleanupTask cleanupTask = injector.getSingleton(CleanupTask.class);
cleanupTask.runTaskTimerAsynchronously(this, CLEANUP_INTERVAL, CLEANUP_INTERVAL);
// Do a backup on start
backupService.doBackup(BackupService.BackupCause.START);
// Set up Metrics
OnStartupTasks.sendMetrics(this, settings);
if(settings.getProperty(SecuritySettings.SHOW_STARTUP_BANNER)) {
String loadColorConfig = settings.getProperty(SecuritySettings.STARTUP_BANNER_COLOR);
if (loadColorConfig.startsWith("§")) {
logger.info("\n" + loadColorConfig + " ___ __ __ __ ___ \n" +
loadColorConfig + " / | __ __/ /_/ /_ / |/ /__ \n" +
loadColorConfig + " / /| |/ / / / __/ __ \\/ /|_/ / _ \\\n" +
loadColorConfig + " / ___ / /_/ / /_/ / / / / / / __/\n" +
loadColorConfig + "/_/ |_\\__,_/\\__/_/ /_/_/ /_/\\___/ \n" +
loadColorConfig + " ");
}else {
logger.info("\n"+" ___ __ __ __ ___ \n" +
" / | __ __/ /_/ /_ / |/ /__ \n" +
" / /| |/ / / / __/ __ \\/ /|_/ / _ \\\n" +
" / ___ / /_/ / /_/ / / / / / / __/\n" +
"/_/ |_\\__,_/\\__/_/ /_/_/ /_/\\___/ \n" +
" ");
}
}
// Successful message
logger.info("AuthMeReloaded successfully enabled!");
//detect server brand with classloader
checkServerType();
logger.info("AuthMeReReloaded is enabled successfully!");
// Purge on start if enabled
PurgeService purgeService = injector.getSingleton(PurgeService.class);
purgeService.runAutoPurge();
}
// 注册玩家加入事件监听
// if (settings.getProperty(SecuritySettings.ANTI_GHOST_PLAYERS) || settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)/* || settings.getProperty(SecuritySettings.GUI_CAPTCHA)*/) {
if (settings.getProperty(SecuritySettings.ANTI_GHOST_PLAYERS)) {
getServer().getPluginManager().registerEvents(new DoubleLoginFixListener((Plugin) this), this);
}
if (settings.getProperty(SecuritySettings.GUI_CAPTCHA) && getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
getServer().getPluginManager().registerEvents(new GuiCaptchaHandler((Plugin) this), this);
logger.info("(Alpha4)GUICaptcha Feature is enabled successfully!");
logger.info("These features are still in development, if you encountered any problem, please report.");
} else if (settings.getProperty(SecuritySettings.GUI_CAPTCHA) && !getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
logger.warning("ProtocolLib is not loaded, we can't enable GUI Captcha.");
}
logger.info("GitHub: https://github.com/HaHaWTH/AuthMeReReloaded/");
if (settings.getProperty(SecuritySettings.CHECK_FOR_UPDATES)) {
checkForUpdates();
}
if (SHAEnabled){
//shaChecker();
}
}
public File pluginfile = getFile();
/**
* Load the version and build number of the plugin from the description file.
*
* @param versionRaw the version as given by the plugin description file
*/
private static void loadPluginInfo(String versionRaw) {
int index = versionRaw.lastIndexOf("-");
if (index != -1) {
@@ -305,7 +360,7 @@ public class AuthMe extends JavaPlugin {
onShutdownPlayerSaver.saveAllPlayers();
}
if (settings.getProperty(EmailSettings.SHUTDOWN_MAIL)){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy''MM''dd'' HH:mm:ss");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'.'MM'.'dd'.' HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
emailService.sendShutDown(settings.getProperty(EmailSettings.SHUTDOWN_MAIL_ADDRESS),dateFormat.format(date));
}
@@ -320,9 +375,124 @@ public class AuthMe extends JavaPlugin {
// Disabled correctly
Consumer<String> infoLogMethod = logger == null ? getLogger()::info : logger::info;
infoLogMethod.accept("AuthMe " + this.getDescription().getVersion() + " disabled!");
infoLogMethod.accept("AuthMe " + this.getDescription().getVersion() + " is unloaded successfully!");
ConsoleLogger.closeFileWriter();
}
private static final String owner = "HaHaWTH";
private static final String owner_gitee = "Shixuehan114514";
private static final String repo = "AuthMeReReloaded";
private void checkForUpdates() {
logger.info("Checking for updates...");
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
try {
// 从南通集线器获取最新版本号
URL url = new URL("https://api.github.com/repos/" + owner + "/" + repo + "/releases/latest");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000); // 设置连接超时为10秒
conn.setReadTimeout(10000); // 设置读取超时为10秒
Scanner scanner = new Scanner(conn.getInputStream());
String response = scanner.useDelimiter("\\Z").next();
scanner.close();
// 处理JSON响应
String latestVersion = response.substring(response.indexOf("tag_name") + 11);
latestVersion = latestVersion.substring(0, latestVersion.indexOf("\""));
if ((pluginBuild + pluginBuildNumber).equals(latestVersion)) {
getLogger().log(Level.INFO,"You are running the latest version.");
}
if (!(pluginBuild + pluginBuildNumber).equals(latestVersion)) {
// Display update message
String message = "New version available! Latest:" + latestVersion + " Current:" + pluginBuild + pluginBuildNumber;
getLogger().log(Level.INFO, message);
getLogger().log(Level.INFO,"Download from here:github.com/HaHaWTH/AuthMeReReloaded/releases/latest");
}
}catch (IOException e) {
getLogger().log(Level.WARNING,"Error occurred while checking updates from GitHub. Reason: " + e.getMessage());
}
});
}
private void checkServerType() {
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");
} else if (isClassLoaded("org.spigotmc.SpigotConfig")) {
logger.info("AuthMeReReloaded is running on Spigot");
} else if (isClassLoaded("org.bukkit.craftbukkit.CraftServer")) {
logger.info("AuthMeReReloaded is running on Bukkit");
} else {
logger.info("AuthMeReReloaded is running on Unknown*");
}
}
// 其他方法和事件处理
// 其他方法和事件处理
private static final String SHA_URL = "https://raw.githubusercontent.com/"+ owner +"/"+ repo + "/master/"+pluginBuild +pluginBuildNumber+ ".sha";
private static final String ALGORITHM = "SHA-256";
private static final String PROXY_URL = "https://ghproxy.com/";
private static final String SHA_URL_GITEE = "https://gitee.com/"+ owner_gitee +"/"+ repo + "/raw/master/"+pluginBuild+pluginBuildNumber+ ".sha";
// public void shaChecker() {
// // 请求SHA文件
//
// String actualSha;
// try {
// URL url;
// if(settings.getProperty(SecuritySettings.SHA_CHECK_METHOD).equals("github")) {
// url = new URL(SHA_URL);
// logger.info("正在检查文件完整性...(GitHub)");
// } else if(settings.getProperty(SecuritySettings.SHA_CHECK_METHOD).equals("ghproxy")) {
// url = new URL(PROXY_URL + SHA_URL);
// logger.info("正在检查文件完整性...(GhProxy)");
// } else if (settings.getProperty(SecuritySettings.SHA_CHECK_METHOD).equals("gitee")) {
// url = new URL(SHA_URL_GITEE);
// logger.info("正在检查文件完整性...(Gitee)");
// }else {
// logger.warning("未知的SHA检查方法,将从GitHub获取SHA文件");
// url = new URL(SHA_URL);
// }
//
//
// HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// conn.setConnectTimeout(10000);
// conn.setReadTimeout(9000);
// conn.setRequestMethod("GET");
// InputStream stream = conn.getInputStream();
// ByteArrayOutputStream result = new ByteArrayOutputStream();
// byte[] buffer = new byte[1024];
// int length;
// while ((length = stream.read(buffer)) != -1) {
// result.write(buffer, 0, length);
// }
// String expectedSha = result.toString().trim();
// // 计算插件文件的SHA值
// MessageDigest md = MessageDigest.getInstance(ALGORITHM);
// byte[] fileBytes = Files.readAllBytes(pluginfile.toPath());
// byte[] hashBytes = md.digest(fileBytes);
// StringBuilder sb = new StringBuilder();
// for (byte b : hashBytes) {
// sb.append(String.format("%02x", b));
// }
// actualSha = sb.toString();
//
// // 比较SHA值并加载插件
// if (expectedSha.equals(actualSha)) {
// logger.info("SHA联网安全校验完毕");
// } else {
// // SHA值不匹配,插件可能被篡改
// logger.warning("SHA值不匹配,插件被篡改");
// stopOrUnload();
// }
// }catch (NoSuchAlgorithmException | IOException e){
// logger.warning("SHA校验失败,请尝试切换校验API");
// logger.warning("您当前请求的API为:" + settings.getProperty(SecuritySettings.SHA_CHECK_METHOD));
// stopOrUnload();
// }
// }
/**
* Handle Bukkit commands.
@@ -142,7 +142,7 @@ public final class ConsoleLogger {
public void fine(String message) {
if (logLevel.includes(LogLevel.FINE)) {
logger.info(message);
writeLog("[FINE] " + message);
writeLog("[INFO:FINE] " + message);
}
}
@@ -215,7 +215,7 @@ public final class ConsoleLogger {
}
private void logAndWriteWithDebugPrefix(String message) {
String debugMessage = "[DEBUG] " + message;
String debugMessage = "[INFO:DEBUG] " + message;
logger.info(debugMessage);
writeLog(debugMessage);
}
@@ -29,7 +29,6 @@ import fr.xephi.authme.command.executable.authme.TotpViewStatusCommand;
import fr.xephi.authme.command.executable.authme.UnregisterAdminCommand;
import fr.xephi.authme.command.executable.authme.UpdateHelpMessagesCommand;
import fr.xephi.authme.command.executable.authme.VersionCommand;
import fr.xephi.authme.command.executable.authme.WhitelistCommand;
import fr.xephi.authme.command.executable.authme.debug.DebugCommand;
import fr.xephi.authme.command.executable.captcha.CaptchaCommand;
import fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand;
@@ -421,16 +420,6 @@ public class CommandInitializer {
.executableCommand(SwitchAntiBotCommand.class)
.register();
CommandDescription.builder()
.parent(authmeBase)
.labels("whitelist")
.description("Switch whitelist mode")
.detailedDescription("Switch or toggle the whitelist mode to the specified state.")
.withArgument("mode", "ON / OFF", OPTIONAL)
.permission(AdminPermission.SWITCH_ANTIBOT)
.executableCommand(WhitelistCommand.class)
.register();
// Register the reload command
CommandDescription.builder()
.parent(authmeBase)
@@ -17,9 +17,9 @@ public abstract class PlayerCommand implements ExecutableCommand {
} else {
String alternative = getAlternativeCommand();
if (alternative != null) {
sender.sendMessage("Player only! Please use " + alternative + " instead.");
sender.sendMessage("此命令仅限玩家使用!请使用 " + alternative + " .");
} else {
sender.sendMessage("This command is only for players.");
sender.sendMessage("此命令只能被玩家执行.");
}
}
}
@@ -1,9 +1,13 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.TeleportUtils;
import org.bukkit.entity.Player;
import fr.xephi.authme.AuthMe;
import javax.inject.Inject;
import java.util.List;
@@ -11,16 +15,22 @@ import java.util.List;
* Teleports the player to the first spawn.
*/
public class FirstSpawnCommand extends PlayerCommand {
@Inject
private Settings settings;
@Inject
private SpawnLoader spawnLoader;
@Override
public void runCommand(Player player, List<String> arguments) {
if (spawnLoader.getFirstSpawn() == null) {
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
} else {
player.teleport(spawnLoader.getFirstSpawn());
//String name= player.getName();
if(settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
TeleportUtils.teleport(player, spawnLoader.getFirstSpawn());
} else {
player.teleport(spawnLoader.getFirstSpawn());
}
//player.teleport(spawnLoader.getFirstSpawn());
}
}
}
@@ -1,40 +0,0 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.service.WhiteListService;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
* Display or change the status of the antibot mod.
*/
public class WhitelistCommand implements ExecutableCommand {
@Inject
private WhiteListService whiteListService;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments) {
if (arguments.isEmpty()) {
sender.sendMessage("[AuthMe] WhiteList: " + whiteListService.getWhiteListStatus().name());
return;
}
String newState = arguments.get(0);
// Enable or disable the mod
if ("ON".equalsIgnoreCase(newState)) {
whiteListService.overrideWhiteListStatus(true);
sender.sendMessage("[AuthMe] WhiteList enabled!");
} else if ("OFF".equalsIgnoreCase(newState)) {
sender.sendMessage("[AuthMe] WhiteList disabled!");
whiteListService.overrideWhiteListStatus(false);
} else {
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/authme help whitelist");
}
}
}
@@ -42,6 +42,12 @@ public class ChangePasswordCommand extends PlayerCommand {
commonService.send(player, MessageKey.NOT_LOGGED_IN);
return;
}
// Check if the user has been verified or not
if (codeManager.isVerificationRequired(player)) {
codeManager.codeExistOrGenerateNew(name);
commonService.send(player, MessageKey.VERIFICATION_CODE_REQUIRED);
return;
}
String oldPassword = arguments.get(0);
String newPassword = arguments.get(1);
@@ -70,7 +70,7 @@ public class TotpCodeCommand extends PlayerCommand {
boolean isCodeValid = totpAuthenticator.checkCode(auth, inputCode);
if (isCodeValid) {
logger.debug("Successfully checked TOTP code for `{0}`", player.getName());
asynchronousLogin.performLogin(player, auth,false);
asynchronousLogin.performLogin(player, auth);
} else {
logger.debug("Input TOTP code was invalid for player `{0}`", player.getName());
messages.send(player, MessageKey.TWO_FACTOR_INVALID_CODE);
@@ -53,7 +53,7 @@ public class OnStartupTasks {
* @param settings the settings
*/
public static void sendMetrics(AuthMe plugin, Settings settings) {
final Metrics metrics = new Metrics(plugin, 164);
final Metrics metrics = new Metrics(plugin, 18479);
metrics.addCustomChart(new SimplePie("messages_language",
() -> settings.getProperty(PluginSettings.MESSAGES_LANGUAGE)));
@@ -0,0 +1,35 @@
package fr.xephi.authme.listener;
//Prevent Ghost Players
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
import java.util.Collection;
import java.util.HashSet;
public class DoubleLoginFixListener implements Listener {
private final Plugin plugin;
public DoubleLoginFixListener(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Collection<? extends Player> PlayerList = Bukkit.getServer().getOnlinePlayers();
HashSet<String> PlayerSet = new HashSet<String>();
for (Player ep : PlayerList) {
if (PlayerSet.contains(ep.getName().toLowerCase())) {
ep.kickPlayer("You have been disconnected due to doubled login.");
break;
}
PlayerSet.add(ep.getName().toLowerCase());
}
}
}
@@ -0,0 +1,253 @@
package fr.xephi.authme.listener;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import static org.bukkit.Bukkit.getLogger;
import static org.bukkit.Bukkit.getServer;
public class GuiCaptchaHandler implements Listener {
//define AuthMeApi
private final AuthMeApi authmeApi = AuthMeApi.getInstance();
private final Plugin plugin;
//define timesLeft
public int timesLeft = 3;
//Use ConcurrentHashMap to store player and their close reason
/* We used many async tasks so there is concurrent**/
protected static ConcurrentHashMap<Player, String> closeReasonMap = new ConcurrentHashMap<>();
//define randomStringSet
String randomSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz!@#%&*()_+";
String randomString = "";
Random randomItemSet = new Random();
Random howManyRandom = new Random();
int howLongIsRandomString = (howManyRandom.nextInt(3) + 1);
public GuiCaptchaHandler(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (event.getWhoClicked() instanceof Player) {
Player player = (Player) event.getWhoClicked();
// 获取点击事件的容器
if (!authmeApi.isRegistered(player.getName()) && !closeReasonMap.containsKey(player)) {
if (AuthMe.settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_BE_COMPATIBILITY) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(event.getWhoClicked().getUniqueId()) && (getServer().getPluginManager().isPluginEnabled("floodgate") || getServer().getPluginManager().getPlugin("floodgate") != null)) {
if (!closeReasonMap.containsKey(player)) {
closeReasonMap.put(player,"verified");
return;
}
return;
}
if (Objects.requireNonNull(event.getCurrentItem()).getType().equals(Material.REDSTONE_BLOCK)) {
event.setCancelled(true);
closeReasonMap.put(player, "verified");
player.closeInventory();
player.sendMessage("§a验证完成");
} else {
player.sendMessage("§c验证失败,你还有" + timesLeft + "§c次机会");
timesLeft--;
}
//force to string
}
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerJoin(PlayerJoinEvent event) {
randomString = "";
Player playerunreg = event.getPlayer();
String name = playerunreg.getName();
if (!authmeApi.isRegistered(name)) {
if (AuthMe.settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_BE_COMPATIBILITY) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(event.getPlayer().getUniqueId()) && (getServer().getPluginManager().isPluginEnabled("floodgate") || getServer().getPluginManager().getPlugin("floodgate") != null)) {
closeReasonMap.put(playerunreg, "verified");
playerunreg.sendMessage("§a基岩版自动验证完成");
return;
}
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
StringBuilder sb = new StringBuilder();
howLongIsRandomString = (howManyRandom.nextInt(3) + 1);
for (int i = 0; i < howLongIsRandomString; i++) {
//生成随机索引号
int index = randomItemSet.nextInt(randomSet.length());
// 从字符串中获取由索引 index 指定的字符
char randomChar = randomSet.charAt(index);
// 将字符追加到字符串生成器
sb.append(randomChar);
}
Bukkit.getScheduler().runTask(this.plugin, () -> {
randomString = sb.toString();
Random random_blockpos = new Random();
AtomicInteger random_num = new AtomicInteger(random_blockpos.nextInt(26));
Inventory menu = Bukkit.createInventory(null, 27, randomString + "请验证你是真人");
ItemStack item = new ItemStack(Material.REDSTONE_BLOCK);
ItemMeta meta = item.getItemMeta();
try {
if (meta != null) {
meta.setDisplayName("§a我是真人");
item.setItemMeta(meta);
}
} catch (NullPointerException e) {
getLogger().log(Level.WARNING, "Unexpected error occurred while setting item meta.");
}
Bukkit.getScheduler().runTask(this.plugin, () -> {
menu.setItem(random_num.get(), item);
});
menu.setItem(random_num.get(), item);
Bukkit.getScheduler().runTask(this.plugin, () -> {
playerunreg.openInventory(menu);
});
if (AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT) > 0) {
long timeOut = AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT);
if (AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT) > AuthMe.settings.getProperty(RestrictionSettings.TIMEOUT)) {
Bukkit.getScheduler().runTask(this.plugin, () -> {
Bukkit.getLogger().warning("AuthMe detected that your GUI captcha timeout seconds(" + AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA_TIMEOUT) + ") is bigger than the Login timeout seconds(" +
AuthMe.settings.getProperty(RestrictionSettings.TIMEOUT) + "). To prevent issues, we will let the GUI captcha follow the Login timeout seconds, please check and modify your config.");
});
timeOut = AuthMe.settings.getProperty(RestrictionSettings.TIMEOUT);
}
long finalTimeOut = timeOut;
Bukkit.getScheduler().runTask(this.plugin, () -> {
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {
if (!closeReasonMap.containsKey(playerunreg) && !authmeApi.isRegistered(playerunreg.getName())) {
playerunreg.kickPlayer("§c验证超时");
timesLeft = 3; // Reset the attempt counter
}
}, finalTimeOut * 20L);
});
}
Bukkit.getScheduler().runTask(this.plugin, () -> {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this.plugin, ListenerPriority.HIGHEST, PacketType.Play.Client.CLOSE_WINDOW) {
@Override
public void onPacketReceiving(PacketEvent event) {
if (event.getPlayer() == playerunreg && !closeReasonMap.containsKey(playerunreg) && !authmeApi.isRegistered(playerunreg.getName())) {
if (timesLeft <= 0) {
Bukkit.getScheduler().runTask(this.plugin, () -> {
playerunreg.kickPlayer("§c请先完成人机验证!");
});
timesLeft = 3;
return;
} else {
timesLeft--;
playerunreg.sendMessage("§c请先完成验证!,你还有" + timesLeft + "次机会");
}
event.setCancelled(true);
random_num.set(random_blockpos.nextInt(26));
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
Bukkit.getScheduler().runTask(plugin, () -> {
menu.clear();
menu.setItem(random_num.get(), item);
});
Bukkit.getScheduler().runTask(plugin, () -> {
playerunreg.openInventory(menu);
});
});
}
}
});
});
Bukkit.getScheduler().runTask(this.plugin, () -> {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this.plugin, ListenerPriority.HIGHEST, PacketType.Play.Client.CHAT) {
@Override
public void onPacketReceiving(PacketEvent event) {
if (event.getPlayer() == playerunreg && !closeReasonMap.containsKey(playerunreg) && !authmeApi.isRegistered(playerunreg.getName())) {
playerunreg.sendMessage("§c请先完成验证!");
event.setCancelled(true);
}
}
});
});
});
});
}
}
private void deletePlayerData(UUID playerUUID) {
// 获取服务器的存储文件夹路径
File serverFolder = Bukkit.getServer().getWorldContainer();
String worldFolderName = AuthMe.settings.getProperty(SecuritySettings.DELETE_PLAYER_DATA_WORLD);
// 构建playerdata文件夹路径
File playerDataFolder = new File(serverFolder, File.separator+worldFolderName+File.separator+"playerdata");
// 构建玩家数据文件路径
File playerDataFile = new File(playerDataFolder, File.separator+playerUUID + ".dat");
// 删除玩家数据文件
if (playerDataFile.exists()) {
playerDataFile.delete();
}
}
private void deletePlayerStats(UUID playerUUID) {
// 获取服务器的存储文件夹路径
File serverFolder = Bukkit.getServer().getWorldContainer();
String worldFolderName = AuthMe.settings.getProperty(SecuritySettings.DELETE_PLAYER_DATA_WORLD);
// 构建stats文件夹路径
File statsFolder = new File(serverFolder, File.separator+worldFolderName+File.separator+"stats");
// 构建玩家统计数据文件路径
File statsFile = new File(statsFolder, File.separator+playerUUID + ".json");
// 删除玩家统计数据文件
if (statsFile.exists()) {
statsFile.delete();
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
String name = player.getName();
UUID playerUUID = event.getPlayer().getUniqueId();
if (!authmeApi.isRegistered(name)) {
if(AuthMe.settings.getProperty(SecuritySettings.DELETE_UNVERIFIED_PLAYER_DATA) && !closeReasonMap.containsKey(player)){
Bukkit.getScheduler().runTaskLater(this.plugin,() -> {
deletePlayerData(playerUUID);
deletePlayerStats(playerUUID);
},100L);
return;
}
closeReasonMap.remove(player);
}
}
}
@@ -1,11 +1,14 @@
package fr.xephi.authme.listener;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -18,13 +21,13 @@ import javax.inject.Inject;
* Service class for the AuthMe listeners to determine whether an event should be canceled.
*/
class ListenerService implements SettingsDependent {
private final AuthMeApi authmeApi = AuthMeApi.getInstance();
private final DataSource dataSource;
private final PlayerCache playerCache;
private final ValidationService validationService;
private boolean isRegistrationForced;
@Inject
ListenerService(Settings settings, DataSource dataSource, PlayerCache playerCache,
ValidationService validationService) {
@@ -76,9 +79,18 @@ class ListenerService implements SettingsDependent {
* @param player the player to verify
* @return true if the associated event should be canceled, false otherwise
*/
public boolean shouldCancelEvent(Player player) {
return player != null && !checkAuth(player.getName()) && !PlayerUtils.isNpc(player);
}
public boolean shouldCancelInvEvent(Player player) {
try {
return !AuthMe.settings.getProperty(SecuritySettings.GUI_CAPTCHA) || authmeApi.isRegistered(player.getName()) || GuiCaptchaHandler.closeReasonMap.containsKey(player)/* || !player.getOpenInventory().getTitle().equals("请验证你是真人")*/;
} catch (Exception e) {
return true;
}
}
@Override
public void reload(Settings settings) {
@@ -93,7 +105,7 @@ class ListenerService implements SettingsDependent {
* @return true if the player may play, false otherwise
*/
private boolean checkAuth(String name) {
if (validationService.isUnrestricted(name) || playerCache.isAuthenticated(name)) {
if (validationService.isUnrestricted(name) || playerCache.isAuthenticated(name)){
return true;
}
if (!isRegistrationForced && !dataSource.isAuthAvailable(name)) {
@@ -7,13 +7,11 @@ import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.service.AntiBotService;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.service.WhiteListService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
@@ -48,8 +46,6 @@ public class OnJoinVerifier implements Reloadable {
@Inject
private AntiBotService antiBotService;
@Inject
private WhiteListService whiteListService;
@Inject
private ValidationService validationService;
@Inject
private BukkitService bukkitService;
@@ -85,18 +81,6 @@ public class OnJoinVerifier implements Reloadable {
throw new FailedVerificationException(MessageKey.KICK_ANTIBOT);
}
}
public void checkWhitelist(String name, boolean isAuthAvailable) throws FailedVerificationException {
if (isAuthAvailable || permissionsManager.hasPermissionOffline(name, PlayerStatePermission.WHITELIST)) {
return;
} else {
bukkitService.getOnlinePlayers().stream()
.filter(player -> permissionsManager.hasPermission(player, AdminPermission.WHITELIST_MESSAGE))
.forEach(player -> messages.send(player, MessageKey.WHITELIST_KICK, name));
}
if (whiteListService.shouldKick()) {
throw new FailedVerificationException(MessageKey.KICK_WHITELIST);
}
}
/**
* Checks whether non-registered players should be kicked, and if so, whether the player should be kicked.
@@ -1,5 +1,7 @@
package fr.xephi.authme.listener;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.data.QuickCommandsProtectionManager;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
@@ -18,6 +20,8 @@ import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.TeleportUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@@ -53,6 +57,8 @@ import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import org.bukkit.inventory.InventoryView;
import static org.bukkit.Bukkit.getServer;
import javax.inject.Inject;
import java.util.Locale;
import java.util.Set;
@@ -63,7 +69,11 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAU
/**
* Listener class for player events.
*/
public class PlayerListener implements Listener {
public class PlayerListener implements Listener{
private final AuthMeApi authmeApi = AuthMeApi.getInstance();
@Inject
private Settings settings;
@@ -93,9 +103,12 @@ public class PlayerListener implements Listener {
private PermissionsManager permissionsManager;
@Inject
private QuickCommandsProtectionManager quickCommandsProtectionManager;
// Lowest priority to apply fast protection checks
@EventHandler(priority = EventPriority.LOWEST)
public void onAsyncPlayerPreLoginEventLowest(AsyncPlayerPreLoginEvent event) {
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
return;
}
@@ -111,9 +124,10 @@ public class PlayerListener implements Listener {
if (validationService.isUnrestricted(name)) {
return;
}
if (settings.getProperty(RestrictionSettings.HOOK_FLOODGATE_PLAYER) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(event.getUniqueId())){
return;
if (settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER)) {
if (getServer().getPluginManager().getPlugin("floodgate") != null) {
if (org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(event.getUniqueId())) return;
}
}
// Non-blocking checks
try {
@@ -121,8 +135,8 @@ public class PlayerListener implements Listener {
} catch (FailedVerificationException e) {
event.setKickMessage(messages.retrieveSingle(name, e.getReason(), e.getArgs()));
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
}
}
}
/*
@@ -148,7 +162,6 @@ public class PlayerListener implements Listener {
final PlayerAuth auth = dataSource.getAuth(name);
final boolean isAuthAvailable = auth != null;
onJoinVerifier.checkKickNonRegistered(isAuthAvailable);
onJoinVerifier.checkWhitelist(name, isAuthAvailable);
onJoinVerifier.checkAntibot(name, isAuthAvailable);
onJoinVerifier.checkNameCasing(name, auth);
final String ip = event.getAddress().getHostAddress();
@@ -185,7 +198,7 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerJoin(PlayerJoinEvent event) {
final Player player = event.getPlayer();
final AuthMeApi authmeApi = AuthMeApi.getInstance();
if (!PlayerListener19Spigot.isPlayerSpawnLocationEventCalled()) {
teleportationService.teleportOnJoin(player);
}
@@ -195,12 +208,15 @@ public class PlayerListener implements Listener {
management.performJoin(player);
teleportationService.teleportNewPlayerToFirstSpawn(player);
}
@EventHandler(priority = EventPriority.HIGH) // HIGH as EssentialsX listens at HIGHEST
public void onJoinMessage(PlayerJoinEvent event) {
final Player player = event.getPlayer();
// Note: join message can be null, despite api documentation says not
if (settings.getProperty(RegistrationSettings.REMOVE_JOIN_MESSAGE)) {
event.setJoinMessage(null);
@@ -335,12 +351,12 @@ public class PlayerListener implements Listener {
}
/*
* Limit player X and Z movements to 1 block
* Limit player X and Z movements
* Deny player Y+ movements (allows falling)
*/
if (from.getBlockX() == to.getBlockX()
&& from.getBlockZ() == to.getBlockZ()
if (from.getX() == to.getX()
&& from.getZ() == to.getZ()
&& from.getY() - to.getY() >= 0) {
return;
}
@@ -363,9 +379,17 @@ public class PlayerListener implements Listener {
Location spawn = spawnLoader.getSpawnLocation(player);
if (spawn != null && spawn.getWorld() != null) {
if (!player.getWorld().equals(spawn.getWorld())) {
player.teleport(spawn);
if(settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
TeleportUtils.teleport(player,spawn);
} else {
player.teleport(spawn);
}
} else if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) {
player.teleport(spawn);
if(settings.getProperty(SecuritySettings.SMART_ASYNC_TELEPORT)) {
TeleportUtils.teleport(player,spawn);
} else {
player.teleport(spawn);
}
}
}
}
@@ -489,15 +513,16 @@ public class PlayerListener implements Listener {
return false;
}
Set<String> whitelist = settings.getProperty(RestrictionSettings.UNRESTRICTED_INVENTORIES);
//append a string for String whitelist
return whitelist.contains(ChatColor.stripColor(inventory.getTitle()).toLowerCase(Locale.ROOT));
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
final HumanEntity player = event.getPlayer();
Player ply = (Player) event.getPlayer();
if (listenerService.shouldCancelEvent(player)
&& !isInventoryWhitelisted(event.getView())) {
&& !isInventoryWhitelisted(event.getView()) && listenerService.shouldCancelInvEvent(ply)) {
event.setCancelled(true);
/*
@@ -114,10 +114,6 @@ class InventoryPacketAdapter extends PacketAdapter {
itemListModifier.write(0, Arrays.asList(blankInventory));
}
try {
protocolManager.sendServerPacket(player, inventoryPacket, false);
} catch (InvocationTargetException invocationExc) {
logger.logException("Error during sending blank inventory", invocationExc);
}
protocolManager.sendServerPacket(player, inventoryPacket, false);
}
}
@@ -4,7 +4,6 @@ package fr.xephi.authme.message;
* Keys for translatable messages managed by {@link Messages}.
*/
public enum MessageKey {
/** In order to use this command you must be authenticated! */
DENIED_COMMAND("error.denied_command"),
@@ -16,9 +15,6 @@ public enum MessageKey {
/** AntiBot protection mode is enabled! You have to wait some minutes before joining the server. */
KICK_ANTIBOT("antibot.kick_antibot"),
KICK_WHITELIST("on_join_validation.kick_whitelist"),
WHITELIST_ENABLED_MESSAGE("misc.whitelist_enabled"),
WHITELIST_DISABLED_MESSAGE("misc.whitelist_disabled"),
/** This user isn't registered! */
UNKNOWN_USER("error.unregistered_user"),
@@ -38,6 +34,9 @@ public enum MessageKey {
/** In-game registration is disabled! */
REGISTRATION_DISABLED("registration.disabled"),
/** Logged-in due to Session Reconnection. */
SESSION_RECONNECTION("session.valid_session"),
/** Successful login! */
LOGIN_SUCCESS("login.success"),
@@ -80,6 +79,9 @@ public enum MessageKey {
/** The chosen password isn't safe, please choose another one... */
PASSWORD_UNSAFE_ERROR("password.unsafe_password"),
/** Your chosen password is not secure. It was used %pwned_count times already! Please use a stronger password... */
PASSWORD_PWNED_ERROR("password.pwned_password", "%pwned_count"),
/** Your password contains illegal characters. Allowed chars: %valid_chars */
PASSWORD_CHARACTERS_ERROR("password.forbidden_characters", "%valid_chars"),
@@ -199,7 +201,6 @@ public enum MessageKey {
/** [AntiBotService] AntiBot disabled after %m minutes! */
ANTIBOT_AUTO_DISABLED_MESSAGE("antibot.auto_disabled", "%m"),
WHITELIST_KICK("misc.whitelist_kick", "%p"),
/** The email address is already being used */
EMAIL_ALREADY_USED_ERROR("email.already_used"),
@@ -30,6 +30,7 @@ final class OldMessageKeysMigrater {
.put(MessageKey.WRONG_PASSWORD, "wrong_pwd")
.put(MessageKey.UNREGISTERED_SUCCESS, "unregistered")
.put(MessageKey.REGISTRATION_DISABLED, "reg_disabled")
.put(MessageKey.SESSION_RECONNECTION, "valid_session")
.put(MessageKey.ACCOUNT_NOT_ACTIVATED, "vb_nonActiv")
.put(MessageKey.NAME_ALREADY_REGISTERED, "user_regged")
.put(MessageKey.NO_PERMISSION, "no_perm")
@@ -124,7 +124,6 @@ public enum AdminPermission implements PermissionNode {
* Permission to see Antibot messages.
*/
ANTIBOT_MESSAGES("authme.admin.antibotmessages"),
WHITELIST_MESSAGE("authme.admin.whitelistmessage"),
/**
* Permission to use the update messages command.
@@ -10,7 +10,6 @@ public enum PlayerStatePermission implements PermissionNode {
* Permission node to bypass AntiBot protection.
*/
BYPASS_ANTIBOT("authme.bypassantibot", DefaultPermission.OP_ONLY),
WHITELIST("authme.whitelist", DefaultPermission.OP_ONLY),
/**
* Permission node to bypass BungeeCord server teleportation.
@@ -54,7 +54,7 @@ public class Management {
}
public void forceLogin(Player player) {
runTask(() -> asynchronousLogin.forceLogin(player,0));
runTask(() -> asynchronousLogin.forceLogin(player));
}
public void forceLogin(Player player, boolean quiet) {
@@ -19,7 +19,6 @@ import fr.xephi.authme.service.bungeecord.BungeeSender;
import fr.xephi.authme.service.bungeecord.MessageType;
import fr.xephi.authme.settings.commandconfig.CommandManager;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.InternetProtocolUtils;
@@ -129,16 +128,18 @@ public class AsynchronousJoin implements AsynchronousProcess {
// Session logic
if (sessionService.canResumeSession(player)) {
service.send(player, MessageKey.SESSION_RECONNECTION);
// Run commands
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
() -> commandManager.runCommandsOnSessionLogin(player));
bukkitService.runTaskOptionallyAsync(() -> asynchronousLogin.forceLogin(player,service.getProperty(PluginSettings.HIDE_SESSIONS_LOGIN) ? 1 : 0));
bukkitService.runTaskOptionallyAsync(() -> asynchronousLogin.forceLogin(player));
return;
} else if (proxySessionManager.shouldResumeSession(name)) {
service.send(player, MessageKey.SESSION_RECONNECTION);
// Run commands
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
() -> commandManager.runCommandsOnSessionLogin(player));
bukkitService.runTaskOptionallyAsync(() -> asynchronousLogin.forceLogin(player,service.getProperty(PluginSettings.HIDE_SESSIONS_LOGIN) ? 1 : 0));
bukkitService.runTaskOptionallyAsync(() -> asynchronousLogin.forceLogin(player));
logger.info("The user " + player.getName() + " has been automatically logged in, "
+ "as present in autologin queue.");
return;
@@ -102,7 +102,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
limboService.getLimboPlayer(player.getName()).setState(LimboPlayerState.TOTP_REQUIRED);
// TODO #1141: Check if we should check limbo state before processing password
} else {
performLogin(player, auth, false);
performLogin(player, auth);
}
}
}
@@ -112,10 +112,10 @@ public class AsynchronousLogin implements AsynchronousProcess {
*
* @param player the player to log in
*/
public void forceLogin(Player player,int quiet) {
public void forceLogin(Player player) {
PlayerAuth auth = getPlayerAuth(player);
if (auth != null) {
performLogin(player, auth, quiet == 1);
performLogin(player, auth);
}
}
@@ -128,7 +128,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
public void forceLogin(Player player, boolean quiet) {
PlayerAuth auth = getPlayerAuth(player, quiet);
if (auth != null) {
performLogin(player, auth, false);
performLogin(player, auth);
}
}
@@ -265,7 +265,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
* @param player the player to log in
* @param auth the associated PlayerAuth object
*/
public void performLogin(Player player, PlayerAuth auth, boolean quiet) {
public void performLogin(Player player, PlayerAuth auth) {
if (player.isOnline()) {
boolean isFirstLogin = (auth.getLastLogin() == null);
@@ -284,7 +284,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
tempbanManager.resetCount(ip, name);
player.setNoDamageTicks(0);
if (!quiet) {service.send(player, MessageKey.LOGIN_SUCCESS);}
service.send(player, MessageKey.LOGIN_SUCCESS);
// Other auths
List<String> auths = dataSource.getAllAuthsByIp(auth.getLastIp());
@@ -89,9 +89,9 @@ abstract class AbstractPasswordRegisterExecutor<P extends AbstractPasswordRegist
final Player player = params.getPlayer();
if (performLoginAfterRegister(params)) {
if (commonService.getProperty(PluginSettings.USE_ASYNC_TASKS)) {
bukkitService.runTaskAsynchronously(() -> asynchronousLogin.forceLogin(player,0));
bukkitService.runTaskAsynchronously(() -> asynchronousLogin.forceLogin(player));
} else {
bukkitService.scheduleSyncDelayedTask(() -> asynchronousLogin.forceLogin(player,0), SYNC_LOGIN_DELAY);
bukkitService.scheduleSyncDelayedTask(() -> asynchronousLogin.forceLogin(player), SYNC_LOGIN_DELAY);
}
}
syncProcessManager.processSyncPasswordRegister(player);
@@ -42,18 +42,21 @@ import java.util.zip.GZIPInputStream;
public class GeoIpService {
private static final String LICENSE =
"[LICENSE] This product includes GeoLite2 data created by MaxMind, available at https://www.maxmind.com";
//private static final String LICENSE =
//"[LICENSE] This product includes GeoLite2 data created by MaxMind, available at https://www.maxmind.com";
private static final String DATABASE_NAME = "GeoLite2-Country";
private static final String DATABASE_FILE = DATABASE_NAME + ".mmdb";
private final ConsoleLogger logger = ConsoleLoggerFactory.get(GeoIpService.class);
private final Path dataFile;
private GeoIp2Provider databaseReader;
private volatile boolean downloading;
@Inject
GeoIpService(@DataFolder File dataFolder) {
GeoIpService(@DataFolder File dataFolder){
this.dataFile = dataFolder.toPath().resolve(DATABASE_FILE);
// Fires download of recent data or the initialization of the look up service
@@ -86,27 +89,63 @@ public class GeoIpService {
if (Files.exists(dataFile)) {
try {
startReading();
// don't fire the update task - we are up to date
return true;
} catch (IOException ioEx) {
logger.logException("Failed to load GeoLiteAPI database", ioEx);
return false;
}
}
// File is outdated or doesn't exist - let's try to download the data file!
// use bukkit's cached threads
return false;
}
/**
*
*/
private void startReading() throws IOException {
databaseReader = new Reader(dataFile.toFile(), FileMode.MEMORY, new CHMCache());
logger.info(LICENSE);
// clear downloading flag, because we now have working reader instance
downloading = false;
}
/**
* Downloads the archive to the destination file if it's newer than the locally version.
*
* @param lastModified modification timestamp of the already present file
* @param destination save file
* @return null if no updates were found, the MD5 hash of the downloaded archive if successful
* @throws IOException if failed during downloading and writing to destination file
*/
/**
* Downloads the archive to the destination file if it's newer than the locally version.
*
* @param destination save file
* @return null if no updates were found, the MD5 hash of the downloaded archive if successful
* @throws IOException if failed during downloading and writing to destination file
*/
/**
* Verify if the expected checksum is equal to the checksum of the given file.
*
* @param function the checksum function like MD5, SHA256 used to generate the checksum from the file
* @param file the file we want to calculate the checksum from
* @param expectedChecksum the expected checksum
* @throws IOException on I/O error reading the file or the checksum verification failed
*/
/**
* Extract the database from gzipped data. Existing outputFile will be replaced if it already exists.
*
* @param inputFile gzipped database input file
* @param outputFile destination file for the database
* @throws IOException on I/O error reading the archive, or writing the output
*/
/**
* Get the country code of the given IP address.
*
@@ -11,6 +11,7 @@ import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
@@ -21,6 +22,11 @@ import fr.xephi.authme.util.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.io.DataInputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.net.InetSocketAddress;
@@ -28,6 +34,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import java.util.regex.Pattern;
import static fr.xephi.authme.util.StringUtils.isInsideString;
@@ -84,7 +91,15 @@ public class ValidationService implements Reloadable {
return new ValidationResult(MessageKey.INVALID_PASSWORD_LENGTH);
} else if (settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(passLow)) {
return new ValidationResult(MessageKey.PASSWORD_UNSAFE_ERROR);
} else if (settings.getProperty(SecuritySettings.HAVE_I_BEEN_PWNED_CHECK)) {
HaveIBeenPwnedResults results = validatePasswordHaveIBeenPwned(password);
if (results != null
&& results.isPwned()
&& results.getPwnCount() > settings.getProperty(SecuritySettings.HAVE_I_BEEN_PWNED_LIMIT)) {
return new ValidationResult(MessageKey.PASSWORD_PWNED_ERROR, String.valueOf(results.getPwnCount()));
}
}
return new ValidationResult();
}
@@ -225,6 +240,47 @@ public class ValidationService implements Reloadable {
}
return restrictions;
}
/**
* Check haveibeenpwned.com for the given password.
*
* @param password password to check for
* @return Results of the check
*/
public HaveIBeenPwnedResults validatePasswordHaveIBeenPwned(String password) {
String hash = HashUtils.sha1(password);
String hashPrefix = hash.substring(0, 5);
try {
String url = String.format("https://api.pwnedpasswords.com/range/%s", hashPrefix);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "AuthMeReloaded");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setDoInput(true);
StringBuilder outStr = new StringBuilder();
try (DataInputStream input = new DataInputStream(connection.getInputStream())) {
for (int c = input.read(); c != -1; c = input.read())
outStr.append((char) c);
}
String[] hashes = outStr.toString().split("\n");
for (String hashSuffix : hashes) {
String[] hashSuffixParts = hashSuffix.trim().split(":");
if (hashSuffixParts[0].equalsIgnoreCase(hash.substring(5))) {
return new HaveIBeenPwnedResults(true, Integer.parseInt(hashSuffixParts[1]));
}
}
return new HaveIBeenPwnedResults(false, 0);
} catch (java.io.IOException e) {
logger.warning("验证密码时出现错误,这可能是由于网络问题,如果无法解决,请关闭HaveIBeenPwned检查");
}
return null;
}
public static final class ValidationResult {
private final MessageKey messageKey;
@@ -266,4 +322,22 @@ public class ValidationService implements Reloadable {
return args;
}
}
public static final class HaveIBeenPwnedResults {
private final boolean isPwned;
private final int pwnCount;
public HaveIBeenPwnedResults(boolean isPwned, int pwnCount) {
this.isPwned = isPwned;
this.pwnCount = pwnCount;
}
public boolean isPwned() {
return isPwned;
}
public int getPwnCount() {
return pwnCount;
}
}
}
@@ -1,82 +0,0 @@
package fr.xephi.authme.service;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.util.Locale;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The AntiBot Service Management class.
*/
public class WhiteListService implements SettingsDependent {
private final PermissionsManager permissionsManager;
private final Messages messages;
private final BukkitService bukkitService;
private WhiteListStatus whiteListStatus;
@Inject
WhiteListService(Settings settings, Messages messages, PermissionsManager permissionsManager,
BukkitService bukkitService) {
// Instances
this.messages = messages;
this.permissionsManager = permissionsManager;
this.bukkitService = bukkitService;
// Initial status
whiteListStatus = WhiteListStatus.DISABLED;
// Load settings and start if required
reload(settings);
}
@Override
public void reload(Settings settings) {
}
private void startProtection() {
if (whiteListStatus == WhiteListStatus.ACTIVE) {
return;
}
whiteListStatus = WhiteListStatus.ACTIVE;
bukkitService.getOnlinePlayers().stream()
.filter(player -> permissionsManager.hasPermission(player, AdminPermission.WHITELIST_MESSAGE))
.forEach(player -> messages.send(player, MessageKey.WHITELIST_ENABLED_MESSAGE));
}
private void stopProtection() {
if (whiteListStatus == WhiteListStatus.DISABLED) {
return;
}
whiteListStatus = WhiteListStatus.DISABLED;
bukkitService.getOnlinePlayers().stream()
.filter(player -> permissionsManager.hasPermission(player, AdminPermission.WHITELIST_MESSAGE))
.forEach(player -> messages.send(player, MessageKey.WHITELIST_DISABLED_MESSAGE));
}
public WhiteListStatus getWhiteListStatus() {
return whiteListStatus;
}
public void overrideWhiteListStatus(boolean started) {
if (started) {
startProtection();
} else {
stopProtection();
}
}
public boolean shouldKick() {
return whiteListStatus != WhiteListStatus.DISABLED;
}
public enum WhiteListStatus {
DISABLED,
ACTIVE
}
}
@@ -19,6 +19,11 @@ public final class HooksSettings implements SettingsHolder {
public static final Property<Boolean> BUNGEECORD =
newProperty("Hooks.bungeecord", false);
@Comment("Allow FloodGatePlayer Join Without checkIsValidName()")
public static final Property<Boolean> HOOK_FLOODGATE_PLAYER =
newProperty("Hooks.floodgate", false);
@Comment("Send player to this BungeeCord server after register/login")
public static final Property<String> BUNGEECORD_SERVER =
newProperty("Hooks.sendPlayerTo", "");
@@ -20,12 +20,6 @@ public final class PluginSettings implements SettingsHolder {
public static final Property<Boolean> SESSIONS_ENABLED =
newProperty("settings.sessions.enabled", true);
@Comment({
"Do you want to hide login success message to player?"
})
public static final Property<Boolean> HIDE_SESSIONS_LOGIN =
newProperty("settings.sessions.hidelogin", true);
@Comment({
"After how many minutes should a session expire?",
"A player's session ends after the timeout or if his IP has changed"
@@ -19,9 +19,7 @@ public final class ProtectionSettings implements SettingsHolder {
@Comment("Apply the protection also to registered usernames")
public static final Property<Boolean> ENABLE_PROTECTION_REGISTERED =
newProperty("Protection.enableProtectionRegistered", true);
@Comment("Only allow registed usernames join server")
public static final Property<Boolean> ENABLE_WHITELIST =
newProperty("Protection.enableWhiteList", true);
@Comment({
"Countries allowed to join the server and register. For country codes, see",
"https://dev.maxmind.com/geoip/legacy/codes/iso3166/",
@@ -18,7 +18,7 @@ public final class RegistrationSettings implements SettingsHolder {
"Send every X seconds a message to a player to",
"remind him that he has to login/register"})
public static final Property<Integer> MESSAGE_INTERVAL =
newProperty("settings.registration.messageInterval", 600);
newProperty("settings.registration.messageInterval", 5);
@Comment({
"Only registered and logged in players can play.",
@@ -33,7 +33,7 @@ public final class RegistrationSettings implements SettingsHolder {
"More info at https://github.com/AuthMe/AuthMeReloaded/wiki/Registration"
})
public static final Property<RegistrationType> REGISTRATION_TYPE =
newProperty(RegistrationType.class, "settings.registration.type", RegistrationType.EMAIL);
newProperty(RegistrationType.class, "settings.registration.type", RegistrationType.PASSWORD);
@Comment({
"Second argument the /register command should take: ",
@@ -44,7 +44,7 @@ public final class RegistrationSettings implements SettingsHolder {
})
public static final Property<RegisterSecondaryArgument> REGISTER_SECOND_ARGUMENT =
newProperty(RegisterSecondaryArgument.class, "settings.registration.secondArg",
RegisterSecondaryArgument.NONE);
RegisterSecondaryArgument.CONFIRMATION);
@Comment({
"Do we force kick a player after a successful registration?",
@@ -4,6 +4,8 @@ import ch.jalu.configme.Comment;
import ch.jalu.configme.SettingsHolder;
import ch.jalu.configme.properties.Property;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -113,21 +115,19 @@ public final class RestrictionSettings implements SettingsHolder {
@Comment("Can unregistered players walk around?")
public static final Property<Boolean> ALLOW_UNAUTHED_MOVEMENT =
newProperty("settings.restrictions.allowMovement", true);
newProperty("settings.restrictions.allowMovement", false);
@Comment({
"After how many seconds should players who fail to login or register",
"be kicked? Set to 0 to disable."})
public static final Property<Integer> TIMEOUT =
newProperty("settings.restrictions.timeout", 0);
newProperty("settings.restrictions.timeout", 120);
@Comment("Regex pattern of allowed characters in the player name.")
public static final Property<String> ALLOWED_NICKNAME_CHARACTERS =
newProperty("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*");
@Comment("Allow FloodGatePlayer Join Without checkIsValidName()")
public static final Property<Boolean> HOOK_FLOODGATE_PLAYER =
newProperty("settings.restrictions.hookFloodGatePlayer", false);
@Comment({
"How far can unregistered players walk?",
"Set to 0 for unlimited radius"
@@ -163,7 +163,7 @@ public final class RestrictionSettings implements SettingsHolder {
@Comment("AuthMe will NEVER teleport players if set to true!")
public static final Property<Boolean> NO_TELEPORT =
newProperty("settings.restrictions.noTeleport", true);
newProperty("settings.restrictions.noTeleport", false);
@Comment({
"Regex syntax for allowed chars in passwords. The default [!-~] allows all visible ASCII",
@@ -175,7 +175,7 @@ public final class RestrictionSettings implements SettingsHolder {
@Comment("Regex syntax for allowed chars in email.")
public static final Property<String> ALLOWED_EMAIL_REGEX =
newProperty("settings.restrictions.allowedEmailCharacters", "^[A-Za-z0-9]{4,15}@(outlook|163|gmail|icloud).com$");
newProperty("settings.restrictions.allowedEmailCharacters", "^[A-Za-z0-9_]{4,15}@(qq|outlook|163|gmail|icloud)\\.com$");
@Comment("Force survival gamemode when player joins?")
@@ -194,6 +194,7 @@ public final class RestrictionSettings implements SettingsHolder {
public static final Property<Set<String>> UNRESTRICTED_NAMES =
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedName");
@Comment({
"Below you can list all inventories names that AuthMe will ignore",
"for registration or login. Configure it at your own risk!!",
@@ -206,7 +207,9 @@ public final class RestrictionSettings implements SettingsHolder {
public static final Property<Set<String>> UNRESTRICTED_INVENTORIES =
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedInventories");
private RestrictionSettings() {
}
}
@@ -2,10 +2,10 @@ package fr.xephi.authme.settings.properties;
import ch.jalu.configme.Comment;
import ch.jalu.configme.SettingsHolder;
import ch.jalu.configme.properties.Property;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.settings.EnumSetProperty;
import java.util.Set;
import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty;
@@ -17,16 +17,76 @@ public final class SecuritySettings implements SettingsHolder {
"Take care with this, if you set this to false,",
"AuthMe will automatically disable and the server won't be protected!"})
public static final Property<Boolean> STOP_SERVER_ON_PROBLEM =
newProperty("Security.SQLProblem.stopServer", true);
newProperty("Security.SQLProblem.stopServer", false);
@Comment("Enable the new feature to prevent ghost players?")
public static final Property<Boolean> ANTI_GHOST_PLAYERS = newProperty("3rdPartyFeature.fixes.antiGhostPlayer", false);
@Comment({"Choose the best teleport method by server brand?",
"(Enable this if you are using Paper)"})
public static final Property<Boolean> SMART_ASYNC_TELEPORT = newProperty("3rdPartyFeature.optimizes.smartAsyncTeleport",false);
@Comment("Send a GUI captcha to unregistered players?(Requires ProtocolLib)")
public static final Property<Boolean> GUI_CAPTCHA = newProperty("3rdPartyFeature.captcha.guiCaptcha",false);
@Comment({"Should we kick the players when they don't finish the GUI captcha in seconds?",
"(less than or equals 0 is disabled)"})
public static final Property<Integer> GUI_CAPTCHA_TIMEOUT = newProperty("3rdPartyFeature.captcha.timeOut",0);
@Comment({"Should we ignore floodgate players when sending GUI captcha?",
"(Requires floodgate and hookFloodgate: true)"})
public static final Property<Boolean> GUI_CAPTCHA_BE_COMPATIBILITY = newProperty("3rdPartyFeature.captcha.ignoreBedrock",false);
@Comment("Should we delete player data and stats when they didn't finish the captcha?")
public static final Property<Boolean> DELETE_UNVERIFIED_PLAYER_DATA = newProperty("3rdPartyFeature.captcha.purgePlayerData",false);
@Comment("Which world's player data should be deleted?(Enter the world *FOLDER* name where your players first logged in)")
public static final Property<String> DELETE_PLAYER_DATA_WORLD = newProperty("3rdPartyFeature.captcha.purgeWorldFolderName","world");
// @Comment({"Should we kick the players when they failed captcha too many times?",
// "(Minimum value is 1)(Default: 3)"})
// public static final Property<Integer> GUI_CAPTCHA_MAX_TRY = newProperty("3rdPartyFeature.captcha.maxTryTimes",3);
//@Comment({"Using which API to get hash data?",
//"Available options: github, gitee, ghproxy (if your server is in China, please use gitee or ghproxy.)"})
//public static final Property<String> SHA_CHECK_METHOD = newProperty("Plugin.hashing.hashApi","github");
//@Comment("Should we use the local cache sometimes instead of requesting API?")
//public static final Property<Boolean> USE_LOCAL_CACHE = newProperty("Plugin.hashing.useLocalCache",false);
//@Comment("DON'T TOUCH!!!")
//public static final Property<String> SHA_CHECK_CACHE = newProperty("Plugin.hashing.hashCached","");
@Comment("Copy AuthMe log output in a separate file as well?")
public static final Property<Boolean> USE_LOGGING =
newProperty("Security.console.logConsole", true);
@Comment({"Query haveibeenpwned.com with a hashed version of the password.",
"This is used to check whether it is safe."})
public static final Property<Boolean> HAVE_I_BEEN_PWNED_CHECK =
newProperty("Security.account.haveIBeenPwned.check", false);
@Comment({"If the password is used more than this number of times, it is considered unsafe."})
public static final Property<Integer> HAVE_I_BEEN_PWNED_LIMIT =
newProperty("Security.account.haveIBeenPwned.limit", 0);
@Comment("Enable captcha when a player uses wrong password too many times")
public static final Property<Boolean> ENABLE_LOGIN_FAILURE_CAPTCHA =
newProperty("Security.captcha.useCaptcha", false);
@Comment("Check for updates on enabled from GitHub?")
public static final Property<Boolean> CHECK_FOR_UPDATES =
newProperty("Plugin.updates.checkForUpdates", true);
@Comment("Should we show the AuthMe banner on startup?")
public static final Property<Boolean> SHOW_STARTUP_BANNER =
newProperty("Plugin.banners.showBanners", true);
@Comment("Change the banner colors here (Default: §r)")
public static final Property<String> STARTUP_BANNER_COLOR =
newProperty("Plugin.banners.bannerColor", "§r");
@Comment("Max allowed tries before a captcha is required")
public static final Property<Integer> MAX_LOGIN_TRIES_BEFORE_CAPTCHA =
newProperty("Security.captcha.maxLoginTry", 8);
@@ -0,0 +1,50 @@
package fr.xephi.authme.util;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//
//public class TeleportUtils {
// public static void teleport(Player player, Location location) {
// try {
// Class<?> paperClass = Class.forName("com.destroystokyo.paper.PaperConfig");
// // Paper API is loaded, use teleportAsync
// Method teleportAsyncMethod = player.getClass().getMethod("teleportAsync", Location.class);
// teleportAsyncMethod.setAccessible(true);
// teleportAsyncMethod.invoke(player, location);
// } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
// // Paper API is not loaded, use normal teleport
// player.teleport(location);
// }
// }
//}
public class TeleportUtils {
private static Method teleportAsyncMethod;
static {
try {//Detect Paper class
Class<?> paperClass = Class.forName("com.destroystokyo.paper.PaperConfig");
teleportAsyncMethod = Player.class.getMethod("teleportAsync", Location.class);
// if detected,use teleportAsync()
} catch (ClassNotFoundException | NoSuchMethodException e) {
teleportAsyncMethod = null;
//if not, set method to null
}
}
public static void teleport(Player player, Location location) {
if (teleportAsyncMethod != null) {
try {
teleportAsyncMethod.setAccessible(true);
teleportAsyncMethod.invoke(player, location);
} catch (IllegalAccessException | InvocationTargetException e) {
player.teleport(location);
}
} else {
player.teleport(location);
}
}
}
Binary file not shown.
+1 -4
View File
@@ -41,10 +41,7 @@
# executor: CONSOLE
# ifNumberOfAccountsAtLeast: 5
# Commands to run for players logging in whose 'last login date' was empty
onFirstLogin:
broadcast:
command: 'cmi broadcast &b欢迎 &r%p &7( %ip ) &b光临服务器,请大家多多关照!'
executor: CONSOLE
onFirstLogin: {}
onJoin: {}
onLogin: {}
# These commands are called whenever a logged in player uses /logout or quits.
+2 -2
View File
@@ -102,8 +102,8 @@
<tbody>
<tr>
<td>
<p style="color:#b0adc5;">© 2023 IrisCraft. All rights reserved.</p>
<a href="https://www.mcbbs.net/thread-1263385-1-1.html" target="_blank" style="text-decoration: none; font-size: 16px">iriscraft.work</a>
<p style="color:#b0adc5;">© 2023 HomoCraft. All rights reserved.</p>
<a href="1919810.com" target="_blank" style="text-decoration: none; font-size: 16px">homomc.cc</a>
</td>
</tr>
</tbody>
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Сесията е продължена.'
invalid_session: '&cТвоят IP се е променил и сесията беше прекратена.'
# Error messages when joining
+1 -1
View File
@@ -69,7 +69,7 @@ misc:
# Mensagens de sessão
session:
valid_session: '&2Você deslogou recentemente, então sua sessão foi retomada!'
invalid_session: '&fO seu IP foi alterado e sua sessão expirou!'
# Mensagens de erro ao entrar
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&cAutomatické znovupřihlášení.'
invalid_session: '&cChyba: Počkej než vyprší tvoje relace.'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Erfolgreich eingeloggt!'
invalid_session: '&cUngültige Session. Bitte starte das Spiel neu oder warte, bis die Session abgelaufen ist.'
# Error messages when joining
+2 -1
View File
@@ -20,6 +20,7 @@ password:
unsafe_password: '&cThe chosen password isn''t safe, please choose another one...'
forbidden_characters: '&4Your password contains illegal characters. Allowed chars: %valid_chars'
wrong_length: '&cYour password is too short or too long! Please try with another one!'
pwned_password: '&cYour chosen password is not secure. It was used %pwned_count times already! Please use a strong password...'
# Login
login:
@@ -66,7 +67,7 @@ misc:
# Session messages
session:
invalid_session: '&cYour IP has been changed and your session data has expired!'
valid_session: '&2Logged-in due to Session Reconnection.'
# Error messages when joining
on_join_validation:
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Ensalutantojn pro Sesio Rekonektas.'
invalid_session: '&cVia IP estis ŝanĝita kaj via seanco datumoj finiĝis!'
# Error messages when joining
+1 -1
View File
@@ -67,7 +67,7 @@ misc:
# Session messages
session:
valid_session: '&cInicio de sesión'
invalid_session: '&fLos datos de sesión no corresponden. Por favor espera a terminar la sesión.'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
invalid_session: '&cSinu IP-aadress muutus, seega sinu sessioon aegus!'
valid_session: '&2Sisse logitud sessiooni jätkumise tõttu.'
# Error messages when joining
on_join_validation:
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&cSesioa mantendu eta beraz ez daukazu saioa hasi beharrik.'
invalid_session: '&cZure IP helbidea aldatu da, eta horregatik zure sesioa iraungi da!'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&cIstunto jatkettu!'
invalid_session: '&fIstunto ei täsmää! Ole hyvä ja odota istunnon loppuun'
# Error messages when joining
+1 -1
View File
@@ -69,7 +69,7 @@ misc:
# Session
session:
valid_session: '&aVous avez été automatiquement connecté !'
invalid_session: 'Session expirée suite à un changement d''IP.'
# Erreurs lors d'une tentative connexion
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&cIdentificado mediante a sesión'
invalid_session: '&fOs datos de sesión non corresponden, por favor, espere a que remate a sesión'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2A megadott időkereten belül csatlakoztál vissza, így a rendszer automatikusan beléptetett.'
invalid_session: '&cAz IP címed megváltozott, ezért a visszacsatlakozási időkereted lejárt.'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Otomatis login, karena sesi masih terhubung.'
invalid_session: '&cIP kamu telah berubah, dan sesi kamu telah berakhir!'
# Error messages when joining
+1 -1
View File
@@ -67,7 +67,7 @@ misc:
# Session messages
session:
valid_session: '&2Autenticato automaticamente attraverso la precedente sessione!'
invalid_session: '&cIl tuo indirizzo IP è cambiato e la tua sessione è stata terminata!'
# Error messages when joining
+1 -1
View File
@@ -68,7 +68,7 @@ misc:
# Session messages
session:
valid_session: '&2세션 재 연결로 인해 로그인 되었습니다.'
invalid_session: '&cIP가 변경되어 세션이 만료되었습니다!'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&aSesijos prisijungimas'
invalid_session: '&cSesijos laikai nesutampa, prasome palaukti kol secija baigsis.'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Ingelogd wegens sessie-herverbinding.'
invalid_session: '&cJouw IP-adres is veranderd en je sessie is verlopen!'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&aZalogowano automatycznie z powodu sesji logowania.'
invalid_session: '&fSesja logowania zakończona!'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&cSessão válida'
invalid_session: '&fDados de sessão não correspondem. Por favor aguarde o fim da sessão'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
invalid_session: '&cIP-ul tau a fost schimbat si sesiunea ta a expirat!'
valid_session: '&2Conectat datorita reconectarii sesiunii.'
# Error messages when joining
on_join_validation:
+1 -1
View File
@@ -61,7 +61,7 @@ misc:
# Session messages
session:
valid_session: '&2Вы автоматически авторизовались!'
invalid_session: '&cСессия некорректна. Дождитесь, пока она закончится.'
# Error messages when joining
+2 -1
View File
@@ -65,7 +65,7 @@ misc:
# Session messages
session:
valid_session: '&2Uspešna povezava.'
invalid_session: '&cVas IP je bil spremenjen in vasa seja je potekla!'
# Error messages when joining
@@ -154,3 +154,4 @@ time:
hours: 'ure'
day: 'dan'
days: 'dni'
+1 -1
View File
@@ -72,7 +72,7 @@ misc:
# Session messages
session:
valid_session: '&cAutomatické prihlásenie z dôvodu pokračovania relácie.'
invalid_session: '&fTvoja IP sa zmenila a tvoje prihlásenie(relácia) vypršalo(/a).'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Ulogovani ste zbog ponovnog povezivanja sesije.'
invalid_session: '&cVaš IP je promenjen i vaši podaci o sesiji su istekli!'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Oturuma girisiniz otomatikmen yapilmistir.'
invalid_session: '&cIP adresin degistirildi ve oturum suren doldu!'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Сесію відновлено.'
invalid_session: '&cСесію було розірвано внаслідок зміни IP.'
# Error messages when joining
+1 -1
View File
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2Phiên đăng nhập đã được kết nối trở lại.'
invalid_session: '&cIP của bạn đã bị thay đổi và phiên đăng nhập của bạn đã hết hạn!'
# Error messages when joining
+7 -11
View File
@@ -7,8 +7,8 @@
registration:
disabled: '&c注册已被禁止'
name_taken: '&c此用户已经在此服务器注册过'
register_request: '&7请输入“/register <邮箱>”以注册'
command_usage: '&c正确用法:“/register <邮箱>”'
register_request: '&b请输入“&a/reg <密码> <重复密码>&b”以注册'
command_usage: '&c正确用法:“/reg <密码> <重复密码>”'
reg_only: '&c只允许注册过的玩家进服!'
success: '&a*** 已成功注册 ***'
@@ -19,13 +19,14 @@ password:
unsafe_password: '&c您不能使用安全性过低的密码。 '
forbidden_characters: '&4您的密码包含了非法字符.可使用的字符: %valid_chars'
wrong_length: '&4您的密码没有达到要求!'
pwned_password: '&c你使用的密码并不安全。它已经被使用了 %pwned_count 次! 请使用一个更强大的密码...'
# Login
login:
command_usage: '&c正确用法:“/login <密码>”'
command_usage: '&c正确用法:“/l <密码>”'
wrong_password: '&c*** 密码错误 ***'
success: '&a*** 已成功登录 ***'
login_request: '&c请输入“/login <密码>”以登录'
login_request: '&c请输入“/l <密码>”以登录'
timeout_error: '给您登录的时间已经过了'
# Errors
@@ -65,12 +66,10 @@ misc:
usage_change_password: '&a正确用法:“/changepassword 旧密码 新密码”'
accounts_owned_self: '您拥有 %count 个账户:'
accounts_owned_other: '玩家 %name 拥有 %count 个账户:'
whitelist_enabled: '&c*** 服务器已暂停注册 ***'
whitelist_disabled: '&a*** 服务器已开放注册 ***'
whitelist_kick: '&7玩家 &c%p &7请求加入服务器,但是被拒绝了.'
# Session messages
session:
valid_session: ''
invalid_session: '&c*** 请重新登录 ***'
# Error messages when joining
@@ -90,10 +89,7 @@ on_join_validation:
&c如果您并不知情,请更换您的用户名重新加入该服务器.
invalid_name_case: '&c您应该使用 %valid 登录服务器,当前名字: %invalid .'
quick_command: '&c您发送命令的速度太快了,请重新加入服务器等待一会后再使用命令'
kick_whitelist: |-
&6[&b&lAccount Security System&6]
&c本服务器已经暂停注册,请用下面的联系方式了解详细情况.
&cQQ群聊号码: 550984860 &b| &c QQ: 2125368097 &b| &cTelegram: @Stabrinai
# Email
email:
add_email_request: ''
@@ -69,7 +69,7 @@ misc:
# Session messages
session:
valid_session: '&8[&6用戶系統&8] &b嗨 歡迎回來喔~'
invalid_session: '&8[&6用戶系統&8] &f登入階段資料已損壞,請等待登入階段結束。'
# Error messages when joining
@@ -66,7 +66,7 @@ misc:
# Session messages
session:
valid_session: '&2由於會話重新連接而登錄.'
invalid_session: '&c您的IP已更改,並且您的會話數據已過期!'
# Error messages when joining
@@ -68,7 +68,7 @@ misc:
# Session messages
session:
valid_session: '&b【AuthMe】&6您已經成功登入!'
invalid_session: '&b【AuthMe】&6Session驗證不相符!'
# Error messages when joining
+2 -2
View File
@@ -108,8 +108,8 @@
<tbody>
<tr>
<td>
<p style="color:#b0adc5;">© 2023 IrisCraft. All rights reserved.</p>
<a href="https://www.mcbbs.net/thread-1263385-1-1.html" target="_blank" style="text-decoration: none; font-size: 16px">iriscraft.work</a>
<p style="color:#b0adc5;">© 2023 HomoCraft. All rights reserved.</p>
<a href="1919810.com" target="_blank" style="text-decoration: none; font-size: 16px">homomc.cc</a>
</td>
</tr>
</tbody>
+3 -7
View File
@@ -1,9 +1,9 @@
name: ${pluginDescription.name}
authors: [${pluginDescription.authors}]
website: ${project.url}
description: ${project.description}
website: http://github.com/HaHaWTH/AuthMeReReloaded/
description: A fork of AuthMeReloaded that contains bug fixes
main: ${pluginDescription.main}
version: ${pluginDescription.version}
version: 5.6.0-FORK-b23
api-version: 1.13
softdepend:
- Vault
@@ -28,7 +28,6 @@ commands:
usage: /login <password>
aliases:
- l
- log
logout:
description: Logout command
usage: /logout
@@ -184,9 +183,6 @@ permissions:
authme.bypassantibot:
description: Permission node to bypass AntiBot protection.
default: op
authme.whitelist:
description: Permission node to whitelist.
default: op
authme.bypasscountrycheck:
description: Permission to bypass the GeoIp country code check.
default: false
+2 -2
View File
@@ -101,8 +101,8 @@
<tbody>
<tr>
<td>
<p style="color:#b0adc5;">© 2023 IrisCraft. All rights reserved.</p>
<a href="https://www.mcbbs.net/thread-1263385-1-1.html" target="_blank" style="text-decoration: none; font-size: 16px">iriscraft.work</a>
<p style="color:#b0adc5;">© 2023 HomoCraft. All rights reserved.</p>
<a href="191980.com" target="_blank" style="text-decoration: none; font-size: 16px">homomc.cc</a>
</td>
</tr>
</tbody>
+2 -2
View File
@@ -99,8 +99,8 @@
<tbody>
<tr>
<td>
<p style="color:#b0adc5;">© 2023 IrisCraft. All rights reserved.</p>
<a href="https://www.mcbbs.net/thread-1263385-1-1.html" target="_blank" style="text-decoration: none; font-size: 16px">iriscraft.work</a>
<p style="color:#b0adc5;">© 2023 HomoCraft. All rights reserved.</p>
<a href="1919810.com" target="_blank" style="text-decoration: none; font-size: 16px">homomc.cc</a>
</td>
</tr>
</tbody>
@@ -101,8 +101,8 @@
<tbody>
<tr>
<td>
<p style="color:#b0adc5;">© 2023 IrisCraft. All rights reserved.</p>
<a href="https://www.mcbbs.net/thread-1263385-1-1.html" target="_blank" style="text-decoration: none; font-size: 16px">iriscraft.work</a>
<p style="color:#b0adc5;">© 2023 HomoCraft. All rights reserved.</p>
<a href="1919810.com" target="_blank" style="text-decoration: none; font-size: 16px">homomc.cc</a>
</td>
</tr>
</tbody>