Compare commits

..

84 Commits

Author SHA1 Message Date
games647
9f5186a3ed Revert "Minor code recommendations"
This reverts commit d89d332273.
2024-05-21 11:01:38 +02:00
games647
896e250fa2 Fix setting offline UUID with newer BungeeCord
Fixes #1189
Fixes #1193
2024-04-30 10:11:48 +02:00
games647
a65a5f3020 Make ignore states more verbose in Velocity 2024-02-13 16:54:23 +01:00
games647
8a729e069d Use current link for hastebin 2024-02-13 16:54:22 +01:00
games647
d89d332273 Minor code recommendations 2024-02-13 16:54:22 +01:00
games647
cd3cfef6d4 Do not encapsulate the task twice in Velocity 2024-02-13 16:54:22 +01:00
games647
6ec6e4844d Bump dependencies 2024-02-13 16:54:22 +01:00
games647
60a65377b8 Hint proxy setup guide and out of date versions 2024-02-13 16:54:22 +01:00
games647
ffbf0ae3f4 Merge pull request #1151 from games647/dependabot/github_actions/advanced-security/maven-dependency-submission-action-4.0.0
Bump advanced-security/maven-dependency-submission-action from 3.0.2 to 4.0.0
2024-02-01 11:38:47 +01:00
dependabot[bot]
4cf65cf7e5 Bump advanced-security/maven-dependency-submission-action
Bumps [advanced-security/maven-dependency-submission-action](https://github.com/advanced-security/maven-dependency-submission-action) from 3.0.2 to 4.0.0.
- [Release notes](https://github.com/advanced-security/maven-dependency-submission-action/releases)
- [Commits](https://github.com/advanced-security/maven-dependency-submission-action/compare/v3.0.2...v4.0.0)

---
updated-dependencies:
- dependency-name: advanced-security/maven-dependency-submission-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 07:45:51 +00:00
games647
dbf5ae2fae [Velocity] Fix plugin resuming event processing if login is not handled
This causes login timeouts if this plugin doesn't handle the login for
cases like:

* Anti-Bot is triggered
* Another plugin already denied the login

Fixes #1146
2024-01-23 13:59:49 +01:00
games647
707572a007 Add core module name 2024-01-16 14:08:47 +01:00
games647
108f5ad324 Transform velocity MariaDB transformers too
Otherwise, authentication plugin drivers couldn't be found.
2024-01-15 17:01:02 +01:00
games647
2112d06162 Increase encryption key size for Spigot protocol
1024 bits are very weak keys. This size equals vanillas implementation.
Therefore, 2048 goes out of spec, but works and requires only minimal
additional performance for improved security.

The consequence will be during the login and playing in onlinemode.
First for authenticating and second for the encryption of all following
packets.
2024-01-15 16:37:48 +01:00
games647
aece7f855d Update Java CI version 2024-01-15 16:29:26 +01:00
games647
33b4ac8494 [ci-skip] Fully qualify dependabot versions 2024-01-15 16:29:16 +01:00
games647
09161b86dd Merge pull request #1142 from games647/dependabot/maven/production-dependencies-eb968b0e20
Bump the production-dependencies group with 5 updates
2024-01-15 16:25:55 +01:00
games647
57833bb40b Merge pull request #1133 from games647/dependabot/github_actions/github/codeql-action-3
Bump github/codeql-action from 2 to 3
2024-01-15 16:23:45 +01:00
games647
a1414a38ff Merge pull request #1141 from games647/dependabot/maven/development-dependencies-ca802ab3b6
Bump the development-dependencies group with 1 update
2024-01-15 16:23:24 +01:00
games647
0021bc476d Merge pull request #709 from Smart123s/feature/floodgate/newdb
Differentiate Floodgate players in database
2024-01-15 16:22:34 +01:00
dependabot[bot]
4b1e08a2f8 Bump the production-dependencies group with 5 updates
Bumps the production-dependencies group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) | `10.12.5` | `10.12.7` |
| [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) | `3.2.2` | `3.2.5` |
| org.slf4j:slf4j-jdk14 | `2.0.9` | `2.0.11` |
| com.lenis0012.bukkit:loginsecurity | `3.2.1` | `3.3.0` |
| [org.mariadb.jdbc:mariadb-java-client](https://github.com/mariadb-corporation/mariadb-connector-j) | `3.3.1` | `3.3.2` |


Updates `com.puppycrawl.tools:checkstyle` from 10.12.5 to 10.12.7
- [Release notes](https://github.com/checkstyle/checkstyle/releases)
- [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.5...checkstyle-10.12.7)

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.2.2 to 3.2.5
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.2...surefire-3.2.5)

Updates `org.slf4j:slf4j-jdk14` from 2.0.9 to 2.0.11

Updates `com.lenis0012.bukkit:loginsecurity` from 3.2.1 to 3.3.0

Updates `org.mariadb.jdbc:mariadb-java-client` from 3.3.1 to 3.3.2
- [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.3.1...3.3.2)

---
updated-dependencies:
- dependency-name: com.puppycrawl.tools:checkstyle
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.slf4j:slf4j-jdk14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: com.lenis0012.bukkit:loginsecurity
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: org.mariadb.jdbc:mariadb-java-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 07:40:02 +00:00
dependabot[bot]
dbf5b8907e Bump the development-dependencies group with 1 update
Bumps the development-dependencies group with 1 update: [org.mockito:mockito-core](https://github.com/mockito/mockito).


Updates `org.mockito:mockito-core` from 5.8.0 to 5.9.0
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v5.8.0...v5.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 07:38:05 +00:00
dependabot[bot]
e6dfa97e70 Bump github/codeql-action from 2 to 3
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 07:12:00 +00:00
games647
434a276d30 Invert if and document migration flow for better readability 2023-12-11 16:16:16 +01:00
games647
485af5e044 Document states 2023-12-11 16:16:16 +01:00
Smart123s
e566740dde Differentiate Floodgate players during login 2023-12-11 16:16:15 +01:00
Smart123s
db5b818a80 Add Floodgate variable to StoredProfile/Database 2023-12-11 16:16:15 +01:00
Smart123s
b0b998d1aa Use columnName instead of columnIndex
It's safer to rely on names instead of indexes.
It's also easier to add new columns at the end of the table.
2023-12-11 16:16:15 +01:00
Smart123s
62ca46fe6a Add checksytle suppression via comments 2023-12-11 16:16:15 +01:00
games647
cd67797b5b Merge pull request #1122 from games647/dependabot/maven/development-dependencies-a116437099
Bump the development-dependencies group with 3 updates
2023-12-06 16:19:28 +01:00
games647
48e8b45f1e Merge pull request #1123 from games647/dependabot/maven/production-dependencies-d650319dc7
Bump the production-dependencies group with 6 updates
2023-12-06 16:19:09 +01:00
games647
1c9b8cb971 Merge pull request #1120 from games647/dependabot/github_actions/actions/setup-java-4
Bump actions/setup-java from 3 to 4
2023-12-06 16:18:34 +01:00
dependabot[bot]
dcb9540a2f Bump the production-dependencies group with 6 updates
Bumps the production-dependencies group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) | `10.12.4` | `10.12.5` |
| [org.apache.maven.plugins:maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) | `3.3.0` | `3.3.1` |
| [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) | `3.1.2` | `3.2.2` |
| me.clip:placeholderapi | `2.11.4` | `2.11.5` |
| [org.mariadb.jdbc:mariadb-java-client](https://github.com/mariadb-corporation/mariadb-connector-j) | `3.2.0` | `3.3.1` |
| [org.codehaus.mojo:templating-maven-plugin](https://github.com/mojohaus/templating-maven-plugin) | `1.0.0` | `3.0.0` |


Updates `com.puppycrawl.tools:checkstyle` from 10.12.4 to 10.12.5
- [Release notes](https://github.com/checkstyle/checkstyle/releases)
- [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.4...checkstyle-10.12.5)

Updates `org.apache.maven.plugins:maven-checkstyle-plugin` from 3.3.0 to 3.3.1
- [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.3.0...maven-checkstyle-plugin-3.3.1)

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.1.2 to 3.2.2
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.1.2...surefire-3.2.2)

Updates `me.clip:placeholderapi` from 2.11.4 to 2.11.5

Updates `org.mariadb.jdbc:mariadb-java-client` from 3.2.0 to 3.3.1
- [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.2.0...3.3.1)

Updates `org.codehaus.mojo:templating-maven-plugin` from 1.0.0 to 3.0.0
- [Release notes](https://github.com/mojohaus/templating-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/templating-maven-plugin/compare/templating-maven-plugin-1.0.0...3.0.0)

---
updated-dependencies:
- dependency-name: com.puppycrawl.tools:checkstyle
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: me.clip:placeholderapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.mariadb.jdbc:mariadb-java-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: org.codehaus.mojo:templating-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 07:49:44 +00:00
dependabot[bot]
cacf3c23f1 Bump the development-dependencies group with 3 updates
Bumps the development-dependencies group with 3 updates: [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5), [org.mockito:mockito-core](https://github.com/mockito/mockito) and [org.bouncycastle:bcprov-jdk18on](https://github.com/bcgit/bc-java).


Updates `org.junit.jupiter:junit-jupiter` from 5.10.0 to 5.10.1
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.10.0...r5.10.1)

Updates `org.mockito:mockito-core` from 5.6.0 to 5.8.0
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v5.6.0...v5.8.0)

Updates `org.bouncycastle:bcprov-jdk18on` from 1.76 to 1.77
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: org.mockito:mockito-core
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: org.bouncycastle:bcprov-jdk18on
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 07:48:07 +00:00
dependabot[bot]
67f170694f Bump actions/setup-java from 3 to 4
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 07:49:23 +00:00
games647
e15ea9ce85 Restore support for fully qualified storage drivers
Related #1100
2023-10-12 10:47:14 +02:00
games647
70960661b4 [ci-skip] Fix typo in issue templates 2023-10-11 13:42:17 +02:00
games647
ec657faaff Force lowercase SQL driver name to improve type checks 2023-10-11 13:40:57 +02:00
games647
51898b4b34 Migrate enhancement requests to newer issue templates 2023-10-11 13:28:12 +02:00
games647
e30de1b700 Include CI server in issue template 2023-10-11 13:28:11 +02:00
games647
ce17441edb Merge pull request #1097 from games647/dependabot/maven/production-dependencies-84d7f6773a
Bump the production-dependencies group with 6 updates
2023-10-11 12:39:04 +02:00
dependabot[bot]
3244b7a87a Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 12:38:02 +02:00
games647
ecacd2a715 Update toolchain for Java 21 compiling 2023-10-11 12:37:07 +02:00
SzczurekYT
ea6d4cf2f6 Add proper support for 1.19.3-1.20.1 2023-10-11 12:37:07 +02:00
SzczurekYT
91b05289ad Add 1.20.2 support 2023-10-11 12:37:07 +02:00
dependabot[bot]
4e0f8cfb65 Bump the production-dependencies group with 6 updates
Bumps the production-dependencies group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) | `10.12.3` | `10.12.4` |
| [org.projectlombok:lombok](https://github.com/projectlombok/lombok) | `1.18.28` | `1.18.30` |
| com.mycila:license-maven-plugin | `4.2` | `4.3` |
| org.slf4j:slf4j-jdk14 | `2.0.7` | `2.0.9` |
| me.clip:placeholderapi | `2.11.3` | `2.11.4` |
| [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) | `3.5.0` | `3.5.1` |


Updates `com.puppycrawl.tools:checkstyle` from 10.12.3 to 10.12.4
- [Release notes](https://github.com/checkstyle/checkstyle/releases)
- [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.3...checkstyle-10.12.4)

Updates `org.projectlombok:lombok` from 1.18.28 to 1.18.30
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.28...v1.18.30)

Updates `com.mycila:license-maven-plugin` from 4.2 to 4.3

Updates `org.slf4j:slf4j-jdk14` from 2.0.7 to 2.0.9

Updates `me.clip:placeholderapi` from 2.11.3 to 2.11.4

Updates `org.apache.maven.plugins:maven-shade-plugin` from 3.5.0 to 3.5.1
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.0...maven-shade-plugin-3.5.1)

---
updated-dependencies:
- dependency-name: com.puppycrawl.tools:checkstyle
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: com.mycila:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: org.slf4j:slf4j-jdk14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: me.clip:placeholderapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 07:56:41 +00:00
games647
d76690dcbe Merge pull request #1087 from games647/dependabot/maven/production-dependencies-ce791421b1
Bump the production-dependencies group with 7 updates
2023-08-31 15:23:30 +02:00
dependabot[bot]
3559d067ad Bump the production-dependencies group with 7 updates
Bumps the production-dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) | `10.9.3` | `10.12.3` |
| [org.projectlombok:lombok](https://github.com/projectlombok/lombok) | `1.18.26` | `1.18.28` |
| [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) | `2.22.2` | `3.1.2` |
| [com.google.code.gson:gson](https://github.com/google/gson) | `2.10` | `2.10.1` |
| com.lenis0012.bukkit:loginsecurity | `3.1.1` | `3.2.1` |
| [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) | `3.4.1` | `3.5.0` |
| [org.mariadb.jdbc:mariadb-java-client](https://github.com/mariadb-corporation/mariadb-connector-j) | `3.1.4` | `3.2.0` |


Updates `com.puppycrawl.tools:checkstyle` from 10.9.3 to 10.12.3
- [Release notes](https://github.com/checkstyle/checkstyle/releases)
- [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.9.3...checkstyle-10.12.3)

Updates `org.projectlombok:lombok` from 1.18.26 to 1.18.28
- [Release notes](https://github.com/projectlombok/lombok/releases)
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.26...v1.18.28)

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 2.22.2 to 3.1.2
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.22.2...surefire-3.1.2)

Updates `com.google.code.gson:gson` from 2.10 to 2.10.1
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.10...gson-parent-2.10.1)

Updates `com.lenis0012.bukkit:loginsecurity` from 3.1.1 to 3.2.1

Updates `org.apache.maven.plugins:maven-shade-plugin` from 3.4.1 to 3.5.0
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.1...maven-shade-plugin-3.5.0)

Updates `org.mariadb.jdbc:mariadb-java-client` 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: com.puppycrawl.tools:checkstyle
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: production-dependencies
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: com.lenis0012.bukkit:loginsecurity
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: org.mariadb.jdbc:mariadb-java-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-31 11:53:12 +00:00
games647
48a92ed35e Use wildcard exclude patterns 2023-08-31 13:51:42 +02:00
games647
a4eec19f53 [ci-skip] Fix dependency name 2023-08-31 13:19:17 +02:00
games647
32eda941ee Ignore Hikari and SnakeYAML in dependency updates 2023-08-31 12:42:32 +02:00
games647
92d88caf0a Merge pull request #1085 from games647/dependabot/maven/development-dependencies-424a594065
Bump the development-dependencies group with 2 updates
2023-08-31 12:28:11 +02:00
dependabot[bot]
d2202d7a12 Bump the development-dependencies group with 2 updates
Bumps the development-dependencies group with 2 updates: [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5) and [org.bouncycastle:bcprov-jdk18on](https://github.com/bcgit/bc-java).


Updates `org.junit.jupiter:junit-jupiter` from 5.9.1 to 5.10.0
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.9.1...r5.10.0)

Updates `org.bouncycastle:bcprov-jdk18on` from 1.75 to 1.76
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: org.bouncycastle:bcprov-jdk18on
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-31 10:21:23 +00:00
games647
6a68e04c87 Fix grouping for maven packages 2023-08-31 12:18:10 +02:00
games647
b702f48907 Add version number back 2023-08-31 12:14:06 +02:00
games647
159a6ed37c Add JavaDoc snippets and tiny reformats 2023-08-31 12:08:40 +02:00
games647
b48dfed709 Add NPE check on velocity for logins 2023-08-31 12:08:40 +02:00
games647
2db327ccc4 Group dependency updates together 2023-08-31 12:08:39 +02:00
games647
9d907983a6 Only run CodeQL if successful 2023-08-31 12:08:39 +02:00
games647
4a3d7f448f Merge pull request #1071 from xrh0905/floodgate_enabled
Floodgate enabled
2023-08-31 12:07:53 +02:00
xrh0905
31cbb2ff11 Add floodgate support
Based on: https://github.com/games647/FastLogin/pull/649

Solve hooks not found

Add defination of floodgateservice

Geyser API
2023-08-31 12:04:23 +02:00
games647
1715c08ee6 Merge pull request #1041 from games647/dependabot/maven/org.apache.maven.plugins-maven-checkstyle-plugin-3.3.0
Bump maven-checkstyle-plugin from 3.1.2 to 3.3.0
2023-07-20 12:02:43 +02:00
games647
5682df9ad5 Merge pull request #1048 from games647/dependabot/maven/org.bouncycastle-bcprov-jdk18on-1.75
Bump bcprov-jdk18on from 1.72 to 1.75
2023-07-20 12:01:27 +02:00
games647
132b560130 Merge pull request #1036 from games647/dependabot/maven/org.mariadb.jdbc-mariadb-java-client-3.1.4
Bump mariadb-java-client from 3.1.0 to 3.1.4
2023-07-20 12:01:13 +02:00
games647
e204c9c579 Merge pull request #1021 from games647/dependabot/maven/com.mycila-license-maven-plugin-4.2
Bump license-maven-plugin from 4.1 to 4.2
2023-07-20 12:00:56 +02:00
games647
f92863e53a Merge branch 'main' into dependabot/maven/org.apache.maven.plugins-maven-checkstyle-plugin-3.3.0 2023-07-20 12:00:33 +02:00
games647
23fec56ecd Merge branch 'main' into dependabot/maven/org.bouncycastle-bcprov-jdk18on-1.75 2023-07-20 11:57:50 +02:00
games647
5cd10fd795 Run CodeQL after main build to leverage caching 2023-07-17 17:04:28 +02:00
games647
ecbf07c0b2 Manually start build process in CodeQL 2023-07-17 16:26:52 +02:00
games647
053b51e96b Relax java build version requirement
GitHub action seems to always download Java 19 even though it is
already downloaded and installed. This could also help with running
the CodeQL action.
2023-07-17 16:17:57 +02:00
games647
44d365b15d Use java dot file to help autobuild select the correct version 2023-07-17 15:52:54 +02:00
games647
610c49d62c Enable write for dependency graph 2023-07-17 15:49:36 +02:00
games647
dbd12742fa Only upload dependency graph on push 2023-07-17 15:47:02 +02:00
games647
f2fd51d4e2 Use suggestion dependency version 2023-07-17 15:17:29 +02:00
games647
f9ca318775 Apply Java version selection after CodeQL init 2023-07-17 15:13:40 +02:00
games647
f06ace2f5b Add dependency graph to help GitHub find dependencies 2023-07-17 15:09:16 +02:00
games647
ee465e381c Rephrase invalid session warning to make it more clear 2023-07-17 10:10:03 +02:00
games647
6ab81b1a2f Fix formatting errors 2023-07-17 09:55:24 +02:00
games647
36ee52aa6e Print out a warning if we detect local IP addresses during connections
Reference #1055
2023-07-10 15:52:34 +02:00
dependabot[bot]
e5c70d8597 Bump bcprov-jdk18on from 1.72 to 1.75
Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.72 to 1.75.
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

---
updated-dependencies:
- dependency-name: org.bouncycastle:bcprov-jdk18on
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-26 07:58:13 +00:00
dependabot[bot]
8b1485f0b1 Bump maven-checkstyle-plugin from 3.1.2 to 3.3.0
Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.1.2 to 3.3.0.
- [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.1.2...maven-checkstyle-plugin-3.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-29 07:57:19 +00:00
games647
c106089a72 Include updated yaml for older Spigot platforms
Fixes #1031
2023-05-22 15:16:42 +02:00
dependabot[bot]
5fc27f6c4a Bump mariadb-java-client from 3.1.0 to 3.1.4
Bumps [mariadb-java-client](https://github.com/mariadb-corporation/mariadb-connector-j) from 3.1.0 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/commits/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-05-08 07:57:09 +00:00
dependabot[bot]
73720277b3 Bump license-maven-plugin from 4.1 to 4.2
Bumps license-maven-plugin from 4.1 to 4.2.

---
updated-dependencies:
- dependency-name: com.mycila:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 07:58:12 +00:00
39 changed files with 809 additions and 169 deletions

View File

@@ -36,7 +36,7 @@ body:
attributes:
label: Server log
description: The error, stacktrace or link the complete log. You can use the links above for long versions.
placeholder: https://hastebin.com/ / https://gist.github.com/
placeholder: https://www.toptal.com/developers/hastebin / https://gist.github.com/
- type: input
attributes:
label: Plugin version
@@ -59,9 +59,11 @@ body:
label: Relevance
description: Check list for previous tickets
options:
- label: I tried the latest build (build refers to development builds not necessary a release version)
- label: |
I tried the [latest build](https://ci.codemc.io/job/Games647/job/FastLogin/)
(build refers to development builds not necessary a release version; i.e. v1.10 is out of date)
required: true
- label: |
I checked for existing tickets -
If there are, please vote them with a thumps reaction and not create new ones
If there are, please vote them with a thumbs reaction and not create new ones
required: true

View File

@@ -1,30 +0,0 @@
---
name: 💡 Enhancement request
about: New feature or change request
title: ''
labels: 'enhancement'
assignees: ''
---
[//]: # (Lines in this format are considered as comments and will not be displayed.)
[//]: # (Before reporting make sure you're running the **latest build** of the plugin and checked for existing issues!)
[//]: # (This ticket is about suggestions for a feature or particular enhancement)
### Is your feature request related to a problem? Please describe.
[//]: # (A clear and concise description of what the problem is. Ex. I'm always frustrated when [...])
### Describe the solution you'd like
[//]: # (A clear and concise description of what you want to happen.)
### Describe alternatives you've considered
[//]: # (A clear and concise description of any alternative solutions or features you've considered.)
### Additional context
[//]: # (Add any other context or screenshots about the feature request here.)

View File

@@ -0,0 +1,43 @@
name: 💡 Enhancement request
description: New feature or change request
labels: [ enhancement ]
body:
- type: markdown
attributes:
value: |
This ticket is about suggestions for a feature or particular enhancement.
Feedback about this form is appreciated.
- type: textarea
attributes:
label: Is your feature request related to a problem? Please describe.
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
validations:
required: true
- type: textarea
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
- type: textarea
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
- type: dropdown
attributes:
label: Platform
description: Server software - choose your proxy software if you have multiple servers
options:
- Spigot
- BungeeCord
- Velocity
- All / Shared
validations:
required: true
- type: checkboxes
attributes:
label: Relevance
description: Check list for previous tickets
options:
- label: |
I checked for existing tickets -
If there are, please vote them with a thumbs reaction and not create new ones
required: true

View File

@@ -14,3 +14,22 @@ updates:
directory: "/"
schedule:
interval: weekly
groups:
production-dependencies:
dependency-type: "production"
development-dependencies:
dependency-type: "development"
exclude-patterns:
# Create single PR for these
# Plugin require special evaluation about their compatibility
- "com.lenis0012.bukkit:loginsecurity"
- "com.comphenix.protocol:ProtocolLib"
ignore:
# HikariCP dropped Java 8 support with 5.0
- dependency-name: "com.zaxxer:HikariCP"
update-types: ["version-update:semver-major"]
# SnakeYAML has breaking changes with 2.0
- dependency-name: "org.yaml:snakeyaml"
update-types: ["version-update:semver-major"]

View File

@@ -4,11 +4,11 @@
name: "CodeQL"
on:
# Scan only for push on the primary branch for now
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_run:
workflows: ["Maven Build"]
branches: [main]
types:
- completed
jobs:
# job i
@@ -20,6 +20,10 @@ jobs:
# Environment
runs-on: ubuntu-latest
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
actions: read
contents: read
@@ -33,28 +37,29 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Setup Java
- name: Set up JDK
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 19
cache: 'maven'
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# Auto build attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Setup Java
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version-file: '.java-version'
cache: 'maven'
# Manually start the autobuild process, because autobuild always selects Java 8 as build toolchain, but
# we are doing cross-crompiling from a newer Java version
- name: Build with Maven
# Extracted from autobuild
run: mvn package -f "pom.xml" --batch-mode -V -e -Dfindbugs.skip -Dcheckstyle.skip -Dpmd.skip=true -Dspotbugs.skip -Denforcer.skip -Dmaven.javadoc.skip -DskipTests -Dmaven.test.skip.exec -Dlicense.skip=true -Drat.skip=true -Dspotless.check.skip=true -t /home/runner/.m2/toolchains.xml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@@ -21,19 +21,19 @@ jobs:
# Environment image - always use the newest OS
runs-on: ubuntu-latest
permissions:
contents: read
contents: write
# Run steps
steps:
# Pull changes
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Setup Java
- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 19
java-version-file: '.java-version'
cache: 'maven'
# Build and test (included in package)
@@ -41,3 +41,7 @@ jobs:
# Run non-interactive, package (with compile+test),
# ignore snapshot updates, because they are likely to have breaking changes, enforce checksums
run: mvn test --batch-mode --threads 2.0C --no-snapshot-updates --strict-checksums --file pom.xml
- name: Update dependency graph
if: ${{ github.event_name == 'push' }}
uses: advanced-security/maven-dependency-submission-action@v4.0.0

2
.java-version Normal file
View File

@@ -0,0 +1,2 @@
# Latest GitHub Action java release that is installed on the runners
21

View File

@@ -50,7 +50,7 @@
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>false</shadedArtifactAttached>
@@ -207,7 +207,7 @@
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.0.0</version>
<version>5.1.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -278,7 +278,7 @@
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.3</version>
<version>2.11.5</version>
<scope>provided</scope>
<optional>true</optional>
<exclusions>
@@ -307,7 +307,7 @@
<dependency>
<groupId>com.lenis0012.bukkit</groupId>
<artifactId>loginsecurity</artifactId>
<version>3.1.1</version>
<version>3.3.0</version>
<scope>provided</scope>
<optional>true</optional>
<exclusions>
@@ -378,7 +378,7 @@
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.72</version>
<version>1.77</version>
<scope>test</scope>
</dependency>

View File

@@ -228,6 +228,22 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
/**
* Fetches the premium status of an online player.
* {@snippet :
* // Bukkit's players object after successful authentication i.e. PlayerJoinEvent
* // except for proxies like BungeeCord and Velocity where the details are sent delayed (1-2 seconds)
* Player player;
* PremiumStatus status = JavaPlugin.getPlugin(FastLoginBukkit.class).getStatus(player.getUniqueId());
* switch (status) {
* case CRACKED:
* // player is offline
* break;
* case PREMIUM:
* // account is premium and player passed the verification
* break;
* case UNKNOWN:
* // no record about this player
* }
* }
*
* @param onlinePlayer player that is currently online player (play state)
* @return the online status or unknown if an error happened, the player isn't online or BungeeCord doesn't send

View File

@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: MIT
*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 games647 and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit;
import java.net.InetAddress;
public final class InetUtils {
private InetUtils() {
// Utility
}
/**
* Verifies if the given IP address is from the local network
*
* @param address IP address
* @return true if address is from local network or even from the device itself (loopback)
*/
public static boolean isLocalAddress(InetAddress address) {
// Loopback addresses like 127.0.* (IPv4) or [::1] (IPv6)
return address.isLoopbackAddress()
// Example: 10.0.0.0, 172.16.0.0, 192.168.0.0, fec0::/10 (deprecated)
// Ref: https://en.wikipedia.org/wiki/IP_address#Private_addresses
|| address.isSiteLocalAddress()
// Example: 169.254.0.0/16, fe80::/10
// Ref: https://en.wikipedia.org/wiki/IP_address#Address_autoconfiguration
|| address.isLinkLocalAddress()
// non deprecated unique site-local that java doesn't check yet -> fc00::/7
|| isIPv6UniqueSiteLocal(address);
}
private static boolean isIPv6UniqueSiteLocal(InetAddress address) {
// ref: https://en.wikipedia.org/wiki/Unique_local_address
// currently undefined but could be used in the near future fc00::/8
return (address.getAddress()[0] & 0xFF) == 0xFC
// in use for unique site-local fd00::/8
|| (address.getAddress()[0] & 0xFF) == 0xFD;
}
}

View File

@@ -70,7 +70,7 @@ final class EncryptionUtil {
public static final int VERIFY_TOKEN_LENGTH = 4;
public static final String KEY_PAIR_ALGORITHM = "RSA";
private static final int RSA_LENGTH = 1_024;
private static final int RSA_LENGTH = 2_048;
private static final PublicKey MOJANG_SESSION_KEY;
private static final int LINE_LENGTH = 76;

View File

@@ -38,6 +38,7 @@ import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.Converters;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedProfilePublicKey.WrappedProfileKeyData;
@@ -46,6 +47,7 @@ import com.github.games647.craftapi.model.skin.SkinProperty;
import com.github.games647.craftapi.resolver.MojangResolver;
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.InetUtils;
import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey;
import lombok.val;
import org.bukkit.entity.Player;
@@ -71,10 +73,17 @@ public class VerifyResponseTask implements Runnable {
private static final String ENCRYPTION_CLASS_NAME = "MinecraftEncryption";
private static final Class<?> ENCRYPTION_CLASS;
private static final String ADDRESS_VERIFY_WARNING = "This indicates the use of reverse-proxy like HAProxy, "
+ "TCPShield, BungeeCord, Velocity, etc. "
+ "By default (configurable in the config) this plugin requests Mojang to verify the connecting IP "
+ "to this server with the one used to log into Minecraft to prevent MITM attacks. In "
+ "order to work this security feature, the actual client IP needs to be forwarding "
+ "(keyword IP forwarding). This process will also be useful for other server "
+ "features like IP banning, so that it doesn't ban the proxy IP.";
static {
ENCRYPTION_CLASS = MinecraftReflection.getMinecraftClass(
"util." + ENCRYPTION_CLASS_NAME, ENCRYPTION_CLASS_NAME
"util." + ENCRYPTION_CLASS_NAME, ENCRYPTION_CLASS_NAME
);
}
@@ -149,10 +158,27 @@ public class VerifyResponseTask implements Runnable {
} else {
//user tried to fake an authentication
disconnect(
"invalid-session",
"GameProfile {} ({}) tried to log in with an invalid session. ServerId: {}",
session.getRequestUsername(), socketAddress, serverId
"invalid-session",
"Session server rejected incoming connection for GameProfile {} ({}). Possible reasons are"
+ "1) Client IP address contacting Mojang and server during server join were different "
+ "(Do you use a reverse proxy? -> Enable IP forwarding, "
+ "or disable the feature in the config). "
+ "2) Player is offline, but tried to bypass the authentication"
+ "3) Client uses an outdated username for connecting (Fix: Restart client)",
requestedUsername, address
);
if (InetUtils.isLocalAddress(address)) {
plugin.getLog().warn(
"The incoming request for player {} uses a local IP address",
requestedUsername
);
plugin.getLog().warn(ADDRESS_VERIFY_WARNING);
} else {
plugin.getLog().warn("If you think this is an error, please verify that the incoming "
+ "IP address {} is not associated with a server hosting company.", address);
plugin.getLog().warn(ADDRESS_VERIFY_WARNING);
}
}
} catch (IOException ioEx) {
disconnect("error-kick", "Failed to connect to session server", ioEx);
@@ -177,7 +203,7 @@ public class VerifyResponseTask implements Runnable {
session.setVerified(true);
setPremiumUUID(session.getUuid());
receiveFakeStartPacket(realUsername, session.getClientPublicKey());
receiveFakeStartPacket(realUsername, session.getClientPublicKey(), session.getUuid());
}
private void setPremiumUUID(UUID premiumUUID) {
@@ -217,15 +243,15 @@ public class VerifyResponseTask implements Runnable {
try {
// Try to get the old (pre MC 1.16.4) encryption method
encryptMethod = FuzzyReflection.fromClass(networkManagerClass)
.getMethodByParameters("a", SecretKey.class);
.getMethodByParameters("a", SecretKey.class);
} catch (IllegalArgumentException exception) {
// Get the new encryption method
encryptMethod = FuzzyReflection.fromClass(networkManagerClass)
.getMethodByParameters("a", Cipher.class, Cipher.class);
.getMethodByParameters("a", Cipher.class, Cipher.class);
// Get the needed Cipher helper method (used to generate ciphers from login key)
cipherMethod = FuzzyReflection.fromClass(ENCRYPTION_CLASS)
.getMethodByParameters("a", int.class, Key.class);
.getMethodByParameters("a", int.class, Key.class);
}
}
@@ -268,15 +294,23 @@ public class VerifyResponseTask implements Runnable {
}
//fake a new login packet in order to let the server handle all the other stuff
private void receiveFakeStartPacket(String username, ClientPublicKey clientKey) {
private void receiveFakeStartPacket(String username, ClientPublicKey clientKey, UUID uuid) {
PacketContainer startPacket;
if (new MinecraftVersion(1, 19, 0).atOrAbove()) {
if (new MinecraftVersion(1, 20, 2).atOrAbove()) {
startPacket = new PacketContainer(START);
startPacket.getStrings().write(0, username);
startPacket.getUUIDs().write(0, uuid);
} else if (new MinecraftVersion(1, 19, 3).atOrAbove()) {
startPacket = new PacketContainer(START);
startPacket.getStrings().write(0, username);
startPacket.getOptionals(Converters.passthrough(UUID.class)).write(0, Optional.of(uuid));
} else if (new MinecraftVersion(1, 19, 0).atOrAbove()) {
startPacket = new PacketContainer(START);
startPacket.getStrings().write(0, username);
EquivalentConverter<WrappedProfileKeyData> converter = BukkitConverters.getWrappedPublicKeyDataConverter();
val wrappedKey = Optional.ofNullable(clientKey).map(key ->
new WrappedProfileKeyData(clientKey.expiry(), clientKey.key(), clientKey.signature())
new WrappedProfileKeyData(clientKey.expiry(), clientKey.key(), clientKey.signature())
);
startPacket.getOptionals(converter).write(0, wrappedKey);

View File

@@ -47,7 +47,7 @@
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.1</version>
<configuration>
<minimizeJar>true</minimizeJar>

View File

@@ -71,25 +71,43 @@ public class ConnectListener implements Listener {
private static final String UUID_FIELD_NAME = "uniqueId";
protected static final MethodHandle UNIQUE_ID_SETTER;
private static final String REWRITE_ID_NAME = "rewriteId";
protected static final MethodHandle REWRITE_ID_SETTER;
static {
MethodHandle setHandle = null;
MethodHandle uniqueIdHandle = null;
MethodHandle rewriterHandle = null;
try {
Lookup lookup = MethodHandles.lookup();
// test for implementation class availability
Class.forName("net.md_5.bungee.connection.InitialHandler");
Field uuidField = InitialHandler.class.getDeclaredField(UUID_FIELD_NAME);
uuidField.setAccessible(true);
setHandle = lookup.unreflectSetter(uuidField);
uniqueIdHandle = getHandlerSetter(lookup, UUID_FIELD_NAME);
try {
rewriterHandle = getHandlerSetter(lookup, REWRITE_ID_NAME);
} catch (NoSuchFieldException noSuchFieldEx) {
Logger logger = LoggerFactory.getLogger(ConnectListener.class);
logger.error(
"Rewrite field not found. Setting only legacy BungeeCord field"
);
}
} catch (ReflectiveOperationException reflectiveOperationException) {
Logger logger = LoggerFactory.getLogger(ConnectListener.class);
logger.error(
"Cannot find Bungee initial handler; Disabling premium UUID and skin won't work.",
"Cannot find Bungee UUID field implementation; Disabling premium UUID and skin won't work.",
reflectiveOperationException
);
}
UNIQUE_ID_SETTER = setHandle;
UNIQUE_ID_SETTER = uniqueIdHandle;
REWRITE_ID_SETTER = rewriterHandle;
}
private static MethodHandle getHandlerSetter(Lookup lookup, String fieldName)
throws NoSuchFieldException, IllegalAccessException {
Field uuidField = InitialHandler.class.getDeclaredField(fieldName);
uuidField.setAccessible(true);
return lookup.unreflectSetter(uuidField);
}
private final FastLoginBungee plugin;
@@ -179,6 +197,12 @@ public class ConnectListener implements Listener {
// So we have to do it with reflection
UNIQUE_ID_SETTER.invokeExact(connection, offlineUUID);
// if available set rewrite id to forward the UUID for newer BungeeCord versions since
// https://github.com/SpigotMC/BungeeCord/commit/1be25b6c74ec2be4b15adf8ca53a0497f01e2afe
if (REWRITE_ID_SETTER != null) {
REWRITE_ID_SETTER.invokeExact(connection, offlineUUID);
}
String format = "Overridden UUID from {} to {} (based of {}) on {}";
plugin.getLog().info(format, oldPremiumId, offlineUUID, username, connection);
} catch (Exception ex) {

View File

@@ -220,6 +220,14 @@
<property name="optional" value="true"/>
</module>
<!-- Suppress filters via comments -->
<!-- https://stackoverflow.com/a/4023351/9767089 -->
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
<property name="checkFormat" value="$1"/>
</module>
</module>
</module>

View File

@@ -63,6 +63,23 @@
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifestEntries>
<Automatic-Module-Name>com.github.games647.fastlogin.core</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Libraries that we shade into the project -->
@@ -85,7 +102,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>2.0.7</version>
<version>2.0.11</version>
</dependency>
<!-- snakeyaml is present in Bungee, Spigot, Cauldron, so we could use this independent implementation -->
@@ -178,7 +195,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
<version>2.10.1</version>
</dependency>
<dependency>

View File

@@ -25,8 +25,17 @@
*/
package com.github.games647.fastlogin.core.hooks;
/**
* Password generator for your auth plugin.
* @param <P> platform dependent player class
*/
@FunctionalInterface
public interface PasswordGenerator<P> {
/**
* Generate a password for a non-registered player
* @param player
* @return daw
*/
String getRandomPassword(P player);
}

View File

@@ -80,6 +80,40 @@ public abstract class FloodgateManagement<P extends C, C, L extends LoginSession
}
profile = core.getStorage().loadProfile(username);
if (profile.isSaved()) {
if (profile.isFloodgateMigrated()) {
if (profile.getFloodgate() == FloodgateState.TRUE && isLinked) {
core.getPlugin().getLog()
.info("Player {} is already stored by FastLogin as a non-linked Bedrock Edition player",
username);
return;
} else if (profile.getFloodgate() == FloodgateState.FALSE && isLinked) {
profile.setFloodgate(FloodgateState.LINKED);
core.getPlugin().getLog().info(
"Player {} will be changed from a Java player to a linked Floodgate player",
username);
}
} else {
if (isLinked) {
profile.setFloodgate(FloodgateState.LINKED);
core.getPlugin().getLog().info(
"Player {} will be migrated to the v2 database schema as a linked Floodgate user",
username);
} else {
profile.setFloodgate(FloodgateState.TRUE);
core.getPlugin().getLog().info(
"Player {} will be migrated to the v2 database schema as a Floodgate user", username);
}
}
} else {
if (isLinked) {
profile.setFloodgate(FloodgateState.LINKED);
} else {
profile.setFloodgate(FloodgateState.TRUE);
}
}
AuthPlugin<P> authPlugin = core.getAuthPluginHook();
try {
@@ -119,13 +153,17 @@ public abstract class FloodgateManagement<P extends C, C, L extends LoginSession
}
}
// defer auto registration, if it's not enabled in the config
if (!isRegistered && !isAutoAuthAllowed(autoRegisterFloodgate)) {
return;
}
//logging in from bedrock for a second time threw an error with UUID
if (profile == null) {
profile = new StoredProfile(getUUID(player), username, true, getAddress(player).toString());
// stop the auto login procedure, if the current connection's parameters don't match the one stored in our
// database
// ex. we stored a LINKED account, but the current connection is not linked
if ((profile.getFloodgate() == FloodgateState.LINKED && !isLinked)
|| (profile.getFloodgate() == FloodgateState.TRUE && isLinked)) {
return;
}
//start Bukkit/Bungee specific tasks

View File

@@ -0,0 +1,86 @@
/*
* SPDX-License-Identifier: MIT
*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 games647 and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.core.shared;
public enum FloodgateState {
/**
* Purely Java profile
*/
FALSE(0),
/**
* Purely Bedrock profile
*/
TRUE(1),
/**
* Bedrock profile is bidirectional associated with the Java Mojang profile.
*/
LINKED(2),
/**
* Data before floodgate database migration. Floodgate state is unknown.
*/
NOT_MIGRATED(3);
private int value;
FloodgateState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
/**
* Convert a number to FloodgateState
* <ol start="0">
* <li>False</li>
* <li>True</li>
* <li>Linked</li>
* <li>Not Migrated</li>
* </ol>
* @param num the number, most likely loaded from the database
* @return FloodgateStatus on success, null otherwise
*/
public static FloodgateState fromInt(int num) {
// using Enum.values()[i] is expensive as per https://stackoverflow.com/a/8762387/9767089
switch (num) {
case 0:
return FloodgateState.FALSE;
case 1:
return FloodgateState.TRUE;
case 2:
return FloodgateState.LINKED;
case 3:
return FloodgateState.NOT_MIGRATED;
default:
return null;
}
}
}

View File

@@ -62,7 +62,7 @@ public abstract class ForceLoginManagement<P extends C, C, L extends LoginSessio
//premium player
AuthPlugin<P> authPlugin = core.getAuthPluginHook();
if (authPlugin == null) {
//maybe only bungeecord plugin
// maybe only bungeecord plugin
onForceActionSuccess(session);
} else {
boolean success = true;

View File

@@ -49,17 +49,32 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
public void onLogin(String username, S source) {
core.getPlugin().getLog().info("Handling player {}", username);
//check if the player is connecting through Bedrock Edition
if (bedrockService != null && bedrockService.isBedrockConnection(username)) {
//perform Bedrock specific checks and skip Java checks if no longer needed
if (bedrockService.performChecks(username, source)) {
return;
}
}
StoredProfile profile = core.getStorage().loadProfile(username);
//can't be a premium Java player, if it's not saved in the database
if (profile == null) {
return;
}
//check if the player is connecting through Bedrock Edition
if (bedrockService != null && bedrockService.isBedrockConnection(username)) {
//perform Bedrock specific checks and skip Java checks, if they are not needed
if (bedrockService.performChecks(username, source)) {
if (profile.isFloodgateMigrated()) {
if (profile.getFloodgate() == FloodgateState.TRUE) {
// migrated and enabled floodgate player, however the above bedrocks fails, so the current connection
// isn't premium
return;
}
} else {
profile.setFloodgate(FloodgateState.FALSE);
core.getPlugin().getLog().info(
"Player {} will be migrated to the v2 database schema as a JAVA user", username);
}
callFastLoginPreLoginEvent(username, source, profile);
@@ -139,6 +154,12 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
if (core.getConfig().get("nameChangeCheck", false)) {
StoredProfile storedProfile = core.getStorage().loadProfile(profile.getId());
if (storedProfile != null) {
if (storedProfile.getFloodgate() == FloodgateState.TRUE) {
core.getPlugin().getLog()
.info("Player {} is already stored by FastLogin as a Bedrock Edition player.", username);
return false;
}
//uuid exists in the database
core.getPlugin().getLog().info("GameProfile {} changed it's username", profile);

View File

@@ -29,9 +29,20 @@ import com.github.games647.fastlogin.core.shared.LoginSession;
import com.github.games647.fastlogin.core.storage.StoredProfile;
/**
* This event fires if the plugin performs an auto login on the platform where the login plugin is.
* This event fires if the plugin performs an auto login on the platform where the login plugin is
*
* {@snippet :
* @EventHandler()
* public void onPlayerLogin(FastLoginAutoLoginEvent loginEvent) {
* StoredProfile profile = loginEvent.getProfile();
* LoginSession session = loginEvent.getSession();
*
* System.out.println("Player: " + session.getUsername() + " is about to be force logged in");
* }
* }
*/
public interface FastLoginAutoLoginEvent extends FastLoginCancellableEvent {
LoginSession getSession();
StoredProfile getProfile();
}

View File

@@ -28,5 +28,6 @@ package com.github.games647.fastlogin.core.shared.event;
public interface FastLoginCancellableEvent {
boolean isCancelled();
void setCancelled(boolean cancelled);
}

View File

@@ -34,6 +34,8 @@ import com.github.games647.fastlogin.core.storage.StoredProfile;
public interface FastLoginPreLoginEvent {
String getUsername();
LoginSource getSource();
StoredProfile getProfile();
}

View File

@@ -33,6 +33,7 @@ import com.github.games647.fastlogin.core.storage.StoredProfile;
public interface FastLoginPremiumToggleEvent {
StoredProfile getProfile();
PremiumToggleReason getReason();
enum PremiumToggleReason {

View File

@@ -28,6 +28,8 @@ package com.github.games647.fastlogin.core.storage;
import com.github.games647.fastlogin.core.shared.PlatformPlugin;
import com.zaxxer.hikari.HikariConfig;
import java.util.Locale;
public class MySQLStorage extends SQLStorage {
private static final String JDBC_PROTOCOL = "jdbc:";
@@ -68,12 +70,12 @@ public class MySQLStorage extends SQLStorage {
}
private static String buildJDBCUrl(String driver, String host, int port, String database) {
String protocol = "mysql";
if (driver.contains("mariadb")) {
protocol = "mariadb";
MySQLVariant variant = MySQLVariant.fromDriver(driver);
if (variant == null) {
throw new IllegalArgumentException("Unknown storage driver");
}
return protocol + "://" + host + ':' + port + '/' + database;
return variant.getJdbcPrefix() + "://" + host + ':' + port + '/' + database;
}
private static void addPerformanceProperties(HikariConfig config) {
@@ -106,4 +108,32 @@ public class MySQLStorage extends SQLStorage {
// In our case it can be useful to see the time in error messages
// config.addDataSourceProperty("maintainTimeStats", false);
}
enum MySQLVariant {
MYSQL("mysql"),
MARIADB("mariadb");
private final String jdbcPrefix;
public static MySQLVariant fromDriver(String driver) {
String normalizedDriver = driver.toLowerCase(Locale.ENGLISH);
if (normalizedDriver.contains("mysql")) {
return MYSQL;
} else if (normalizedDriver.contains("mariadb")) {
return MARIADB;
}
return null;
}
MySQLVariant(String jdbcPrefix) {
this.jdbcPrefix = jdbcPrefix;
}
public String getJdbcPrefix() {
return jdbcPrefix;
}
}
}

View File

@@ -26,11 +26,13 @@
package com.github.games647.fastlogin.core.storage;
import com.github.games647.craftapi.UUIDAdapter;
import com.github.games647.fastlogin.core.shared.FloodgateState;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -56,13 +58,19 @@ public abstract class SQLStorage implements AuthStorage {
+ "UNIQUE (`Name`) "
+ ')';
protected static final String LOAD_BY_NAME = "SELECT * FROM `" + PREMIUM_TABLE + "` WHERE `Name`=? LIMIT 1";
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE + "` WHERE `UUID`=? LIMIT 1";
protected static final String ADD_FLOODGATE_COLUMN_STMT = "ALTER TABLE `" + PREMIUM_TABLE
+ "` ADD COLUMN `Floodgate` INTEGER(3)";
protected static final String LOAD_BY_NAME = "SELECT * FROM `" + PREMIUM_TABLE
+ "` WHERE `Name`=? LIMIT 1";
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE
+ "` WHERE `UUID`=? LIMIT 1";
protected static final String INSERT_PROFILE = "INSERT INTO `" + PREMIUM_TABLE
+ "` (`UUID`, `Name`, `Premium`, `LastIp`) " + "VALUES (?, ?, ?, ?) ";
+ "` (`UUID`, `Name`, `Premium`, `Floodgate`, `LastIp`) " + "VALUES (?, ?, ?, ?, ?) ";
// limit not necessary here, because it's unique
protected static final String UPDATE_PROFILE = "UPDATE `" + PREMIUM_TABLE
+ "` SET `UUID`=?, `Name`=?, `Premium`=?, `LastIp`=?, `LastLogin`=CURRENT_TIMESTAMP WHERE `UserID`=?";
+ "` SET `UUID`=?, `Name`=?, `Premium`=?, `Floodgate`=?, `LastIp`=?, "
+ "`LastLogin`=CURRENT_TIMESTAMP WHERE `UserID`=?";
protected final Logger log;
protected final HikariDataSource dataSource;
@@ -81,11 +89,23 @@ public abstract class SQLStorage implements AuthStorage {
// choose surrogate PK(ID), because UUID can be null for offline players
// if UUID is always Premium UUID we would have to update offline player entries on insert
// name cannot be PK, because it can be changed for premium players
//todo: add unique uuid index usage
try (Connection con = dataSource.getConnection();
Statement createStmt = con.createStatement()) {
createStmt.executeUpdate(CREATE_TABLE_STMT);
Statement stmt = con.createStatement()) {
stmt.executeUpdate(getCreateTableStmt());
// add Floodgate column
DatabaseMetaData md = con.getMetaData();
if (isColumnMissing(md, "Floodgate")) {
stmt.executeUpdate(ADD_FLOODGATE_COLUMN_STMT);
}
}
}
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {
try (ResultSet rs = metaData.getColumns(null, null, PREMIUM_TABLE, columnName)) {
return !rs.next();
}
}
@@ -97,7 +117,8 @@ public abstract class SQLStorage implements AuthStorage {
loadStmt.setString(1, name);
try (ResultSet resultSet = loadStmt.executeQuery()) {
return parseResult(resultSet).orElseGet(() -> new StoredProfile(null, name, false, ""));
return parseResult(resultSet).orElseGet(() -> new StoredProfile(null, name, false,
FloodgateState.FALSE, ""));
}
} catch (SQLException sqlEx) {
log.error("Failed to query profile: {}", name, sqlEx);
@@ -124,15 +145,25 @@ public abstract class SQLStorage implements AuthStorage {
private Optional<StoredProfile> parseResult(ResultSet resultSet) throws SQLException {
if (resultSet.next()) {
long userId = resultSet.getInt(1);
long userId = resultSet.getInt("UserID");
UUID uuid = Optional.ofNullable(resultSet.getString(2)).map(UUIDAdapter::parseId).orElse(null);
UUID uuid = Optional.ofNullable(resultSet.getString("UUID")).map(UUIDAdapter::parseId).orElse(null);
String name = resultSet.getString(3);
boolean premium = resultSet.getBoolean(4);
String lastIp = resultSet.getString(5);
Instant lastLogin = resultSet.getTimestamp(6).toInstant();
return Optional.of(new StoredProfile(userId, uuid, name, premium, lastIp, lastLogin));
String name = resultSet.getString("Name");
boolean premium = resultSet.getBoolean("Premium");
int floodgateNum = resultSet.getInt("Floodgate");
FloodgateState floodgate;
// if the player wasn't migrated to the new database format
if (resultSet.wasNull()) {
floodgate = FloodgateState.NOT_MIGRATED;
} else {
floodgate = FloodgateState.fromInt(floodgateNum);
}
String lastIp = resultSet.getString("LastIp");
Instant lastLogin = resultSet.getTimestamp("LastLogin").toInstant();
return Optional.of(new StoredProfile(userId, uuid, name, premium, floodgate, lastIp, lastLogin));
}
return Optional.empty();
@@ -150,9 +181,10 @@ public abstract class SQLStorage implements AuthStorage {
saveStmt.setString(1, uuid);
saveStmt.setString(2, playerProfile.getName());
saveStmt.setBoolean(3, playerProfile.isPremium());
saveStmt.setString(4, playerProfile.getLastIp());
saveStmt.setInt(4, playerProfile.getFloodgate().getValue());
saveStmt.setString(5, playerProfile.getLastIp());
saveStmt.setLong(5, playerProfile.getRowId());
saveStmt.setLong(6, playerProfile.getRowId());
saveStmt.execute();
}
} else {
@@ -161,7 +193,9 @@ public abstract class SQLStorage implements AuthStorage {
saveStmt.setString(2, playerProfile.getName());
saveStmt.setBoolean(3, playerProfile.isPremium());
saveStmt.setString(4, playerProfile.getLastIp());
saveStmt.setBoolean(3, playerProfile.isPremium());
saveStmt.setInt(4, playerProfile.getFloodgate().getValue());
saveStmt.setString(5, playerProfile.getLastIp());
saveStmt.execute();
try (ResultSet generatedKeys = saveStmt.getGeneratedKeys()) {
@@ -179,6 +213,14 @@ public abstract class SQLStorage implements AuthStorage {
}
}
/**
* SQLite has a slightly different syntax, so this will be overridden by SQLiteStorage
* @return An SQL Statement to create the `premium` table
*/
protected String getCreateTableStmt() {
return CREATE_TABLE_STMT;
}
@Override
public void close() {
dataSource.close();

View File

@@ -31,15 +31,23 @@ import org.sqlite.JDBC;
import org.sqlite.SQLiteConfig;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SQLiteStorage extends SQLStorage {
protected static final String CREATE_TABLE_STMT = "CREATE TABLE IF NOT EXISTS `" + PREMIUM_TABLE + "` ("
+ "`UserID` INTEGER PRIMARY KEY AUTO_INCREMENT, "
+ "`UUID` CHAR(36), "
+ "`Name` VARCHAR(16) NOT NULL, "
+ "`Premium` BOOLEAN NOT NULL, "
+ "`LastIp` VARCHAR(255) NOT NULL, "
+ "`LastLogin` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
//the premium shouldn't steal the cracked account by changing the name
+ "UNIQUE (`Name`) "
+ ')';
private static final String SQLITE_DRIVER = "org.sqlite.SQLiteDataSource";
private final Lock lock = new ReentrantLock();
@@ -103,12 +111,9 @@ public class SQLiteStorage extends SQLStorage {
}
@Override
public void createTables() throws SQLException {
try (Connection con = dataSource.getConnection();
Statement createStmt = con.createStatement()) {
// SQLite has a different syntax for auto increment
createStmt.executeUpdate(CREATE_TABLE_STMT.replace("AUTO_INCREMENT", "AUTOINCREMENT"));
}
protected String getCreateTableStmt() {
// SQLite has a different syntax for auto increment
return CREATE_TABLE_STMT.replace("AUTO_INCREMENT", "AUTOINCREMENT");
}
private static String replacePathVariables(Path dataFolder, String input) {

View File

@@ -26,6 +26,7 @@
package com.github.games647.fastlogin.core.storage;
import com.github.games647.craftapi.model.Profile;
import com.github.games647.fastlogin.core.shared.FloodgateState;
import java.time.Instant;
import java.util.Objects;
@@ -39,20 +40,28 @@ public class StoredProfile extends Profile {
private final ReentrantLock saveLock = new ReentrantLock();
private boolean premium;
private FloodgateState floodgate;
private String lastIp;
private Instant lastLogin;
public StoredProfile(long rowId, UUID uuid, String playerName, boolean premium, String lastIp, Instant lastLogin) {
public StoredProfile(long rowId, UUID uuid, String playerName, boolean premium, FloodgateState floodgate,
String lastIp, Instant lastLogin) {
super(uuid, playerName);
this.rowId = rowId;
this.premium = premium;
this.floodgate = floodgate;
this.lastIp = lastIp;
this.lastLogin = lastLogin;
}
public StoredProfile(UUID uuid, String playerName, boolean premium, FloodgateState isFloodgate, String lastIp) {
this(-1, uuid, playerName, premium, isFloodgate, lastIp, Instant.now());
}
@Deprecated
public StoredProfile(UUID uuid, String playerName, boolean premium, String lastIp) {
this(-1, uuid, playerName, premium, lastIp, Instant.now());
this(-1, uuid, playerName, premium, FloodgateState.FALSE, lastIp, Instant.now());
}
public ReentrantLock getSaveLock() {
@@ -96,6 +105,18 @@ public class StoredProfile extends Profile {
this.premium = premium;
}
public synchronized FloodgateState getFloodgate() {
return floodgate;
}
public synchronized boolean isFloodgateMigrated() {
return floodgate != FloodgateState.NOT_MIGRATED;
}
public synchronized void setFloodgate(FloodgateState floodgate) {
this.floodgate = floodgate;
}
public synchronized String getLastIp() {
return lastIp;
}
@@ -128,7 +149,7 @@ public class StoredProfile extends Profile {
}
return rowId == that.rowId && premium == that.premium
&& Objects.equals(lastIp, that.lastIp) && lastLogin.equals(that.lastLogin);
&& Objects.equals(lastIp, that.lastIp) && lastLogin.equals(that.lastLogin);
}
@Override
@@ -141,6 +162,7 @@ public class StoredProfile extends Profile {
return this.getClass().getSimpleName() + '{'
+ "rowId=" + rowId
+ ", premium=" + premium
+ ", floodgate=" + floodgate
+ ", lastIp='" + lastIp + '\''
+ ", lastLogin=" + lastLogin
+ "} " + super.toString();

View File

@@ -70,7 +70,7 @@ no-console: '&4You are not a player. You cannot toggle the premium state for YOU
# The user wants to toggle premium state, but BungeeCord support is enabled. This means the server have to communicate
# with the BungeeCord first which will establish a connection with the database server.
wait-on-proxy: '&6Sending request... (Do not forget to follow the BungeeCord setup guide)'
wait-on-proxy: '&6Sending request... (Do not forget to follow the BungeeCord setup guide referenced on the plugin page)'
# When ProtocolLib is enabled and the plugin is unable to continue handling a login request after a requested premium
# authentication. In this state the client expects a success packet with an encrypted connection or disconnect packet.
@@ -100,5 +100,3 @@ Type &a/premium&6 again to confirm'
invalid-public-key: '&cInvalid client public key. Please try to restart your game.'
# ========= Bungee/Waterfall only ================================

17
pom.xml
View File

@@ -103,7 +103,7 @@
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>4.1</version>
<version>4.3</version>
<configuration>
<licenseSets>
<licenseSet>
@@ -115,6 +115,7 @@
<excludes>
<exclude>src/test/resources/**</exclude>
<exclude>src/main/resources/**</exclude>
<exclude>.java-version</exclude>
</excludes>
</licenseSet>
</licenseSets>
@@ -130,7 +131,7 @@
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<version>3.3.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
@@ -141,7 +142,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.9.3</version>
<version>10.12.7</version>
</dependency>
</dependencies>
<executions>
@@ -158,7 +159,7 @@
<!-- Require newer versions for Junit5 support -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<version>3.2.5</version>
</plugin>
</plugins>
@@ -187,22 +188,22 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<!-- Require inline to support static mocks -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<artifactId>mockito-core</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -55,7 +55,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<version>3.0.0</version>
<executions>
<execution>
<id>filter-src</id>
@@ -67,7 +67,7 @@
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.1</version>
<configuration>
<minimizeJar>true</minimizeJar>
@@ -97,6 +97,10 @@
<exclude>com.google.guava:guava</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
@@ -129,6 +133,10 @@
<id>velocity</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>opencollab-snapshot</id>
<url>https://repo.opencollab.dev/main/</url>
</repository>
</repositories>
<dependencies>
@@ -143,7 +151,7 @@
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>3.1.1</version>
<version>3.3.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -151,7 +159,29 @@
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.1.0</version>
<version>3.3.2</version>
</dependency>
<!-- Bedrock player bridge -->
<dependency>
<groupId>org.geysermc.geyser</groupId>
<artifactId>core</artifactId>
<version>${geyser.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Floodgate -->
<dependency>
<groupId>org.geysermc.floodgate</groupId>
<artifactId>api</artifactId>
<version>${floodgate.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -27,6 +27,8 @@ package com.github.games647.fastlogin.velocity;
import com.github.games647.fastlogin.core.AsyncScheduler;
import com.github.games647.fastlogin.core.hooks.bedrock.BedrockService;
import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService;
import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService;
import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
import com.github.games647.fastlogin.core.message.ChannelMessage;
import com.github.games647.fastlogin.core.message.SuccessMessage;
@@ -50,6 +52,8 @@ import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
import com.velocitypowered.api.proxy.messages.ChannelRegistrar;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.geyser.GeyserImpl;
import org.slf4j.Logger;
import java.io.IOException;
@@ -76,6 +80,8 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
private FastLoginCore<Player, CommandSource, FastLoginVelocity> core;
private AsyncScheduler scheduler;
private FloodgateService floodgateService;
private GeyserService geyserService;
private UUID proxyId;
@Inject
@@ -95,6 +101,14 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
return;
}
if (isPluginInstalled("floodgate")) {
floodgateService = new FloodgateService(FloodgateApi.getInstance(), core);
}
if (isPluginInstalled("Geyser-Velocity")) {
geyserService = new GeyserService(GeyserImpl.getInstance(), core);
}
server.getEventManager().register(this, new ConnectListener(this, core.getAntiBot()));
server.getEventManager().register(this, new PluginMessageListener(this));
@@ -140,9 +154,21 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
return server.getPluginManager().isLoaded(name);
}
public FloodgateService getFloodgateService() {
return floodgateService;
}
public GeyserService getGeyserService() {
return geyserService;
}
@Override
public BedrockService<?> getBedrockService() {
return null;
if (floodgateService != null) {
return floodgateService;
}
return geyserService;
}
public FastLoginCore<Player, CommandSource, FastLoginVelocity> getCore() {

View File

@@ -53,10 +53,12 @@ public class VelocityLoginSource implements LoginSource {
public void kick(String message) {
if (message == null) {
preLoginEvent.setResult(PreLoginEvent.PreLoginComponentResult.denied(
Component.text("Kicked").color(NamedTextColor.WHITE)));
Component.text("Kicked").color(NamedTextColor.WHITE))
);
} else {
preLoginEvent.setResult(PreLoginEvent.PreLoginComponentResult.denied(
LegacyComponentSerializer.legacyAmpersand().deserialize(message)));
LegacyComponentSerializer.legacyAmpersand().deserialize(message))
);
}
}

View File

@@ -28,13 +28,15 @@ package com.github.games647.fastlogin.velocity.listener;
import com.github.games647.craftapi.UUIDAdapter;
import com.github.games647.fastlogin.core.antibot.AntiBotService;
import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;
import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService;
import com.github.games647.fastlogin.core.shared.LoginSession;
import com.github.games647.fastlogin.core.storage.StoredProfile;
import com.github.games647.fastlogin.velocity.FastLoginVelocity;
import com.github.games647.fastlogin.velocity.VelocityLoginSession;
import com.github.games647.fastlogin.velocity.task.AsyncPremiumCheck;
import com.github.games647.fastlogin.velocity.task.FloodgateAuthTask;
import com.github.games647.fastlogin.velocity.task.ForceLoginTask;
import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.event.EventTask;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.PreLoginEvent;
@@ -48,6 +50,7 @@ import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.GameProfile.Property;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import java.net.InetSocketAddress;
import java.util.ArrayList;
@@ -67,9 +70,9 @@ public class ConnectListener {
}
@Subscribe
public void onPreLogin(PreLoginEvent preLoginEvent, Continuation continuation) {
public EventTask onPreLogin(PreLoginEvent preLoginEvent) {
if (!preLoginEvent.getResult().isAllowed()) {
return;
return null;
}
InboundConnection connection = preLoginEvent.getConnection();
@@ -81,28 +84,30 @@ public class ConnectListener {
switch (action) {
case Ignore:
// just ignore
return;
return null;
case Block:
String message = plugin.getCore().getMessage("kick-antibot");
TextComponent messageParsed = LegacyComponentSerializer.legacyAmpersand().deserialize(message);
PreLoginComponentResult reason = PreLoginComponentResult.denied(messageParsed);
preLoginEvent.setResult(reason);
break;
return null;
case Continue:
default:
Runnable asyncPremiumCheck = new AsyncPremiumCheck(
plugin, connection, username, continuation, preLoginEvent
return EventTask.async(
new AsyncPremiumCheck(plugin, connection, username, preLoginEvent)
);
plugin.getScheduler().runAsync(asyncPremiumCheck);
break;
}
}
@Subscribe
public void onGameprofileRequest(GameProfileRequestEvent event) {
public void onGameProfileRequest(GameProfileRequestEvent event) {
if (event.isOnlineMode()) {
LoginSession session = plugin.getSession().get(event.getConnection().getRemoteAddress());
if (session == null) {
plugin.getLog().warn("No active login session found for player {}", event.getUsername());
return;
}
UUID verifiedUUID = event.getGameProfile().getId();
String verifiedUsername = event.getUsername();
@@ -141,8 +146,20 @@ public class ConnectListener {
Player player = serverConnectedEvent.getPlayer();
RegisteredServer server = serverConnectedEvent.getServer();
FloodgateService floodgateService = plugin.getFloodgateService();
if (floodgateService != null) {
FloodgatePlayer floodgatePlayer = floodgateService.getBedrockPlayer(player.getUniqueId());
if (floodgatePlayer != null) {
plugin.getLog().info("Running floodgate handling for {}", player);
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer, server);
plugin.getScheduler().runAsync(floodgateAuthTask);
return;
}
}
VelocityLoginSession session = plugin.getSession().get(player.getRemoteAddress());
if (session == null) {
plugin.getLog().info("No active login session found on server connect for {}", player);
return;
}
@@ -151,7 +168,7 @@ public class ConnectListener {
// player is still in the login phase and reported to be offline.
Runnable loginTask = new ForceLoginTask(plugin.getCore(), player, server, session);
plugin.getProxy().getScheduler()
.buildTask(plugin, () -> plugin.getScheduler().runAsync(loginTask))
.buildTask(plugin, loginTask)
.delay(1L, TimeUnit.SECONDS) // Delay at least one second, otherwise the login command can be missed
.schedule();
}

View File

@@ -29,6 +29,7 @@ import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
import com.github.games647.fastlogin.core.message.SuccessMessage;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.storage.StoredProfile;
import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService;
import com.github.games647.fastlogin.velocity.FastLoginVelocity;
import com.github.games647.fastlogin.velocity.VelocityLoginSession;
import com.github.games647.fastlogin.velocity.task.AsyncToggleMessage;
@@ -115,7 +116,15 @@ public class PluginMessageListener {
}
private void onSuccessMessage(Player forPlayer) {
if (forPlayer.isOnlineMode()) {
boolean shouldPersist = forPlayer.isOnlineMode();
FloodgateService floodgateService = plugin.getFloodgateService();
if (!shouldPersist && floodgateService != null) {
// always save floodgate players to lock this username
shouldPersist = floodgateService.isBedrockPlayer(forPlayer.getUniqueId());
}
if (shouldPersist) {
//bukkit module successfully received and force logged in the user
//update only on success to prevent corrupt data
VelocityLoginSession loginSession = plugin.getSession().get(forPlayer.getRemoteAddress());

View File

@@ -33,7 +33,6 @@ import com.github.games647.fastlogin.velocity.VelocityLoginSession;
import com.github.games647.fastlogin.velocity.VelocityLoginSource;
import com.github.games647.fastlogin.velocity.event.VelocityFastLoginPreLoginEvent;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.Player;
@@ -45,28 +44,22 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
private final FastLoginVelocity plugin;
private final String username;
private final Continuation continuation;
private final PreLoginEvent preLoginEvent;
private final InboundConnection connection;
public AsyncPremiumCheck(FastLoginVelocity plugin, InboundConnection connection, String username,
Continuation continuation, PreLoginEvent preLoginEvent) {
PreLoginEvent preLoginEvent) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());
this.plugin = plugin;
this.connection = connection;
this.username = username;
this.continuation = continuation;
this.preLoginEvent = preLoginEvent;
}
@Override
public void run() {
plugin.getSession().remove(connection.getRemoteAddress());
try {
super.onLogin(username, new VelocityLoginSource(connection, preLoginEvent));
} finally {
continuation.resume();
}
super.onLogin(username, new VelocityLoginSource(connection, preLoginEvent));
}
@Override

View File

@@ -0,0 +1,85 @@
/*
* SPDX-License-Identifier: MIT
*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 games647 and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.velocity.task;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.FloodgateManagement;
import com.github.games647.fastlogin.velocity.FastLoginVelocity;
import com.github.games647.fastlogin.velocity.VelocityLoginSession;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class FloodgateAuthTask
extends FloodgateManagement<Player, CommandSource, VelocityLoginSession, FastLoginVelocity> {
private final RegisteredServer server;
public FloodgateAuthTask(FastLoginCore<Player, CommandSource, FastLoginVelocity> core, Player player,
FloodgatePlayer floodgatePlayer, RegisteredServer server) {
super(core, player, floodgatePlayer);
this.server = server;
}
@Override
protected void startLogin() {
VelocityLoginSession session = new VelocityLoginSession(player.getUsername(), isRegistered, profile);
core.getPlugin().getSession().put(player.getRemoteAddress(), session);
// enable auto login based on the value of 'autoLoginFloodgate' in config.yml
boolean forcedOnlineMode = autoLoginFloodgate.equals("true")
|| (autoLoginFloodgate.equals("linked") && isLinked);
// delay sending force command, because Paper will process the login event asynchronously
// In this case it means that the force command (plugin message) is already received and processed while
// player is still in the login phase and reported to be offline.
Runnable loginTask = new ForceLoginTask(core.getPlugin().getCore(), player, server, session, forcedOnlineMode);
core.getPlugin().getProxy().getScheduler()
.buildTask(core.getPlugin(), () -> core.getPlugin().getScheduler().runAsync(loginTask))
.delay(1L, TimeUnit.SECONDS) // Delay at least one second, otherwise the login command can be missed
.schedule();
}
@Override
protected String getName(Player player) {
return player.getUsername();
}
@Override
protected UUID getUUID(Player player) {
return player.getUniqueId();
}
@Override
protected InetSocketAddress getAddress(Player player) {
return player.getRemoteAddress();
}
}

View File

@@ -68,6 +68,7 @@ public class ForceLoginTask
@Override
public void run() {
if (session == null) {
core.getPlugin().getLog().info("No active login session on force handling for {}", player);
return;
}
@@ -80,6 +81,7 @@ public class ForceLoginTask
@Override
public boolean forceLogin(Player player) {
if (session.isAlreadyLogged()) {
core.getPlugin().getLog().info("Ignoring second force login attempt for {}", player);
return true;
}
@@ -92,11 +94,11 @@ public class ForceLoginTask
VelocityFastLoginAutoLoginEvent event = new VelocityFastLoginAutoLoginEvent(session, profile);
try {
return core.getPlugin().getProxy().getEventManager().fire(event).get();
} catch (InterruptedException e) {
} catch (InterruptedException interruptedEx) {
Thread.currentThread().interrupt(); // Set the interrupt flag again
return event;
} catch (ExecutionException e) {
core.getPlugin().getLog().error("Error firing event", e);
} catch (ExecutionException executionEx) {
core.getPlugin().getLog().error("Error firing event", executionEx);
return event;
}
}
@@ -114,6 +116,8 @@ public class ForceLoginTask
type = Type.REGISTER;
}
core.getPlugin().getLog().info("Sending force {} for {} towards server {}", type, player.getUsername(), server);
UUID proxyId = core.getPlugin().getProxyId();
ChannelMessage loginMessage = new LoginActionMessage(type, player.getUsername(), proxyId);
core.getPlugin().sendPluginMessage(server, loginMessage);